mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-22 23:42:24 +00:00
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
4 changed files with 38 additions and 2 deletions
|
@ -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)
|
||||
if (!miner_tx && !pool)
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
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.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);
|
||||
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,
|
||||
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;
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -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;
|
||||
// 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
|
||||
|
@ -2286,6 +2310,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||
if (subaddr_account && i->first.major == *subaddr_account)
|
||||
{
|
||||
sub_change += i->second;
|
||||
tx_amounts_individual_outs.erase(i->first);
|
||||
i = tx_money_got_in_outs.erase(i);
|
||||
}
|
||||
else
|
||||
|
@ -2363,6 +2388,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
|||
payment.m_tx_hash = txid;
|
||||
payment.m_fee = fee;
|
||||
payment.m_amount = i.second;
|
||||
payment.m_amounts = tx_amounts_individual_outs[i.first];
|
||||
payment.m_block_height = height;
|
||||
payment.m_unlock_time = tx.unlock_time;
|
||||
payment.m_timestamp = ts;
|
||||
|
|
|
@ -360,10 +360,12 @@ private:
|
|||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
typedef std::vector<uint64_t> amounts_container;
|
||||
struct payment_details
|
||||
{
|
||||
crypto::hash m_tx_hash;
|
||||
uint64_t m_amount;
|
||||
amounts_container m_amounts;
|
||||
uint64_t m_fee;
|
||||
uint64_t m_block_height;
|
||||
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::LR, 0)
|
||||
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::unconfirmed_transfer_details, 8)
|
||||
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 6)
|
||||
|
@ -1939,6 +1941,9 @@ namespace boost
|
|||
return;
|
||||
}
|
||||
a & x.m_coinbase;
|
||||
if (ver < 5)
|
||||
return;
|
||||
a & x.m_amounts;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
|
|
|
@ -326,6 +326,7 @@ namespace tools
|
|||
entry.height = pd.m_block_height;
|
||||
entry.timestamp = pd.m_timestamp;
|
||||
entry.amount = pd.m_amount;
|
||||
entry.amounts = pd.m_amounts;
|
||||
entry.unlock_time = pd.m_unlock_time;
|
||||
entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
|
||||
entry.fee = pd.m_fee;
|
||||
|
@ -408,6 +409,7 @@ namespace tools
|
|||
entry.height = 0;
|
||||
entry.timestamp = pd.m_timestamp;
|
||||
entry.amount = pd.m_amount;
|
||||
entry.amounts = pd.m_amounts;
|
||||
entry.unlock_time = pd.m_unlock_time;
|
||||
entry.locked = true;
|
||||
entry.fee = pd.m_fee;
|
||||
|
|
|
@ -1354,6 +1354,7 @@ namespace wallet_rpc
|
|||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
typedef std::vector<uint64_t> amounts_container;
|
||||
struct transfer_entry
|
||||
{
|
||||
std::string txid;
|
||||
|
@ -1361,6 +1362,7 @@ namespace wallet_rpc
|
|||
uint64_t height;
|
||||
uint64_t timestamp;
|
||||
uint64_t amount;
|
||||
amounts_container amounts;
|
||||
uint64_t fee;
|
||||
std::string note;
|
||||
std::list<transfer_destination> destinations;
|
||||
|
@ -1380,6 +1382,7 @@ namespace wallet_rpc
|
|||
KV_SERIALIZE(height);
|
||||
KV_SERIALIZE(timestamp);
|
||||
KV_SERIALIZE(amount);
|
||||
KV_SERIALIZE(amounts);
|
||||
KV_SERIALIZE(fee);
|
||||
KV_SERIALIZE(note);
|
||||
KV_SERIALIZE(destinations);
|
||||
|
|
Loading…
Reference in a new issue