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