From 925bb723ca71aa76380b769d8926c7c2ad9bbb7b Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 6 Sep 2023 11:24:42 +0100 Subject: [PATCH] [refactor] batch-add transactions to DisconnectedBlockTransactions No behavior change. In a future commit, we can optimize by reserving vtx.size(). --- src/txmempool.h | 14 +++++++++++--- src/validation.cpp | 4 +--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/txmempool.h b/src/txmempool.h index 869612a4a2d..8b4ac2dce1d 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -892,10 +892,18 @@ struct DisconnectedBlockTransactions { return memusage::MallocUsage(sizeof(CTransactionRef) + 6 * sizeof(void*)) * queuedTx.size() + cachedInnerUsage; } - void addTransaction(const CTransactionRef& tx) + /** Add transactions from the block, iterating through vtx in reverse order. Callers should call + * this function for blocks in descending order by block height. + * We assume that callers never pass multiple transactions with the same txid, otherwise things + * can go very wrong in removeForBlock due to queuedTx containing an item without a + * corresponding entry in iters_by_txid. + */ + void AddTransactionsFromBlock(const std::vector& vtx) { - queuedTx.insert(tx); - cachedInnerUsage += RecursiveDynamicUsage(tx); + for (auto block_it = vtx.rbegin(); block_it != vtx.rend(); ++block_it) { + queuedTx.insert(*block_it); + cachedInnerUsage += RecursiveDynamicUsage(*block_it); + } } // Remove entries based on txid_index, and update memory usage. diff --git a/src/validation.cpp b/src/validation.cpp index 0b6327ec558..9326dad10dd 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2721,9 +2721,7 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra if (disconnectpool && m_mempool) { // Save transactions to re-add to mempool at end of reorg - for (auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) { - disconnectpool->addTransaction(*it); - } + disconnectpool->AddTransactionsFromBlock(block.vtx); while (disconnectpool->DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) { // Drop the earliest entry, and remove its children from the mempool. auto it = disconnectpool->queuedTx.get().begin();