/ src / kernel / mempool_entry.h
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