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 10268 : bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const 43 : { 44 10268 : return a.get().GetTx().GetHash() < b.get().GetTx().GetHash(); 45 : } 46 : template <typename T> 47 10244 : bool operator()(const T& a, const T& b) const 48 : { 49 10244 : 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 2211 : 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 5047 : 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 5047 : 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 15141 : 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 5047 : : tx{tx}, 109 5047 : nFee{fee}, 110 5047 : nTxWeight{GetTransactionWeight(*tx)}, 111 5047 : nUsageSize{RecursiveDynamicUsage(tx)}, 112 5047 : nTime{time}, 113 5047 : entry_sequence{entry_sequence}, 114 5047 : entryHeight{entry_height}, 115 5047 : spendsCoinbase{spends_coinbase}, 116 5047 : sigOpCost{sigops_cost}, 117 5047 : m_modified_fee{nFee}, 118 5047 : lockPoints{lp}, 119 5047 : nSizeWithDescendants{GetTxSize()}, 120 5047 : nModFeesWithDescendants{nFee}, 121 5047 : nSizeWithAncestors{GetTxSize()}, 122 5047 : nModFeesWithAncestors{nFee}, 123 10094 : nSigOpCostWithAncestors{sigOpCost} {} 124 : 125 141907 : const CTransaction& GetTx() const { return *this->tx; } 126 34353 : CTransactionRef GetSharedTx() const { return this->tx; } 127 15229 : const CAmount& GetFee() const { return nFee; } 128 63867 : int32_t GetTxSize() const 129 : { 130 63867 : return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp); 131 : } 132 815 : int32_t GetTxWeight() const { return nTxWeight; } 133 9407 : 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 4318 : int64_t GetSigOpCost() const { return sigOpCost; } 137 29457 : CAmount GetModifiedFee() const { return m_modified_fee; } 138 6324 : 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 466 : void UpdateModifiedFee(CAmount fee_diff) 147 : { 148 466 : nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff); 149 466 : nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff); 150 466 : m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff); 151 466 : } 152 : 153 : // Update the LockPoints after a reorg 154 0 : void UpdateLockPoints(const LockPoints& lp) 155 : { 156 0 : lockPoints = lp; 157 0 : } 158 : 159 1899 : uint64_t GetCountWithDescendants() const { return m_count_with_descendants; } 160 9155 : int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } 161 4996 : CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } 162 : 163 0 : bool GetSpendsCoinbase() const { return spendsCoinbase; } 164 : 165 9031 : uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; } 166 8748 : int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } 167 8748 : CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } 168 3934 : int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } 169 : 170 16809 : const Parents& GetMemPoolParentsConst() const { return m_parents; } 171 13341 : const Children& GetMemPoolChildrenConst() const { return m_children; } 172 348 : Parents& GetMemPoolParents() const { return m_parents; } 173 692 : 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