Fix invalid balance in view wallet csv export with imported key images

Received inputs were being handled incorrectly when importing key
images: only the *first* payment received was being removed, but it
can easily happen that we have multiple payments to ourselves in the
same wallet (for example, if we send a fixed amount to ourselves then
almost always send two non-zero amounts to ourself: the amount + the
change).

This would result in (n-1) "in" outputs for the transaction still
showing up in the output, along with the "out" transaction (which
contains the overall net transfer amount).  For example:

- Alice sends 100 + 12.3 change to herself.
- Bob has Alice's view keys, opens a view-only wallet, sees 100 and 12.3
  as two separate inputs from the same transaction.
- Alice provides a key image export to Bob to verify the account
- Bob imports.

Bob's export would now show:

    in 12.3
    out 0

(The inputs of the same transaction are apparently ordered randomly, so
it could also be 'in 100'/'out 0')

and the running total would be 12.3 too high (or 100 too high if the 100
got left instead of the 12.3).

This fixes it by removing *all* matching payments when we import key
images instead of just the first one.
This commit is contained in:
Jason Rhinelander 2021-09-03 00:08:12 -03:00
parent 70954ff373
commit 69300f0a15
No known key found for this signature in database
GPG key ID: C4992CE7A88D4262

View file

@ -13579,13 +13579,12 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
process_outgoing(*spent_txid, spent_tx, e.block_height, e.block_timestamp, tx_money_spent_in_ins, tx_money_got_in_outs, subaddr_account, subaddr_indices);
// erase corresponding incoming payment
for (auto j = m_payments.begin(); j != m_payments.end(); ++j)
for (auto j = m_payments.begin(); j != m_payments.end(); )
{
if (j->second.m_tx_hash == *spent_txid)
{
m_payments.erase(j);
break;
}
j = m_payments.erase(j);
else
++j;
}
++spent_txid;