tx_pool: fix loading with colliding key images

A key image may be present more than once if all but one of the
txes spending that key image are coming from blocks. When loading
a txpool from storage, we must load the one that's not from a
block first to avoid rejection
This commit is contained in:
moneromooo-monero 2018-04-11 15:27:56 +01:00
parent 7090121b13
commit 178c11f4a4
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

View File

@ -1268,7 +1268,15 @@ namespace cryptonote
m_spent_key_images.clear(); m_spent_key_images.clear();
m_txpool_size = 0; m_txpool_size = 0;
std::vector<crypto::hash> remove; std::vector<crypto::hash> remove;
bool r = m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
// first add the not kept by block, then the kept by block,
// to avoid rejection due to key image collision
for (int pass = 0; pass < 2; ++pass)
{
const bool kept = pass == 1;
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
if (!!kept != !!meta.kept_by_block)
return true;
cryptonote::transaction tx; cryptonote::transaction tx;
if (!parse_and_validate_tx_from_blob(*bd, tx)) if (!parse_and_validate_tx_from_blob(*bd, tx))
{ {
@ -1286,6 +1294,7 @@ namespace cryptonote
}, true); }, true);
if (!r) if (!r)
return false; return false;
}
if (!remove.empty()) if (!remove.empty())
{ {
LockedTXN lock(m_blockchain); LockedTXN lock(m_blockchain);