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