mempool_entry.h
1 // Copyright (c) 2009-2022 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 5 #ifndef BITCOIN_KERNEL_MEMPOOL_ENTRY_H 6 #define BITCOIN_KERNEL_MEMPOOL_ENTRY_H 7 8 #include <consensus/amount.h> 9 #include <consensus/validation.h> 10 #include <core_memusage.h> 11 #include <policy/policy.h> 12 #include <policy/settings.h> 13 #include <primitives/transaction.h> 14 #include <util/epochguard.h> 15 #include <util/overflow.h> 16 17 #include <chrono> 18 #include <functional> 19 #include <memory> 20 #include <set> 21 #include <stddef.h> 22 #include <stdint.h> 23 24 class CBlockIndex; 25 26 struct LockPoints { 27 // Will be set to the blockchain height and median time past 28 // values that would be necessary to satisfy all relative locktime 29 // constraints (BIP68) of this tx given our view of block chain history 30 int height{0}; 31 int64_t time{0}; 32 // As long as the current chain descends from the highest height block 33 // containing one of the inputs used in the calculation, then the cached 34 // values are still valid even after a reorg. 35 CBlockIndex* maxInputBlock{nullptr}; 36 }; 37 38 struct CompareIteratorByHash { 39 // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T> 40 // (e.g. a wrapped CTxMemPoolEntry&) 41 template <typename T> 42 bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const 43 { 44 return a.get().GetTx().GetHash() < b.get().GetTx().GetHash(); 45 } 46 template <typename T> 47 bool operator()(const T& a, const T& b) const 48 { 49 return a->GetTx().GetHash() < b->GetTx().GetHash(); 50 } 51 }; 52 53 /** \class CTxMemPoolEntry 54 * 55 * CTxMemPoolEntry stores data about the corresponding transaction, as well 56 * as data about all in-mempool transactions that depend on the transaction 57 * ("descendant" transactions). 58 * 59 * When a new entry is added to the mempool, we update the descendant state 60 * (m_count_with_descendants, nSizeWithDescendants, and nModFeesWithDescendants) for 61 * all ancestors of the newly added transaction. 62 * 63 */ 64 65 class CTxMemPoolEntry 66 { 67 public: 68 typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef; 69 // two aliases, should the types ever diverge 70 typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Parents; 71 typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Children; 72 73 private: 74 CTxMemPoolEntry(const CTxMemPoolEntry&) = default; 75 struct ExplicitCopyTag { 76 explicit ExplicitCopyTag() = default; 77 }; 78 79 const CTransactionRef tx; 80 mutable Parents m_parents; 81 mutable Children m_children; 82 const CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups 83 const int32_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) 84 const size_t nUsageSize; //!< ... and total memory usage 85 const int64_t nTime; //!< Local time when entering the mempool 86 const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay 87 const unsigned int entryHeight; //!< Chain height when entering the mempool 88 const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase 89 const int64_t sigOpCost; //!< Total sigop cost 90 CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block 91 mutable LockPoints lockPoints; //!< Track the height and time at which tx was final 92 93 // Information about descendants of this transaction that are in the 94 // mempool; if we remove this transaction we must remove all of these 95 // descendants as well. 96 int64_t m_count_with_descendants{1}; //!< number of descendant transactions 97 // Using int64_t instead of int32_t to avoid signed integer overflow issues. 98 int64_t nSizeWithDescendants; //!< ... and size 99 CAmount nModFeesWithDescendants; //!< ... and total fees (all including us) 100 101 // Analogous statistics for ancestor transactions 102 int64_t m_count_with_ancestors{1}; 103 // Using int64_t instead of int32_t to avoid signed integer overflow issues. 104 int64_t nSizeWithAncestors; 105 CAmount nModFeesWithAncestors; 106 int64_t nSigOpCostWithAncestors; 107 108 public: 109 CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee, 110 int64_t time, unsigned int entry_height, uint64_t entry_sequence, 111 bool spends_coinbase, 112 int64_t sigops_cost, LockPoints lp) 113 : tx{tx}, 114 nFee{fee}, 115 nTxWeight{GetTransactionWeight(*tx)}, 116 nUsageSize{RecursiveDynamicUsage(tx)}, 117 nTime{time}, 118 entry_sequence{entry_sequence}, 119 entryHeight{entry_height}, 120 spendsCoinbase{spends_coinbase}, 121 sigOpCost{sigops_cost}, 122 m_modified_fee{nFee}, 123 lockPoints{lp}, 124 nSizeWithDescendants{GetTxSize()}, 125 nModFeesWithDescendants{nFee}, 126 nSizeWithAncestors{GetTxSize()}, 127 nModFeesWithAncestors{nFee}, 128 nSigOpCostWithAncestors{sigOpCost} {} 129 130 CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {} 131 CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete; 132 CTxMemPoolEntry(CTxMemPoolEntry&&) = delete; 133 CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete; 134 135 static constexpr ExplicitCopyTag ExplicitCopy{}; 136 137 const CTransaction& GetTx() const { return *this->tx; } 138 CTransactionRef GetSharedTx() const { return this->tx; } 139 const CAmount& GetFee() const { return nFee; } 140 int32_t GetTxSize() const 141 { 142 return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp); 143 } 144 int32_t GetTxWeight() const { return nTxWeight; } 145 std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; } 146 unsigned int GetHeight() const { return entryHeight; } 147 uint64_t GetSequence() const { return entry_sequence; } 148 int64_t GetSigOpCost() const { return sigOpCost; } 149 CAmount GetModifiedFee() const { return m_modified_fee; } 150 size_t DynamicMemoryUsage() const { return nUsageSize; } 151 const LockPoints& GetLockPoints() const { return lockPoints; } 152 153 // Adjusts the descendant state. 154 void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount); 155 // Adjusts the ancestor state 156 void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps); 157 // Updates the modified fees with descendants/ancestors. 158 void UpdateModifiedFee(CAmount fee_diff) 159 { 160 nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff); 161 nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff); 162 m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff); 163 } 164 165 // Update the LockPoints after a reorg 166 void UpdateLockPoints(const LockPoints& lp) const 167 { 168 lockPoints = lp; 169 } 170 171 uint64_t GetCountWithDescendants() const { return m_count_with_descendants; } 172 int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } 173 CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } 174 175 bool GetSpendsCoinbase() const { return spendsCoinbase; } 176 177 uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; } 178 int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } 179 CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } 180 int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } 181 182 const Parents& GetMemPoolParentsConst() const { return m_parents; } 183 const Children& GetMemPoolChildrenConst() const { return m_children; } 184 Parents& GetMemPoolParents() const { return m_parents; } 185 Children& GetMemPoolChildren() const { return m_children; } 186 187 mutable size_t idx_randomized; //!< Index in mempool's txns_randomized 188 mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms 189 }; 190 191 using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef; 192 193 struct TransactionInfo { 194 const CTransactionRef m_tx; 195 /* The fee the transaction paid */ 196 const CAmount m_fee; 197 /** 198 * The virtual transaction size. 199 * 200 * This is a policy field which considers the sigop cost of the 201 * transaction as well as its weight, and reinterprets it as bytes. 202 * 203 * It is the primary metric by which the mining algorithm selects 204 * transactions. 205 */ 206 const int64_t m_virtual_transaction_size; 207 /* The block height the transaction entered the mempool */ 208 const unsigned int txHeight; 209 210 TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height) 211 : m_tx{tx}, 212 m_fee{fee}, 213 m_virtual_transaction_size{vsize}, 214 txHeight{height} {} 215 }; 216 217 struct RemovedMempoolTransactionInfo { 218 TransactionInfo info; 219 explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry) 220 : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {} 221 }; 222 223 struct NewMempoolTransactionInfo { 224 TransactionInfo info; 225 /* 226 * This boolean indicates whether the transaction was added 227 * without enforcing mempool fee limits. 228 */ 229 const bool m_mempool_limit_bypassed; 230 /* This boolean indicates whether the transaction is part of a package. */ 231 const bool m_submitted_in_package; 232 /* 233 * This boolean indicates whether the blockchain is up to date when the 234 * transaction is added to the mempool. 235 */ 236 const bool m_chainstate_is_current; 237 /* Indicates whether the transaction has unconfirmed parents. */ 238 const bool m_has_no_mempool_parents; 239 240 explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee, 241 const int64_t vsize, const unsigned int height, 242 const bool mempool_limit_bypassed, const bool submitted_in_package, 243 const bool chainstate_is_current, 244 const bool has_no_mempool_parents) 245 : info{tx, fee, vsize, height}, 246 m_mempool_limit_bypassed{mempool_limit_bypassed}, 247 m_submitted_in_package{submitted_in_package}, 248 m_chainstate_is_current{chainstate_is_current}, 249 m_has_no_mempool_parents{has_no_mempool_parents} {} 250 }; 251 252 #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H