wallet2: keep received amount breakdown consistent
What changed, and why it matters
This patch changes how a Monero wallet records the breakdown of received amounts when an existing output is 'burnt' and replaced by a new one during transaction processing. It ensures the stored amount list stays consistent with the actual new output value. The commit message frames this as a consistency fix, not a security fix, and the supplied materials do not show any exploit path.
Treat as a correctness/defensive-hardening patch. Review related wallet accounting paths to confirm no other stale amount references remain. No urgent security response is indicated by the supplied materials alone.
Security signals we found
Corrects inconsistent accounting of received amounts after a burnt/spent output is replaced
Adds a defensive exception for unexpected old/new output values
No explicit security claim in commit message or diff
Evidence from the diff
In wallet2::process_new_transaction(), when a key image already exists (a prior output is being spent/burnt and a new output created), the code now locates the matching old amount in tx_amounts_individual_outs and replaces it with extra_amount (amount - burnt). Previously the container was not updated, so the per-output received-amount breakdown could retain a stale value. The added THROW_WALLET_EXCEPTION_IF guards against an inconsistent state by requiring the old amount to be present.
Changed components
src/wallet/wallet2.cppwallet2::process_new_transactionreceived amount tracking for individual outputsInspect captured patch +7 / −0
### src/wallet/wallet2.cpp
@@ -2671,6 +2671,13 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount;
uint64_t burnt = m_transfers[kit->second].amount();
uint64_t extra_amount = amount - burnt;
+
+ amounts_container& tx_amounts_this_out = tx_amounts_individual_outs[tx_scan_info[o].received->index];
+ auto amount_iterator = std::find(tx_amounts_this_out.begin(), tx_amounts_this_out.end(), amount);
+ THROW_WALLET_EXCEPTION_IF(amount_iterator == tx_amounts_this_out.end(),
+ error::wallet_internal_error, "Unexpected values of new and old outputs");
+ *amount_iterator = extra_amount;
+
if (!pool)
{
transfer_details &td = m_transfers[kit->second];Why this scored 31/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.