Bitcoin Core 28.99.0
P2P Digital Currency
disconnected_transactions.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6
7#include <assert.h>
8#include <core_memusage.h>
9#include <memusage.h>
11#include <util/hasher.h>
12
13#include <memory>
14#include <utility>
15
16// It's almost certainly a logic bug if we don't clear out queuedTx before
17// destruction, as we add to it while disconnecting blocks, and then we
18// need to re-process remaining transactions to ensure mempool consistency.
19// For now, assert() that we've emptied out this object on destruction.
20// This assert() can always be removed if the reorg-processing code were
21// to be refactored such that this assumption is no longer true (for
22// instance if there was some other way we cleaned up the mempool after a
23// reorg, besides draining this object).
25{
26 assert(queuedTx.empty());
27 assert(iters_by_txid.empty());
29}
30
32{
33 std::vector<CTransactionRef> evicted;
34
35 while (!queuedTx.empty() && DynamicMemoryUsage() > m_max_mem_usage) {
36 evicted.emplace_back(queuedTx.front());
38 iters_by_txid.erase(queuedTx.front()->GetHash());
39 queuedTx.pop_front();
40 }
41 return evicted;
42}
43
45{
47}
48
49[[nodiscard]] std::vector<CTransactionRef> DisconnectedBlockTransactions::AddTransactionsFromBlock(const std::vector<CTransactionRef>& vtx)
50{
51 iters_by_txid.reserve(iters_by_txid.size() + vtx.size());
52 for (auto block_it = vtx.rbegin(); block_it != vtx.rend(); ++block_it) {
53 auto it = queuedTx.insert(queuedTx.end(), *block_it);
54 auto [_, inserted] = iters_by_txid.emplace((*block_it)->GetHash(), it);
55 assert(inserted); // callers may never pass multiple transactions with the same txid
57 }
58 return LimitMemoryUsage();
59}
60
61void DisconnectedBlockTransactions::removeForBlock(const std::vector<CTransactionRef>& vtx)
62{
63 // Short-circuit in the common case of a block being added to the tip
64 if (queuedTx.empty()) {
65 return;
66 }
67 for (const auto& tx : vtx) {
68 auto iter = iters_by_txid.find(tx->GetHash());
69 if (iter != iters_by_txid.end()) {
70 auto list_iter = iter->second;
71 iters_by_txid.erase(iter);
73 queuedTx.erase(list_iter);
74 }
75 }
76}
77
79{
81 iters_by_txid.clear();
82 queuedTx.clear();
83}
84
85std::list<CTransactionRef> DisconnectedBlockTransactions::take()
86{
87 std::list<CTransactionRef> ret = std::move(queuedTx);
88 clear();
89 return ret;
90}
int ret
std::list< CTransactionRef > take()
Clear all data structures and return the list of transactions.
void removeForBlock(const std::vector< CTransactionRef > &vtx)
Remove any entries that are in this block.
uint64_t cachedInnerUsage
Cached dynamic memory usage for the CTransactionRefs.
std::vector< CTransactionRef > LimitMemoryUsage()
Trim the earliest-added entries until we are within memory bounds.
std::vector< CTransactionRef > AddTransactionsFromBlock(const std::vector< CTransactionRef > &vtx)
Add transactions from the block, iterating through vtx in reverse order.
std::list< CTransactionRef > queuedTx
std::unordered_map< uint256, TxList::iterator, SaltedTxidHasher > iters_by_txid
static size_t RecursiveDynamicUsage(const CScript &script)
Definition: core_memusage.h:12
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:31
bilingual_str _(ConstevalStringLiteral str)
Translation function.
Definition: translation.h:80
assert(!tx.IsCoinBase())