aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/tx_pool.cpp
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-04-11 15:27:56 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-04-11 15:27:56 +0100
commit08343abaf432c56124651a20099d0e5b029aa62e (patch)
tree4230410cc03a126c5cbabbe88dfe07bab9170eef /src/cryptonote_core/tx_pool.cpp
parentMerge pull request #3434 (diff)
downloadmonero-08343abaf432c56124651a20099d0e5b029aa62e.tar.xz
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
Diffstat (limited to 'src/cryptonote_core/tx_pool.cpp')
-rw-r--r--src/cryptonote_core/tx_pool.cpp43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 0af9737a7..5dfbc1dd4 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -1268,24 +1268,33 @@ namespace cryptonote
m_spent_key_images.clear();
m_txpool_size = 0;
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) {
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(*bd, tx))
- {
- MWARNING("Failed to parse tx from txpool, removing");
- remove.push_back(txid);
- }
- if (!insert_key_images(tx, meta.kept_by_block))
- {
- MFATAL("Failed to insert key images from txpool tx");
+
+ // 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;
+ if (!parse_and_validate_tx_from_blob(*bd, tx))
+ {
+ MWARNING("Failed to parse tx from txpool, removing");
+ remove.push_back(txid);
+ }
+ if (!insert_key_images(tx, meta.kept_by_block))
+ {
+ MFATAL("Failed to insert key images from txpool tx");
+ return false;
+ }
+ m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(meta.fee / (double)meta.blob_size, meta.receive_time), txid);
+ m_txpool_size += meta.blob_size;
+ return true;
+ }, true);
+ if (!r)
return false;
- }
- m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(meta.fee / (double)meta.blob_size, meta.receive_time), txid);
- m_txpool_size += meta.blob_size;
- return true;
- }, true);
- if (!r)
- return false;
+ }
if (!remove.empty())
{
LockedTXN lock(m_blockchain);