/ src / node / miner.h
miner.h
  1  // Copyright (c) 2009-2010 Satoshi Nakamoto
  2  // Copyright (c) 2009-2022 The Bitcoin Core developers
  3  // Distributed under the MIT software license, see the accompanying
  4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5  
  6  #ifndef BITCOIN_NODE_MINER_H
  7  #define BITCOIN_NODE_MINER_H
  8  
  9  #include <node/types.h>
 10  #include <policy/policy.h>
 11  #include <primitives/block.h>
 12  #include <txmempool.h>
 13  #include <util/feefrac.h>
 14  
 15  #include <memory>
 16  #include <optional>
 17  #include <stdint.h>
 18  
 19  #include <boost/multi_index/identity.hpp>
 20  #include <boost/multi_index/indexed_by.hpp>
 21  #include <boost/multi_index/ordered_index.hpp>
 22  #include <boost/multi_index/tag.hpp>
 23  #include <boost/multi_index_container.hpp>
 24  
 25  class ArgsManager;
 26  class CBlockIndex;
 27  class CChainParams;
 28  class CScript;
 29  class Chainstate;
 30  class ChainstateManager;
 31  
 32  namespace Consensus { struct Params; };
 33  
 34  namespace node {
 35  static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
 36  
 37  struct CBlockTemplate
 38  {
 39      CBlock block;
 40      // Fees per transaction, not including coinbase transaction (unlike CBlock::vtx).
 41      std::vector<CAmount> vTxFees;
 42      // Sigops per transaction, not including coinbase transaction (unlike CBlock::vtx).
 43      std::vector<int64_t> vTxSigOpsCost;
 44      std::vector<unsigned char> vchCoinbaseCommitment;
 45      /* A vector of package fee rates, ordered by the sequence in which
 46       * packages are selected for inclusion in the block template.*/
 47      std::vector<FeeFrac> m_package_feerates;
 48  };
 49  
 50  // Container for tracking updates to ancestor feerate as we include (parent)
 51  // transactions in a block
 52  struct CTxMemPoolModifiedEntry {
 53      explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
 54      {
 55          iter = entry;
 56          nSizeWithAncestors = entry->GetSizeWithAncestors();
 57          nModFeesWithAncestors = entry->GetModFeesWithAncestors();
 58          nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
 59      }
 60  
 61      CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
 62      uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
 63      CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
 64      size_t GetTxSize() const { return iter->GetTxSize(); }
 65      const CTransaction& GetTx() const { return iter->GetTx(); }
 66  
 67      CTxMemPool::txiter iter;
 68      uint64_t nSizeWithAncestors;
 69      CAmount nModFeesWithAncestors;
 70      int64_t nSigOpCostWithAncestors;
 71  };
 72  
 73  /** Comparator for CTxMemPool::txiter objects.
 74   *  It simply compares the internal memory address of the CTxMemPoolEntry object
 75   *  pointed to. This means it has no meaning, and is only useful for using them
 76   *  as key in other indexes.
 77   */
 78  struct CompareCTxMemPoolIter {
 79      bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
 80      {
 81          return &(*a) < &(*b);
 82      }
 83  };
 84  
 85  struct modifiedentry_iter {
 86      typedef CTxMemPool::txiter result_type;
 87      result_type operator() (const CTxMemPoolModifiedEntry &entry) const
 88      {
 89          return entry.iter;
 90      }
 91  };
 92  
 93  // A comparator that sorts transactions based on number of ancestors.
 94  // This is sufficient to sort an ancestor package in an order that is valid
 95  // to appear in a block.
 96  struct CompareTxIterByAncestorCount {
 97      bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
 98      {
 99          if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
100              return a->GetCountWithAncestors() < b->GetCountWithAncestors();
101          }
102          return CompareIteratorByHash()(a, b);
103      }
104  };
105  
106  
107  struct CTxMemPoolModifiedEntry_Indices final : boost::multi_index::indexed_by<
108      boost::multi_index::ordered_unique<
109          modifiedentry_iter,
110          CompareCTxMemPoolIter
111      >,
112      // sorted by modified ancestor fee rate
113      boost::multi_index::ordered_non_unique<
114          // Reuse same tag from CTxMemPool's similar index
115          boost::multi_index::tag<ancestor_score>,
116          boost::multi_index::identity<CTxMemPoolModifiedEntry>,
117          CompareTxMemPoolEntryByAncestorFee
118      >
119  >
120  {};
121  
122  typedef boost::multi_index_container<
123      CTxMemPoolModifiedEntry,
124      CTxMemPoolModifiedEntry_Indices
125  > indexed_modified_transaction_set;
126  
127  typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
128  typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
129  
130  struct update_for_parent_inclusion
131  {
132      explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
133  
134      void operator() (CTxMemPoolModifiedEntry &e)
135      {
136          e.nModFeesWithAncestors -= iter->GetModifiedFee();
137          e.nSizeWithAncestors -= iter->GetTxSize();
138          e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
139      }
140  
141      CTxMemPool::txiter iter;
142  };
143  
144  /** Generate a new block, without valid proof-of-work */
145  class BlockAssembler
146  {
147  private:
148      // The constructed block template
149      std::unique_ptr<CBlockTemplate> pblocktemplate;
150  
151      // Information on the current status of the block
152      uint64_t nBlockWeight;
153      uint64_t nBlockTx;
154      uint64_t nBlockSigOpsCost;
155      CAmount nFees;
156      std::unordered_set<Txid, SaltedTxidHasher> inBlock;
157  
158      // Chain context for the block
159      int nHeight;
160      int64_t m_lock_time_cutoff;
161  
162      const CChainParams& chainparams;
163      const CTxMemPool* const m_mempool;
164      Chainstate& m_chainstate;
165  
166  public:
167      struct Options : BlockCreateOptions {
168          // Configuration parameters for the block size
169          size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
170          CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
171          // Whether to call TestBlockValidity() at the end of CreateNewBlock().
172          bool test_block_validity{true};
173          bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
174      };
175  
176      explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
177  
178      /** Construct a new block template */
179      std::unique_ptr<CBlockTemplate> CreateNewBlock();
180  
181      /** The number of transactions in the last assembled block (excluding coinbase transaction) */
182      inline static std::optional<int64_t> m_last_block_num_txs{};
183      /** The weight of the last assembled block (including reserved weight for block header, txs count and coinbase tx) */
184      inline static std::optional<int64_t> m_last_block_weight{};
185  
186  private:
187      const Options m_options;
188  
189      // utility functions
190      /** Clear the block's state and prepare for assembling a new block */
191      void resetBlock();
192      /** Add a tx to the block */
193      void AddToBlock(CTxMemPool::txiter iter);
194  
195      // Methods for how to add transactions to a block.
196      /** Add transactions based on feerate including unconfirmed ancestors
197        * Increments nPackagesSelected / nDescendantsUpdated with corresponding
198        * statistics from the package selection (for logging statistics).
199        *
200        * @pre BlockAssembler::m_mempool must not be nullptr
201      */
202      void addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(!m_mempool->cs);
203  
204      // helper functions for addPackageTxs()
205      /** Remove confirmed (inBlock) entries from given set */
206      void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
207      /** Test if a new package would "fit" in the block */
208      bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const;
209      /** Perform checks on each transaction in a package:
210        * locktime, premature-witness, serialized size (if necessary)
211        * These checks should always succeed, and they're here
212        * only as an extra check in case of suboptimal node configuration */
213      bool TestPackageTransactions(const CTxMemPool::setEntries& package) const;
214      /** Sort the package in an order that is valid to appear in a block */
215      void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
216  };
217  
218  /**
219   * Get the minimum time a miner should use in the next block. This always
220   * accounts for the BIP94 timewarp rule, so does not necessarily reflect the
221   * consensus limit.
222   */
223  int64_t GetMinimumTime(const CBlockIndex* pindexPrev, const int64_t difficulty_adjustment_interval);
224  
225  int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
226  
227  /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
228  void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
229  
230  /** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */
231  void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options);
232  } // namespace node
233  
234  #endif // BITCOIN_NODE_MINER_H