// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NODE_MINER_H #define BITCOIN_NODE_MINER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ArgsManager; class CBlockIndex; class CChainParams; class CScript; class Chainstate; class ChainstateManager; namespace Consensus { struct Params; }; using interfaces::BlockRef; namespace node { class KernelNotifications; static const bool DEFAULT_PRINT_MODIFIED_FEE = false; struct CBlockTemplate { CBlock block; // Fees per transaction, not including coinbase transaction (unlike CBlock::vtx). std::vector vTxFees; // Sigops per transaction, not including coinbase transaction (unlike CBlock::vtx). std::vector vTxSigOpsCost; std::vector vchCoinbaseCommitment; /* A vector of package fee rates, ordered by the sequence in which * packages are selected for inclusion in the block template.*/ std::vector m_package_feerates; }; /** Generate a new block, without valid proof-of-work */ class BlockAssembler { private: // The constructed block template std::unique_ptr pblocktemplate; // Information on the current status of the block uint64_t nBlockWeight; uint64_t nBlockTx; uint64_t nBlockSigOpsCost; CAmount nFees; // Chain context for the block int nHeight; int64_t m_lock_time_cutoff; const CChainParams& chainparams; const CTxMemPool* const m_mempool; Chainstate& m_chainstate; public: struct Options : BlockCreateOptions { // Configuration parameters for the block size size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT}; CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE}; // Whether to call TestBlockValidity() at the end of CreateNewBlock(). bool test_block_validity{true}; bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE}; }; explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options); /** Construct a new block template */ std::unique_ptr CreateNewBlock(); /** The number of transactions in the last assembled block (excluding coinbase transaction) */ inline static std::optional m_last_block_num_txs{}; /** The weight of the last assembled block (including reserved weight for block header, txs count and coinbase tx) */ inline static std::optional m_last_block_weight{}; private: const Options m_options; // utility functions /** Clear the block's state and prepare for assembling a new block */ void resetBlock(); /** Add a tx to the block */ void AddToBlock(const CTxMemPoolEntry& entry); // Methods for how to add transactions to a block. /** Add transactions based on chunk feerate * * @pre BlockAssembler::m_mempool must not be nullptr */ void addChunks() EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs); // helper functions for addChunks() /** Test if a new chunk would "fit" in the block */ bool TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const; /** Perform locktime checks on each transaction in a chunk: * This check should always succeed, and is here * only as an extra check in case of a bug */ bool TestChunkTransactions(const std::vector& txs) const; }; /** * Get the minimum time a miner should use in the next block. This always * accounts for the BIP94 timewarp rule, so does not necessarily reflect the * consensus limit. */ int64_t GetMinimumTime(const CBlockIndex* pindexPrev, const int64_t difficulty_adjustment_interval); int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman); /** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */ void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options); /* Compute the block's merkle root, insert or replace the coinbase transaction and the merkle root into the block */ void AddMerkleRootAndCoinbase(CBlock& block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce); /* Interrupt the current wait for the next block template. */ void InterruptWait(KernelNotifications& kernel_notifications, bool& interrupt_wait); /** * Return a new block template when fees rise to a certain threshold or after a * new tip; return nullopt if timeout is reached. */ std::unique_ptr WaitAndCreateNewBlock(ChainstateManager& chainman, KernelNotifications& kernel_notifications, CTxMemPool* mempool, const std::unique_ptr& block_template, const BlockWaitOptions& options, const BlockAssembler::Options& assemble_options, bool& interrupt_wait); /* Locks cs_main and returns the block hash and block height of the active chain if it exists; otherwise, returns nullopt.*/ std::optional GetTip(ChainstateManager& chainman); /* Waits for the connected tip to change until timeout has elapsed. During node initialization, this will wait until the tip is connected (regardless of `timeout`). * Returns the current tip, or nullopt if the node is shutting down. */ std::optional WaitTipChanged(ChainstateManager& chainman, KernelNotifications& kernel_notifications, const uint256& current_tip, MillisecondsDouble& timeout); } // namespace node #endif // BITCOIN_NODE_MINER_H