Branch data Line data Source code
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 : 0 : 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 : 0 : int height{0}; 31 : 0 : 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 : 0 : 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 : 0 : bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const 43 : : { 44 : 0 : return a.get().GetTx().GetHash() < b.get().GetTx().GetHash(); 45 : : } 46 : : template <typename T> 47 : 0 : bool operator()(const T& a, const T& b) const 48 : : { 49 : 0 : 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 [ # # ]: 0 : 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 : : const CTransactionRef tx; 75 : : mutable Parents m_parents; 76 : : mutable Children m_children; 77 : : const CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups 78 : : const int32_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) 79 : : const size_t nUsageSize; //!< ... and total memory usage 80 : : const int64_t nTime; //!< Local time when entering the mempool 81 : : const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay 82 : : const unsigned int entryHeight; //!< Chain height when entering the mempool 83 : : const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase 84 : : const int64_t sigOpCost; //!< Total sigop cost 85 : : CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block 86 : : LockPoints lockPoints; //!< Track the height and time at which tx was final 87 : : 88 : : // Information about descendants of this transaction that are in the 89 : : // mempool; if we remove this transaction we must remove all of these 90 : : // descendants as well. 91 : 0 : int64_t m_count_with_descendants{1}; //!< number of descendant transactions 92 : : // Using int64_t instead of int32_t to avoid signed integer overflow issues. 93 : : int64_t nSizeWithDescendants; //!< ... and size 94 : : CAmount nModFeesWithDescendants; //!< ... and total fees (all including us) 95 : : 96 : : // Analogous statistics for ancestor transactions 97 : 0 : int64_t m_count_with_ancestors{1}; 98 : : // Using int64_t instead of int32_t to avoid signed integer overflow issues. 99 : : int64_t nSizeWithAncestors; 100 : : CAmount nModFeesWithAncestors; 101 : : int64_t nSigOpCostWithAncestors; 102 : : 103 : : public: 104 : 0 : CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee, 105 : : int64_t time, unsigned int entry_height, uint64_t entry_sequence, 106 : : bool spends_coinbase, 107 : : int64_t sigops_cost, LockPoints lp) 108 : 0 : : tx{tx}, 109 : 0 : nFee{fee}, 110 [ # # ]: 0 : nTxWeight{GetTransactionWeight(*tx)}, 111 [ # # ]: 0 : nUsageSize{RecursiveDynamicUsage(tx)}, 112 : 0 : nTime{time}, 113 : 0 : entry_sequence{entry_sequence}, 114 : 0 : entryHeight{entry_height}, 115 : 0 : spendsCoinbase{spends_coinbase}, 116 : 0 : sigOpCost{sigops_cost}, 117 : 0 : m_modified_fee{nFee}, 118 : 0 : lockPoints{lp}, 119 [ # # ]: 0 : nSizeWithDescendants{GetTxSize()}, 120 : 0 : nModFeesWithDescendants{nFee}, 121 [ # # ]: 0 : nSizeWithAncestors{GetTxSize()}, 122 : 0 : nModFeesWithAncestors{nFee}, 123 : 0 : nSigOpCostWithAncestors{sigOpCost} {} 124 : : 125 : 0 : const CTransaction& GetTx() const { return *this->tx; } 126 : 0 : CTransactionRef GetSharedTx() const { return this->tx; } 127 : 0 : const CAmount& GetFee() const { return nFee; } 128 : 0 : int32_t GetTxSize() const 129 : : { 130 : 0 : return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp); 131 : : } 132 : 0 : int32_t GetTxWeight() const { return nTxWeight; } 133 : 0 : std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; } 134 : 0 : unsigned int GetHeight() const { return entryHeight; } 135 : 0 : uint64_t GetSequence() const { return entry_sequence; } 136 : 0 : int64_t GetSigOpCost() const { return sigOpCost; } 137 : 0 : CAmount GetModifiedFee() const { return m_modified_fee; } 138 : 0 : size_t DynamicMemoryUsage() const { return nUsageSize; } 139 : 0 : const LockPoints& GetLockPoints() const { return lockPoints; } 140 : : 141 : : // Adjusts the descendant state. 142 : : void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount); 143 : : // Adjusts the ancestor state 144 : : void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps); 145 : : // Updates the modified fees with descendants/ancestors. 146 : 0 : void UpdateModifiedFee(CAmount fee_diff) 147 : : { 148 : 0 : nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff); 149 : 0 : nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff); 150 : 0 : m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff); 151 : 0 : } 152 : : 153 : : // Update the LockPoints after a reorg 154 : 0 : void UpdateLockPoints(const LockPoints& lp) 155 : : { 156 : 0 : lockPoints = lp; 157 : 0 : } 158 : : 159 : 0 : uint64_t GetCountWithDescendants() const { return m_count_with_descendants; } 160 : 0 : int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } 161 : 0 : CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } 162 : : 163 : 0 : bool GetSpendsCoinbase() const { return spendsCoinbase; } 164 : : 165 : 0 : uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; } 166 : 0 : int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } 167 : 0 : CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } 168 : 0 : int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } 169 : : 170 : 0 : const Parents& GetMemPoolParentsConst() const { return m_parents; } 171 : 0 : const Children& GetMemPoolChildrenConst() const { return m_children; } 172 : 0 : Parents& GetMemPoolParents() const { return m_parents; } 173 : 0 : Children& GetMemPoolChildren() const { return m_children; } 174 : : 175 : : mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes 176 : : mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms 177 : : }; 178 : : 179 : : #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H