/ src / kernel / mempool_entry.h
mempool_entry.h
  1  // Copyright (c) 2009-present 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 <txgraph.h>
 15  #include <util/overflow.h>
 16  
 17  #include <chrono>
 18  #include <cstddef>
 19  #include <cstdint>
 20  #include <functional>
 21  #include <memory>
 22  #include <set>
 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 : public TxGraph::Ref
 66  {
 67  public:
 68      typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef;
 69  
 70  private:
 71      CTxMemPoolEntry(const CTxMemPoolEntry&) = delete;
 72  
 73      const CTransactionRef tx;
 74      const CAmount nFee;             //!< Cached to avoid expensive parent-transaction lookups
 75      const int32_t nTxWeight;         //!< ... and avoid recomputing tx weight (also used for GetTxSize())
 76      const size_t nUsageSize;        //!< ... and total memory usage
 77      const int64_t nTime;            //!< Local time when entering the mempool
 78      const uint64_t entry_sequence;  //!< Sequence number used to determine whether this transaction is too recent for relay
 79      const unsigned int entryHeight; //!< Chain height when entering the mempool
 80      const bool spendsCoinbase;      //!< keep track of transactions that spend a coinbase
 81      const int64_t sigOpCost;        //!< Total sigop cost
 82      mutable CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
 83      mutable LockPoints lockPoints;  //!< Track the height and time at which tx was final
 84  
 85  public:
 86      virtual ~CTxMemPoolEntry() = default;
 87      CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
 88                      int64_t time, unsigned int entry_height, uint64_t entry_sequence,
 89                      bool spends_coinbase,
 90                      int64_t sigops_cost, LockPoints lp)
 91          : tx{tx},
 92            nFee{fee},
 93            nTxWeight{GetTransactionWeight(*tx)},
 94            nUsageSize{RecursiveDynamicUsage(tx)},
 95            nTime{time},
 96            entry_sequence{entry_sequence},
 97            entryHeight{entry_height},
 98            spendsCoinbase{spends_coinbase},
 99            sigOpCost{sigops_cost},
100            m_modified_fee{nFee},
101            lockPoints{lp} {}
102  
103      CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
104      CTxMemPoolEntry(CTxMemPoolEntry&&) = default;
105      CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete;
106  
107      const CTransaction& GetTx() const { return *this->tx; }
108      CTransactionRef GetSharedTx() const { return this->tx; }
109      const CAmount& GetFee() const { return nFee; }
110      int32_t GetTxSize() const
111      {
112          return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
113      }
114      int32_t GetAdjustedWeight() const { return GetSigOpsAdjustedWeight(nTxWeight, sigOpCost, ::nBytesPerSigOp); }
115      int32_t GetTxWeight() const { return nTxWeight; }
116      std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
117      unsigned int GetHeight() const { return entryHeight; }
118      uint64_t GetSequence() const { return entry_sequence; }
119      int64_t GetSigOpCost() const { return sigOpCost; }
120      CAmount GetModifiedFee() const { return m_modified_fee; }
121      size_t DynamicMemoryUsage() const { return nUsageSize; }
122      const LockPoints& GetLockPoints() const { return lockPoints; }
123  
124      // Updates the modified fees with descendants/ancestors.
125      void UpdateModifiedFee(CAmount fee_diff) const
126      {
127          m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
128      }
129  
130      // Update the LockPoints after a reorg
131      void UpdateLockPoints(const LockPoints& lp) const
132      {
133          lockPoints = lp;
134      }
135  
136      bool GetSpendsCoinbase() const { return spendsCoinbase; }
137  
138      mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
139  };
140  
141  using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
142  
143  struct TransactionInfo {
144      const CTransactionRef m_tx;
145      /* The fee the transaction paid */
146      const CAmount m_fee;
147      /**
148       * The virtual transaction size.
149       *
150       * This is a policy field which considers the sigop cost of the
151       * transaction as well as its weight, and reinterprets it as bytes.
152       *
153       * It is the primary metric by which the mining algorithm selects
154       * transactions.
155       */
156      const int64_t m_virtual_transaction_size;
157      /* The block height the transaction entered the mempool */
158      const unsigned int txHeight;
159  
160      TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
161          : m_tx{tx},
162            m_fee{fee},
163            m_virtual_transaction_size{vsize},
164            txHeight{height} {}
165  };
166  
167  struct RemovedMempoolTransactionInfo {
168      TransactionInfo info;
169      explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
170          : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
171  };
172  
173  struct NewMempoolTransactionInfo {
174      TransactionInfo info;
175      /*
176       * This boolean indicates whether the transaction was added
177       * without enforcing mempool fee limits.
178       */
179      const bool m_mempool_limit_bypassed;
180      /* This boolean indicates whether the transaction is part of a package. */
181      const bool m_submitted_in_package;
182      /*
183       * This boolean indicates whether the blockchain is up to date when the
184       * transaction is added to the mempool.
185       */
186      const bool m_chainstate_is_current;
187      /* Indicates whether the transaction has unconfirmed parents. */
188      const bool m_has_no_mempool_parents;
189  
190      explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
191                                         const int64_t vsize, const unsigned int height,
192                                         const bool mempool_limit_bypassed, const bool submitted_in_package,
193                                         const bool chainstate_is_current,
194                                         const bool has_no_mempool_parents)
195          : info{tx, fee, vsize, height},
196            m_mempool_limit_bypassed{mempool_limit_bypassed},
197            m_submitted_in_package{submitted_in_package},
198            m_chainstate_is_current{chainstate_is_current},
199            m_has_no_mempool_parents{has_no_mempool_parents} {}
200  };
201  
202  #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H