LCOV - code coverage report
Current view: top level - src/node - miner.h (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 26 27 96.3 %
Date: 2026-06-25 07:23:51 Functions: 19 19 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 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 <primitives/block.h>
      10             : #include <txmempool.h>
      11             : 
      12             : #include <memory>
      13             : #include <optional>
      14             : #include <stdint.h>
      15             : 
      16             : #include <boost/multi_index/identity.hpp>
      17             : #include <boost/multi_index/indexed_by.hpp>
      18             : #include <boost/multi_index/ordered_index.hpp>
      19             : #include <boost/multi_index/tag.hpp>
      20             : #include <boost/multi_index_container.hpp>
      21             : 
      22             : class CBlockIndex;
      23             : class CChainParams;
      24             : class CChainstateHelper;
      25             : class CConnman;
      26             : class CEvoDB;
      27             : class CScript;
      28             : struct LLMQContext;
      29             : 
      30             : namespace chainlock
      31             : {
      32             : class Chainlocks;
      33             : class ChainlockHandler;
      34             : } // namespace chainlock
      35             : namespace Consensus { struct Params; };
      36             : namespace llmq {
      37             : class CInstantSendManager;
      38             : class CQuorumBlockProcessor;
      39             : class CQuorumManager;
      40             : } // namespace llmq
      41             : 
      42             : namespace node {
      43             : class BlockManager;
      44             : struct NodeContext;
      45             : 
      46             : static const bool DEFAULT_PRINTPRIORITY = false;
      47             : 
      48             : struct CBlockTemplate
      49             : {
      50             :     CBlock block;
      51             :     std::vector<CAmount> vTxFees;
      52             :     std::vector<int64_t> vTxSigOps;
      53             :     uint32_t nPrevBits; // nBits of previous block (for subsidy calculation)
      54             :     std::vector<CTxOut> voutMasternodePayments; // masternode payment
      55             :     std::vector<CTxOut> voutSuperblockPayments; // superblock payment
      56             : };
      57             : 
      58             : // Container for tracking updates to ancestor feerate as we include (parent)
      59             : // transactions in a block
      60             : struct CTxMemPoolModifiedEntry {
      61        2344 :     explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
      62        1172 :     {
      63        1172 :         iter = entry;
      64        1172 :         nSizeWithAncestors = entry->GetSizeWithAncestors();
      65        1172 :         nModFeesWithAncestors = entry->GetModFeesWithAncestors();
      66        1172 :         nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors();
      67        2344 :     }
      68             : 
      69     5889526 :     CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
      70     2944790 :     uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
      71     2944790 :     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
      72     5889526 :     size_t GetTxSize() const { return iter->GetTxSize(); }
      73     2944708 :     const CTransaction& GetTx() const { return iter->GetTx(); }
      74             : 
      75             :     CTxMemPool::txiter iter;
      76             :     uint64_t nSizeWithAncestors;
      77             :     CAmount nModFeesWithAncestors;
      78             :     unsigned int nSigOpCountWithAncestors;
      79             : };
      80             : 
      81             : /** Comparator for CTxMemPool::txiter objects.
      82             :  *  It simply compares the internal memory address of the CTxMemPoolEntry object
      83             :  *  pointed to. This means it has no meaning, and is only useful for using them
      84             :  *  as key in other indexes.
      85             :  */
      86             : struct CompareCTxMemPoolIter {
      87     8884688 :     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
      88             :     {
      89     8884688 :         return &(*a) < &(*b);
      90             :     }
      91             : };
      92             : 
      93             : struct modifiedentry_iter {
      94             :     typedef CTxMemPool::txiter result_type;
      95    10344454 :     result_type operator() (const CTxMemPoolModifiedEntry &entry) const
      96             :     {
      97    10344454 :         return entry.iter;
      98             :     }
      99             : };
     100             : 
     101             : // A comparator that sorts transactions based on number of ancestors.
     102             : // This is sufficient to sort an ancestor package in an order that is valid
     103             : // to appear in a block.
     104             : struct CompareTxIterByAncestorCount {
     105       17794 :     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
     106             :     {
     107       17794 :         if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
     108       17794 :             return a->GetCountWithAncestors() < b->GetCountWithAncestors();
     109             :         }
     110           0 :         return CompareIteratorByHash()(a, b);
     111       17794 :     }
     112             : };
     113             : 
     114             : typedef boost::multi_index_container<
     115             :     CTxMemPoolModifiedEntry,
     116             :     boost::multi_index::indexed_by<
     117             :         boost::multi_index::ordered_unique<
     118             :             modifiedentry_iter,
     119             :             CompareCTxMemPoolIter
     120             :         >,
     121             :         // sorted by modified ancestor fee rate
     122             :         boost::multi_index::ordered_non_unique<
     123             :             // Reuse same tag from CTxMemPool's similar index
     124             :             boost::multi_index::tag<ancestor_score>,
     125             :             boost::multi_index::identity<CTxMemPoolModifiedEntry>,
     126             :             CompareTxMemPoolEntryByAncestorFee
     127             :         >
     128             :     >
     129             : > indexed_modified_transaction_set;
     130             : 
     131             : typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
     132             : typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
     133             : 
     134             : struct update_for_parent_inclusion
     135             : {
     136     1462634 :     explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
     137             : 
     138      731317 :     void operator() (CTxMemPoolModifiedEntry &e)
     139             :     {
     140      731317 :         e.nModFeesWithAncestors -= iter->GetModifiedFee();
     141      731317 :         e.nSizeWithAncestors -= iter->GetTxSize();
     142      731317 :         e.nSigOpCountWithAncestors -= iter->GetSigOpCount();
     143      731317 :     }
     144             : 
     145             :     CTxMemPool::txiter iter;
     146             : };
     147             : 
     148             : /** Generate a new block, without valid proof-of-work */
     149             : class BlockAssembler
     150             : {
     151             : private:
     152             :     // The constructed block template
     153             :     std::unique_ptr<CBlockTemplate> pblocktemplate;
     154             : 
     155             :     // Configuration parameters for the block size
     156             :     unsigned int nBlockMaxSize;
     157             :     unsigned int nBlockMaxSigOps;
     158             :     CFeeRate blockMinFeeRate;
     159             : 
     160             :     // Information on the current status of the block
     161             :     uint64_t nBlockSize;
     162             :     uint64_t nBlockTx;
     163             :     unsigned int nBlockSigOps;
     164             :     CAmount nFees;
     165             :     CTxMemPool::setEntries inBlock;
     166             : 
     167             :     // Chain context for the block
     168             :     int nHeight;
     169             :     int64_t m_lock_time_cutoff;
     170             : 
     171             :     BlockManager& m_blockman;
     172             :     CChainstateHelper& m_chain_helper;
     173             :     CChainState& m_chainstate;
     174             :     CEvoDB& m_evoDb;
     175             :     const chainlock::Chainlocks& m_chainlocks;
     176             :     chainlock::ChainlockHandler& m_clhandler;
     177             :     llmq::CInstantSendManager& m_isman;
     178             :     const CChainParams& chainparams;
     179             :     const CTxMemPool* const m_mempool;
     180             :     const llmq::CQuorumBlockProcessor& m_quorum_block_processor;
     181             :     const llmq::CQuorumManager& m_qman;
     182             : 
     183             : public:
     184             :     struct Options {
     185             :         Options();
     186             :         size_t nBlockMaxSize;
     187             :         CFeeRate blockMinFeeRate;
     188             :     };
     189             : 
     190             :     explicit BlockAssembler(CChainState& chainstate, const node::NodeContext& node, const CTxMemPool* mempool, const CChainParams& params);
     191             :     explicit BlockAssembler(CChainState& chainstate, const node::NodeContext& node, const CTxMemPool* mempool, const CChainParams& params,
     192             :                             const Options& options);
     193             : 
     194             :     /** Construct a new block template with coinbase to scriptPubKeyIn */
     195             :     std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
     196             : 
     197             :     inline static std::optional<int64_t> m_last_block_num_txs{};
     198             :     inline static std::optional<int64_t> m_last_block_size{};
     199             : 
     200             : private:
     201             :     // utility functions
     202             :     /** Clear the block's state and prepare for assembling a new block */
     203             :     void resetBlock();
     204             :     /** Add a tx to the block */
     205             :     void AddToBlock(CTxMemPool::txiter iter);
     206             : 
     207             :     // Methods for how to add transactions to a block.
     208             :     /** Add transactions based on feerate including unconfirmed ancestors
     209             :       * Increments nPackagesSelected / nDescendantsUpdated with corresponding
     210             :       * statistics from the package selection (for logging statistics). */
     211             :     void addPackageTxs(const CTxMemPool& mempool, int& nPackagesSelected, int& nDescendantsUpdated,
     212             :                        const CBlockIndex* pindexPrev) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
     213             : 
     214             :     // helper functions for addPackageTxs()
     215             :     /** Remove confirmed (inBlock) entries from given set */
     216             :     void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
     217             :     /** Test if a new package would "fit" in the block */
     218             :     bool TestPackage(uint64_t packageSize, unsigned int packageSigOps) const;
     219             :     /** Perform checks on each transaction in a package:
     220             :       * locktime
     221             :       * These checks should always succeed, and they're here
     222             :       * only as an extra check in case of suboptimal node configuration */
     223             :     bool TestPackageTransactions(const CTxMemPool::setEntries& package) const;
     224             :     /** Sort the package in an order that is valid to appear in a block */
     225             :     void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
     226             : };
     227             : 
     228             : int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
     229             : } // namespace node
     230             : 
     231             : #endif // BITCOIN_NODE_MINER_H

Generated by: LCOV version 1.16