aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTadeas Moravec <moravec.tadeas@gmail.com>2020-01-09 10:01:56 +0100
committerTadeas Moravec <tadeas@moravec.xyz>2020-01-11 11:48:27 +0100
commit096a9dbdf958d23f74d132247143b8b8d3cb6dcd (patch)
tree7d285dcc389ee70c070f29f1c1e4111989abca8b
parentMerge pull request #6253 (diff)
downloadmonero-096a9dbdf958d23f74d132247143b8b8d3cb6dcd.tar.xz
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>
-rw-r--r--src/wallet/wallet2.cpp28
-rw-r--r--src/wallet/wallet2.h7
-rw-r--r--src/wallet/wallet_rpc_server.cpp2
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h3
4 files changed, 38 insertions, 2 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index ea556ec45..a850f6bfb 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -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;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index b6f72c7e1..f643c0d1a 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -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>
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index de501f056..ae81e211e 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -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;
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index 0c86f404d..9b7d72279 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -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);