LCOV - code coverage report
Current view: top level - src/node - miner.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 28 30 93.3 %
Date: 2023-09-26 12:08:55 Functions: 14 15 93.3 %

          Line data    Source code
       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          38 :     explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
      47             :     {
      48          38 :         iter = entry;
      49          38 :         nSizeWithAncestors = entry->GetSizeWithAncestors();
      50          38 :         nModFeesWithAncestors = entry->GetModFeesWithAncestors();
      51          38 :         nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
      52          38 :     }
      53             : 
      54          12 :     CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
      55           6 :     uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
      56           6 :     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
      57          12 :     size_t GetTxSize() const { return iter->GetTxSize(); }
      58           0 :     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         147 :     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
      73             :     {
      74         147 :         return &(*a) < &(*b);
      75             :     }
      76             : };
      77             : 
      78             : struct modifiedentry_iter {
      79             :     typedef CTxMemPool::txiter result_type;
      80         185 :     result_type operator() (const CTxMemPoolModifiedEntry &entry) const
      81             :     {
      82         185 :         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          13 :     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
      91             :     {
      92          13 :         if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
      93          13 :             return a->GetCountWithAncestors() < b->GetCountWithAncestors();
      94             :         }
      95           0 :         return CompareIteratorByHash()(a, b);
      96          13 :     }
      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          37 :     explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
     122             : 
     123          37 :     void operator() (CTxMemPoolModifiedEntry &e)
     124             :     {
     125          37 :         e.nModFeesWithAncestors -= iter->GetModifiedFee();
     126          37 :         e.nSizeWithAncestors -= iter->GetTxSize();
     127          37 :         e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
     128          37 :     }
     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             :     CTxMemPool::setEntries 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        5059 :     struct Options {
     157             :         // Configuration parameters for the block size
     158        5059 :         size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
     159        5059 :         CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
     160             :         // Whether to call TestBlockValidity() at the end of CreateNewBlock().
     161        5059 :         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

Generated by: LCOV version 1.14