From 6c44f5c6ebca5eb99996694fbfdefd7661a8e51a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 7 Dec 2016 21:05:50 +0000 Subject: [PATCH] wallet: send 0 change to a random address where necessary with rct If a rct transaction would cause no change to be generated, a zero change output is added, and sent to a randomly generated address. This ensures that no transaction will be sent with just one output, which could cause the receiver to be able to determine which of the inputs in the sent rings is the real one. This is very rare, since it requires the sum of outputs to be equal to the sum of outputs plus the fee, which is now a function of the last few blocks. --- src/wallet/wallet2.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 2d293d45c..2f93d0ba1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3770,12 +3770,22 @@ void wallet2::transfer_selected_rct(std::vector splitted_dsts = dsts; cryptonote::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts); - if (needed_money < found_money) + change_dts.amount = found_money - needed_money; + if (change_dts.amount == 0) + { + // If the change is 0, send it to a random address, to avoid confusing + // the sender with a 0 amount output. We send a 0 amount in order to avoid + // letting the destination be able to work out which of the inputs is the + // real one in our rings + cryptonote::account_base dummy; + dummy.generate(); + change_dts.addr = dummy.get_keys().m_account_address; + } + else { change_dts.addr = m_account.get_keys().m_account_address; - change_dts.amount = found_money - needed_money; - splitted_dsts.push_back(change_dts); } + splitted_dsts.push_back(change_dts); crypto::secret_key tx_key; bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), sources, splitted_dsts, extra, tx, unlock_time, tx_key, true);