Bitcoin Core  27.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>
10 #include <primitives/transaction.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 
61 void 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 {
80  cachedInnerUsage = 0;
81  iters_by_txid.clear();
82  queuedTx.clear();
83 }
84 
85 std::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:30
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:74
assert(!tx.IsCoinBase())