mempool_entry.h raw

   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  #include <util/time.h>
  17  
  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
 203