/Users/eugenesiegel/btc/bitcoin/src/node/miner.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2009-2010 Satoshi Nakamoto | 
| 2 |  | // Copyright (c) 2009-present 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 <interfaces/types.h> | 
| 10 |  | #include <node/types.h> | 
| 11 |  | #include <policy/policy.h> | 
| 12 |  | #include <primitives/block.h> | 
| 13 |  | #include <txmempool.h> | 
| 14 |  | #include <util/feefrac.h> | 
| 15 |  |  | 
| 16 |  | #include <cstdint> | 
| 17 |  | #include <memory> | 
| 18 |  | #include <optional> | 
| 19 |  |  | 
| 20 |  | #include <boost/multi_index/identity.hpp> | 
| 21 |  | #include <boost/multi_index/indexed_by.hpp> | 
| 22 |  | #include <boost/multi_index/ordered_index.hpp> | 
| 23 |  | #include <boost/multi_index/tag.hpp> | 
| 24 |  | #include <boost/multi_index_container.hpp> | 
| 25 |  |  | 
| 26 |  | class ArgsManager; | 
| 27 |  | class CBlockIndex; | 
| 28 |  | class CChainParams; | 
| 29 |  | class CScript; | 
| 30 |  | class Chainstate; | 
| 31 |  | class ChainstateManager; | 
| 32 |  |  | 
| 33 |  | namespace Consensus { struct Params; }; | 
| 34 |  |  | 
| 35 |  | using interfaces::BlockRef; | 
| 36 |  |  | 
| 37 |  | namespace node { | 
| 38 |  | class KernelNotifications; | 
| 39 |  |  | 
| 40 |  | static const bool DEFAULT_PRINT_MODIFIED_FEE = false; | 
| 41 |  |  | 
| 42 |  | struct CBlockTemplate | 
| 43 |  | { | 
| 44 |  |     CBlock block; | 
| 45 |  |     // Fees per transaction, not including coinbase transaction (unlike CBlock::vtx). | 
| 46 |  |     std::vector<CAmount> vTxFees; | 
| 47 |  |     // Sigops per transaction, not including coinbase transaction (unlike CBlock::vtx). | 
| 48 |  |     std::vector<int64_t> vTxSigOpsCost; | 
| 49 |  |     std::vector<unsigned char> vchCoinbaseCommitment; | 
| 50 |  |     /* A vector of package fee rates, ordered by the sequence in which | 
| 51 |  |      * packages are selected for inclusion in the block template.*/ | 
| 52 |  |     std::vector<FeeFrac> m_package_feerates; | 
| 53 |  | }; | 
| 54 |  |  | 
| 55 |  | // Container for tracking updates to ancestor feerate as we include (parent) | 
| 56 |  | // transactions in a block | 
| 57 |  | struct CTxMemPoolModifiedEntry { | 
| 58 |  |     explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) | 
| 59 | 0 |     { | 
| 60 | 0 |         iter = entry; | 
| 61 | 0 |         nSizeWithAncestors = entry->GetSizeWithAncestors(); | 
| 62 | 0 |         nModFeesWithAncestors = entry->GetModFeesWithAncestors(); | 
| 63 | 0 |         nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors(); | 
| 64 | 0 |     } | 
| 65 |  |  | 
| 66 | 0 |     CAmount GetModifiedFee() const { return iter->GetModifiedFee(); } | 
| 67 | 0 |     uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } | 
| 68 | 0 |     CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } | 
| 69 | 0 |     size_t GetTxSize() const { return iter->GetTxSize(); } | 
| 70 | 0 |     const CTransaction& GetTx() const { return iter->GetTx(); } | 
| 71 |  |  | 
| 72 |  |     CTxMemPool::txiter iter; | 
| 73 |  |     uint64_t nSizeWithAncestors; | 
| 74 |  |     CAmount nModFeesWithAncestors; | 
| 75 |  |     int64_t nSigOpCostWithAncestors; | 
| 76 |  | }; | 
| 77 |  |  | 
| 78 |  | /** Comparator for CTxMemPool::txiter objects. | 
| 79 |  |  *  It simply compares the internal memory address of the CTxMemPoolEntry object | 
| 80 |  |  *  pointed to. This means it has no meaning, and is only useful for using them | 
| 81 |  |  *  as key in other indexes. | 
| 82 |  |  */ | 
| 83 |  | struct CompareCTxMemPoolIter { | 
| 84 |  |     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const | 
| 85 | 0 |     { | 
| 86 | 0 |         return &(*a) < &(*b); | 
| 87 | 0 |     } | 
| 88 |  | }; | 
| 89 |  |  | 
| 90 |  | struct modifiedentry_iter { | 
| 91 |  |     typedef CTxMemPool::txiter result_type; | 
| 92 |  |     result_type operator() (const CTxMemPoolModifiedEntry &entry) const | 
| 93 | 0 |     { | 
| 94 | 0 |         return entry.iter; | 
| 95 | 0 |     } | 
| 96 |  | }; | 
| 97 |  |  | 
| 98 |  | // A comparator that sorts transactions based on number of ancestors. | 
| 99 |  | // This is sufficient to sort an ancestor package in an order that is valid | 
| 100 |  | // to appear in a block. | 
| 101 |  | struct CompareTxIterByAncestorCount { | 
| 102 |  |     bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const | 
| 103 | 0 |     { | 
| 104 | 0 |         if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) { | 
| 105 | 0 |             return a->GetCountWithAncestors() < b->GetCountWithAncestors(); | 
| 106 | 0 |         } | 
| 107 | 0 |         return CompareIteratorByHash()(a, b); | 
| 108 | 0 |     } | 
| 109 |  | }; | 
| 110 |  |  | 
| 111 |  |  | 
| 112 |  | struct CTxMemPoolModifiedEntry_Indices final : boost::multi_index::indexed_by< | 
| 113 |  |     boost::multi_index::ordered_unique< | 
| 114 |  |         modifiedentry_iter, | 
| 115 |  |         CompareCTxMemPoolIter | 
| 116 |  |     >, | 
| 117 |  |     // sorted by modified ancestor fee rate | 
| 118 |  |     boost::multi_index::ordered_non_unique< | 
| 119 |  |         // Reuse same tag from CTxMemPool's similar index | 
| 120 |  |         boost::multi_index::tag<ancestor_score>, | 
| 121 |  |         boost::multi_index::identity<CTxMemPoolModifiedEntry>, | 
| 122 |  |         CompareTxMemPoolEntryByAncestorFee | 
| 123 |  |     > | 
| 124 |  | > | 
| 125 |  | {}; | 
| 126 |  |  | 
| 127 |  | typedef boost::multi_index_container< | 
| 128 |  |     CTxMemPoolModifiedEntry, | 
| 129 |  |     CTxMemPoolModifiedEntry_Indices | 
| 130 |  | > indexed_modified_transaction_set; | 
| 131 |  |  | 
| 132 |  | typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; | 
| 133 |  | typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter; | 
| 134 |  |  | 
| 135 |  | struct update_for_parent_inclusion | 
| 136 |  | { | 
| 137 | 0 |     explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} | 
| 138 |  |  | 
| 139 |  |     void operator() (CTxMemPoolModifiedEntry &e) | 
| 140 | 0 |     { | 
| 141 | 0 |         e.nModFeesWithAncestors -= iter->GetModifiedFee(); | 
| 142 | 0 |         e.nSizeWithAncestors -= iter->GetTxSize(); | 
| 143 | 0 |         e.nSigOpCostWithAncestors -= iter->GetSigOpCost(); | 
| 144 | 0 |     } | 
| 145 |  |  | 
| 146 |  |     CTxMemPool::txiter iter; | 
| 147 |  | }; | 
| 148 |  |  | 
| 149 |  | /** Generate a new block, without valid proof-of-work */ | 
| 150 |  | class BlockAssembler | 
| 151 |  | { | 
| 152 |  | private: | 
| 153 |  |     // The constructed block template | 
| 154 |  |     std::unique_ptr<CBlockTemplate> pblocktemplate; | 
| 155 |  |  | 
| 156 |  |     // Information on the current status of the block | 
| 157 |  |     uint64_t nBlockWeight; | 
| 158 |  |     uint64_t nBlockTx; | 
| 159 |  |     uint64_t nBlockSigOpsCost; | 
| 160 |  |     CAmount nFees; | 
| 161 |  |     std::unordered_set<Txid, SaltedTxidHasher> inBlock; | 
| 162 |  |  | 
| 163 |  |     // Chain context for the block | 
| 164 |  |     int nHeight; | 
| 165 |  |     int64_t m_lock_time_cutoff; | 
| 166 |  |  | 
| 167 |  |     const CChainParams& chainparams; | 
| 168 |  |     const CTxMemPool* const m_mempool; | 
| 169 |  |     Chainstate& m_chainstate; | 
| 170 |  |  | 
| 171 |  | public: | 
| 172 |  |     struct Options : BlockCreateOptions { | 
| 173 |  |         // Configuration parameters for the block size | 
| 174 |  |         size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT}; | 
| 175 |  |         CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE}; | 
| 176 |  |         // Whether to call TestBlockValidity() at the end of CreateNewBlock(). | 
| 177 |  |         bool test_block_validity{true}; | 
| 178 |  |         bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE}; | 
| 179 |  |     }; | 
| 180 |  |  | 
| 181 |  |     explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options); | 
| 182 |  |  | 
| 183 |  |     /** Construct a new block template */ | 
| 184 |  |     std::unique_ptr<CBlockTemplate> CreateNewBlock(); | 
| 185 |  |  | 
| 186 |  |     /** The number of transactions in the last assembled block (excluding coinbase transaction) */ | 
| 187 |  |     inline static std::optional<int64_t> m_last_block_num_txs{}; | 
| 188 |  |     /** The weight of the last assembled block (including reserved weight for block header, txs count and coinbase tx) */ | 
| 189 |  |     inline static std::optional<int64_t> m_last_block_weight{}; | 
| 190 |  |  | 
| 191 |  | private: | 
| 192 |  |     const Options m_options; | 
| 193 |  |  | 
| 194 |  |     // utility functions | 
| 195 |  |     /** Clear the block's state and prepare for assembling a new block */ | 
| 196 |  |     void resetBlock(); | 
| 197 |  |     /** Add a tx to the block */ | 
| 198 |  |     void AddToBlock(CTxMemPool::txiter iter); | 
| 199 |  |  | 
| 200 |  |     // Methods for how to add transactions to a block. | 
| 201 |  |     /** Add transactions based on feerate including unconfirmed ancestors | 
| 202 |  |       * Increments nPackagesSelected / nDescendantsUpdated with corresponding | 
| 203 |  |       * statistics from the package selection (for logging statistics). | 
| 204 |  |       * | 
| 205 |  |       * @pre BlockAssembler::m_mempool must not be nullptr | 
| 206 |  |     */ | 
| 207 |  |     void addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(!m_mempool->cs); | 
| 208 |  |  | 
| 209 |  |     // helper functions for addPackageTxs() | 
| 210 |  |     /** Remove confirmed (inBlock) entries from given set */ | 
| 211 |  |     void onlyUnconfirmed(CTxMemPool::setEntries& testSet); | 
| 212 |  |     /** Test if a new package would "fit" in the block */ | 
| 213 |  |     bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const; | 
| 214 |  |     /** Perform checks on each transaction in a package: | 
| 215 |  |       * locktime, premature-witness, serialized size (if necessary) | 
| 216 |  |       * These checks should always succeed, and they're here | 
| 217 |  |       * only as an extra check in case of suboptimal node configuration */ | 
| 218 |  |     bool TestPackageTransactions(const CTxMemPool::setEntries& package) const; | 
| 219 |  |     /** Sort the package in an order that is valid to appear in a block */ | 
| 220 |  |     void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries); | 
| 221 |  | }; | 
| 222 |  |  | 
| 223 |  | /** | 
| 224 |  |  * Get the minimum time a miner should use in the next block. This always | 
| 225 |  |  * accounts for the BIP94 timewarp rule, so does not necessarily reflect the | 
| 226 |  |  * consensus limit. | 
| 227 |  |  */ | 
| 228 |  | int64_t GetMinimumTime(const CBlockIndex* pindexPrev, const int64_t difficulty_adjustment_interval); | 
| 229 |  |  | 
| 230 |  | int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); | 
| 231 |  |  | 
| 232 |  | /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */ | 
| 233 |  | void RegenerateCommitments(CBlock& block, ChainstateManager& chainman); | 
| 234 |  |  | 
| 235 |  | /** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */ | 
| 236 |  | void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options); | 
| 237 |  |  | 
| 238 |  | /* Compute the block's merkle root, insert or replace the coinbase transaction and the merkle root into the block */ | 
| 239 |  | void AddMerkleRootAndCoinbase(CBlock& block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce); | 
| 240 |  |  | 
| 241 |  | /** | 
| 242 |  |  * Return a new block template when fees rise to a certain threshold or after a | 
| 243 |  |  * new tip; return nullopt if timeout is reached. | 
| 244 |  |  */ | 
| 245 |  | std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainman, | 
| 246 |  |                                                       KernelNotifications& kernel_notifications, | 
| 247 |  |                                                       CTxMemPool* mempool, | 
| 248 |  |                                                       const std::unique_ptr<CBlockTemplate>& block_template, | 
| 249 |  |                                                       const BlockWaitOptions& options, | 
| 250 |  |                                                       const BlockAssembler::Options& assemble_options); | 
| 251 |  |  | 
| 252 |  | /* Locks cs_main and returns the block hash and block height of the active chain if it exists; otherwise, returns nullopt.*/ | 
| 253 |  | std::optional<BlockRef> GetTip(ChainstateManager& chainman); | 
| 254 |  |  | 
| 255 |  | /* 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`). | 
| 256 |  |  * Returns the current tip, or nullopt if the node is shutting down. */ | 
| 257 |  | std::optional<BlockRef> WaitTipChanged(ChainstateManager& chainman, KernelNotifications& kernel_notifications, const uint256& current_tip, MillisecondsDouble& timeout); | 
| 258 |  | } // namespace node | 
| 259 |  |  | 
| 260 |  | #endif // BITCOIN_NODE_MINER_H |