Wallet: Distingush amounts for a single subaddress
Adding a new `amounts` field ot the output of `get_transfers` RPC method. This field specifies individual payments made to a single subaddress in a single transaction, e.g., made by this command: transfer <addr1> <amount1> <addr1> <amount2>
This commit is contained in:
parent
3c01bffd0c
commit
096a9dbdf9
@ -1842,7 +1842,11 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
// (that is, the prunable stuff may or may not be included)
|
// (that is, the prunable stuff may or may not be included)
|
||||||
if (!miner_tx && !pool)
|
if (!miner_tx && !pool)
|
||||||
process_unconfirmed(txid, tx, height);
|
process_unconfirmed(txid, tx, height);
|
||||||
std::unordered_map<cryptonote::subaddress_index, uint64_t> tx_money_got_in_outs; // per receiving subaddress index
|
|
||||||
|
// per receiving subaddress index
|
||||||
|
std::unordered_map<cryptonote::subaddress_index, uint64_t> tx_money_got_in_outs;
|
||||||
|
std::unordered_map<cryptonote::subaddress_index, amounts_container> tx_amounts_individual_outs;
|
||||||
|
|
||||||
crypto::public_key tx_pub_key = null_pkey;
|
crypto::public_key tx_pub_key = null_pkey;
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
|
||||||
@ -1971,6 +1975,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
{
|
{
|
||||||
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
||||||
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
||||||
|
if (!tx_scan_info[i].error)
|
||||||
|
{
|
||||||
|
tx_amounts_individual_outs[tx_scan_info[i].received->index].push_back(tx_scan_info[i].money_transfered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1994,6 +2002,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
{
|
{
|
||||||
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
||||||
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
||||||
|
if (!tx_scan_info[i].error)
|
||||||
|
{
|
||||||
|
tx_amounts_individual_outs[tx_scan_info[i].received->index].push_back(tx_scan_info[i].money_transfered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2010,6 +2022,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
hwdev.set_mode(hw::device::NONE);
|
hwdev.set_mode(hw::device::NONE);
|
||||||
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
|
||||||
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
|
||||||
|
if (!tx_scan_info[i].error)
|
||||||
|
{
|
||||||
|
tx_amounts_individual_outs[tx_scan_info[i].received->index].push_back(tx_scan_info[i].money_transfered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2118,6 +2134,12 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info[o].received->index] < tx_scan_info[o].amount,
|
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info[o].received->index] < tx_scan_info[o].amount,
|
||||||
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
||||||
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount;
|
tx_money_got_in_outs[tx_scan_info[o].received->index] -= tx_scan_info[o].amount;
|
||||||
|
|
||||||
|
amounts_container& tx_amounts_this_out = tx_amounts_individual_outs[tx_scan_info[o].received->index]; // Only for readability on the following lines
|
||||||
|
auto amount_iterator = std::find(tx_amounts_this_out.begin(), tx_amounts_this_out.end(), tx_scan_info[o].amount);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(amount_iterator == tx_amounts_this_out.end(),
|
||||||
|
error::wallet_internal_error, "Unexpected values of new and old outputs");
|
||||||
|
tx_amounts_this_out.erase(amount_iterator);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2183,6 +2205,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs.size() != tx_amounts_individual_outs.size(), error::wallet_internal_error, "Inconsistent size of output arrays");
|
||||||
|
|
||||||
uint64_t tx_money_spent_in_ins = 0;
|
uint64_t tx_money_spent_in_ins = 0;
|
||||||
// The line below is equivalent to "boost::optional<uint32_t> subaddr_account;", but avoids the GCC warning: ‘*((void*)& subaddr_account +4)’ may be used uninitialized in this function
|
// The line below is equivalent to "boost::optional<uint32_t> subaddr_account;", but avoids the GCC warning: ‘*((void*)& subaddr_account +4)’ may be used uninitialized in this function
|
||||||
// It's a GCC bug with boost::optional, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679
|
// It's a GCC bug with boost::optional, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679
|
||||||
@ -2286,6 +2310,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
if (subaddr_account && i->first.major == *subaddr_account)
|
if (subaddr_account && i->first.major == *subaddr_account)
|
||||||
{
|
{
|
||||||
sub_change += i->second;
|
sub_change += i->second;
|
||||||
|
tx_amounts_individual_outs.erase(i->first);
|
||||||
i = tx_money_got_in_outs.erase(i);
|
i = tx_money_got_in_outs.erase(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2363,6 +2388,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||||||
payment.m_tx_hash = txid;
|
payment.m_tx_hash = txid;
|
||||||
payment.m_fee = fee;
|
payment.m_fee = fee;
|
||||||
payment.m_amount = i.second;
|
payment.m_amount = i.second;
|
||||||
|
payment.m_amounts = tx_amounts_individual_outs[i.first];
|
||||||
payment.m_block_height = height;
|
payment.m_block_height = height;
|
||||||
payment.m_unlock_time = tx.unlock_time;
|
payment.m_unlock_time = tx.unlock_time;
|
||||||
payment.m_timestamp = ts;
|
payment.m_timestamp = ts;
|
||||||
|
@ -360,10 +360,12 @@ private:
|
|||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<uint64_t> amounts_container;
|
||||||
struct payment_details
|
struct payment_details
|
||||||
{
|
{
|
||||||
crypto::hash m_tx_hash;
|
crypto::hash m_tx_hash;
|
||||||
uint64_t m_amount;
|
uint64_t m_amount;
|
||||||
|
amounts_container m_amounts;
|
||||||
uint64_t m_fee;
|
uint64_t m_fee;
|
||||||
uint64_t m_block_height;
|
uint64_t m_block_height;
|
||||||
uint64_t m_unlock_time;
|
uint64_t m_unlock_time;
|
||||||
@ -1628,7 +1630,7 @@ BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 12)
|
|||||||
BOOST_CLASS_VERSION(tools::wallet2::multisig_info, 1)
|
BOOST_CLASS_VERSION(tools::wallet2::multisig_info, 1)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0)
|
BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::multisig_tx_set, 1)
|
BOOST_CLASS_VERSION(tools::wallet2::multisig_tx_set, 1)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 4)
|
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 5)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1)
|
BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 8)
|
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 8)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 6)
|
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 6)
|
||||||
@ -1939,6 +1941,9 @@ namespace boost
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
a & x.m_coinbase;
|
a & x.m_coinbase;
|
||||||
|
if (ver < 5)
|
||||||
|
return;
|
||||||
|
a & x.m_amounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
|
@ -326,6 +326,7 @@ namespace tools
|
|||||||
entry.height = pd.m_block_height;
|
entry.height = pd.m_block_height;
|
||||||
entry.timestamp = pd.m_timestamp;
|
entry.timestamp = pd.m_timestamp;
|
||||||
entry.amount = pd.m_amount;
|
entry.amount = pd.m_amount;
|
||||||
|
entry.amounts = pd.m_amounts;
|
||||||
entry.unlock_time = pd.m_unlock_time;
|
entry.unlock_time = pd.m_unlock_time;
|
||||||
entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
|
entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
|
||||||
entry.fee = pd.m_fee;
|
entry.fee = pd.m_fee;
|
||||||
@ -408,6 +409,7 @@ namespace tools
|
|||||||
entry.height = 0;
|
entry.height = 0;
|
||||||
entry.timestamp = pd.m_timestamp;
|
entry.timestamp = pd.m_timestamp;
|
||||||
entry.amount = pd.m_amount;
|
entry.amount = pd.m_amount;
|
||||||
|
entry.amounts = pd.m_amounts;
|
||||||
entry.unlock_time = pd.m_unlock_time;
|
entry.unlock_time = pd.m_unlock_time;
|
||||||
entry.locked = true;
|
entry.locked = true;
|
||||||
entry.fee = pd.m_fee;
|
entry.fee = pd.m_fee;
|
||||||
|
@ -1354,6 +1354,7 @@ namespace wallet_rpc
|
|||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<uint64_t> amounts_container;
|
||||||
struct transfer_entry
|
struct transfer_entry
|
||||||
{
|
{
|
||||||
std::string txid;
|
std::string txid;
|
||||||
@ -1361,6 +1362,7 @@ namespace wallet_rpc
|
|||||||
uint64_t height;
|
uint64_t height;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint64_t amount;
|
uint64_t amount;
|
||||||
|
amounts_container amounts;
|
||||||
uint64_t fee;
|
uint64_t fee;
|
||||||
std::string note;
|
std::string note;
|
||||||
std::list<transfer_destination> destinations;
|
std::list<transfer_destination> destinations;
|
||||||
@ -1380,6 +1382,7 @@ namespace wallet_rpc
|
|||||||
KV_SERIALIZE(height);
|
KV_SERIALIZE(height);
|
||||||
KV_SERIALIZE(timestamp);
|
KV_SERIALIZE(timestamp);
|
||||||
KV_SERIALIZE(amount);
|
KV_SERIALIZE(amount);
|
||||||
|
KV_SERIALIZE(amounts);
|
||||||
KV_SERIALIZE(fee);
|
KV_SERIALIZE(fee);
|
||||||
KV_SERIALIZE(note);
|
KV_SERIALIZE(note);
|
||||||
KV_SERIALIZE(destinations);
|
KV_SERIALIZE(destinations);
|
||||||
|
Loading…
Reference in New Issue
Block a user