Branch data 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/ordered_index.hpp>
# 17 : : #include <boost/multi_index_container.hpp>
# 18 : :
# 19 : : class ChainstateManager;
# 20 : : class CBlockIndex;
# 21 : : class CChainParams;
# 22 : : class CScript;
# 23 : :
# 24 : : namespace Consensus { struct Params; };
# 25 : :
# 26 : : namespace node {
# 27 : : static const bool DEFAULT_PRINTPRIORITY = false;
# 28 : :
# 29 : : struct CBlockTemplate
# 30 : : {
# 31 : : CBlock block;
# 32 : : std::vector<CAmount> vTxFees;
# 33 : : std::vector<int64_t> vTxSigOpsCost;
# 34 : : std::vector<unsigned char> vchCoinbaseCommitment;
# 35 : : };
# 36 : :
# 37 : : // Container for tracking updates to ancestor feerate as we include (parent)
# 38 : : // transactions in a block
# 39 : : struct CTxMemPoolModifiedEntry {
# 40 : : explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
# 41 : 4042 : {
# 42 : 4042 : iter = entry;
# 43 : 4042 : nSizeWithAncestors = entry->GetSizeWithAncestors();
# 44 : 4042 : nModFeesWithAncestors = entry->GetModFeesWithAncestors();
# 45 : 4042 : nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
# 46 : 4042 : }
# 47 : :
# 48 : 4074065 : CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
# 49 : 2037103 : uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
# 50 : 2037103 : CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
# 51 : 4074065 : size_t GetTxSize() const { return iter->GetTxSize(); }
# 52 : 2032340 : const CTransaction& GetTx() const { return iter->GetTx(); }
# 53 : :
# 54 : : CTxMemPool::txiter iter;
# 55 : : uint64_t nSizeWithAncestors;
# 56 : : CAmount nModFeesWithAncestors;
# 57 : : int64_t nSigOpCostWithAncestors;
# 58 : : };
# 59 : :
# 60 : : /** Comparator for CTxMemPool::txiter objects.
# 61 : : * It simply compares the internal memory address of the CTxMemPoolEntry object
# 62 : : * pointed to. This means it has no meaning, and is only useful for using them
# 63 : : * as key in other indexes.
# 64 : : */
# 65 : : struct CompareCTxMemPoolIter {
# 66 : : bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
# 67 : 6039124 : {
# 68 : 6039124 : return &(*a) < &(*b);
# 69 : 6039124 : }
# 70 : : };
# 71 : :
# 72 : : struct modifiedentry_iter {
# 73 : : typedef CTxMemPool::txiter result_type;
# 74 : : result_type operator() (const CTxMemPoolModifiedEntry &entry) const
# 75 : 7028852 : {
# 76 : 7028852 : return entry.iter;
# 77 : 7028852 : }
# 78 : : };
# 79 : :
# 80 : : // A comparator that sorts transactions based on number of ancestors.
# 81 : : // This is sufficient to sort an ancestor package in an order that is valid
# 82 : : // to appear in a block.
# 83 : : struct CompareTxIterByAncestorCount {
# 84 : : bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
# 85 : 48201 : {
# 86 [ + + ]: 48201 : if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
# 87 : 47992 : return a->GetCountWithAncestors() < b->GetCountWithAncestors();
# 88 : 47992 : }
# 89 : 209 : return CompareIteratorByHash()(a, b);
# 90 : 48201 : }
# 91 : : };
# 92 : :
# 93 : : typedef boost::multi_index_container<
# 94 : : CTxMemPoolModifiedEntry,
# 95 : : boost::multi_index::indexed_by<
# 96 : : boost::multi_index::ordered_unique<
# 97 : : modifiedentry_iter,
# 98 : : CompareCTxMemPoolIter
# 99 : : >,
# 100 : : // sorted by modified ancestor fee rate
# 101 : : boost::multi_index::ordered_non_unique<
# 102 : : // Reuse same tag from CTxMemPool's similar index
# 103 : : boost::multi_index::tag<ancestor_score>,
# 104 : : boost::multi_index::identity<CTxMemPoolModifiedEntry>,
# 105 : : CompareTxMemPoolEntryByAncestorFee
# 106 : : >
# 107 : : >
# 108 : : > indexed_modified_transaction_set;
# 109 : :
# 110 : : typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
# 111 : : typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
# 112 : :
# 113 : : struct update_for_parent_inclusion
# 114 : : {
# 115 : 497818 : explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
# 116 : :
# 117 : : void operator() (CTxMemPoolModifiedEntry &e)
# 118 : 497818 : {
# 119 : 497818 : e.nModFeesWithAncestors -= iter->GetFee();
# 120 : 497818 : e.nSizeWithAncestors -= iter->GetTxSize();
# 121 : 497818 : e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
# 122 : 497818 : }
# 123 : :
# 124 : : CTxMemPool::txiter iter;
# 125 : : };
# 126 : :
# 127 : : /** Generate a new block, without valid proof-of-work */
# 128 : : class BlockAssembler
# 129 : : {
# 130 : : private:
# 131 : : // The constructed block template
# 132 : : std::unique_ptr<CBlockTemplate> pblocktemplate;
# 133 : :
# 134 : : // Configuration parameters for the block size
# 135 : : unsigned int nBlockMaxWeight;
# 136 : : CFeeRate blockMinFeeRate;
# 137 : :
# 138 : : // Information on the current status of the block
# 139 : : uint64_t nBlockWeight;
# 140 : : uint64_t nBlockTx;
# 141 : : uint64_t nBlockSigOpsCost;
# 142 : : CAmount nFees;
# 143 : : CTxMemPool::setEntries inBlock;
# 144 : :
# 145 : : // Chain context for the block
# 146 : : int nHeight;
# 147 : : int64_t m_lock_time_cutoff;
# 148 : :
# 149 : : const CChainParams& chainparams;
# 150 : : const CTxMemPool& m_mempool;
# 151 : : CChainState& m_chainstate;
# 152 : :
# 153 : : public:
# 154 : : struct Options {
# 155 : : Options();
# 156 : : size_t nBlockMaxWeight;
# 157 : : CFeeRate blockMinFeeRate;
# 158 : : };
# 159 : :
# 160 : : explicit BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params);
# 161 : : explicit BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params, const Options& options);
# 162 : :
# 163 : : /** Construct a new block template with coinbase to scriptPubKeyIn */
# 164 : : std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
# 165 : :
# 166 : : inline static std::optional<int64_t> m_last_block_num_txs{};
# 167 : : inline static std::optional<int64_t> m_last_block_weight{};
# 168 : :
# 169 : : private:
# 170 : : // utility functions
# 171 : : /** Clear the block's state and prepare for assembling a new block */
# 172 : : void resetBlock();
# 173 : : /** Add a tx to the block */
# 174 : : void AddToBlock(CTxMemPool::txiter iter);
# 175 : :
# 176 : : // Methods for how to add transactions to a block.
# 177 : : /** Add transactions based on feerate including unconfirmed ancestors
# 178 : : * Increments nPackagesSelected / nDescendantsUpdated with corresponding
# 179 : : * statistics from the package selection (for logging statistics). */
# 180 : : void addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
# 181 : :
# 182 : : // helper functions for addPackageTxs()
# 183 : : /** Remove confirmed (inBlock) entries from given set */
# 184 : : void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
# 185 : : /** Test if a new package would "fit" in the block */
# 186 : : bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const;
# 187 : : /** Perform checks on each transaction in a package:
# 188 : : * locktime, premature-witness, serialized size (if necessary)
# 189 : : * These checks should always succeed, and they're here
# 190 : : * only as an extra check in case of suboptimal node configuration */
# 191 : : bool TestPackageTransactions(const CTxMemPool::setEntries& package) const;
# 192 : : /** Return true if given transaction from mapTx has already been evaluated,
# 193 : : * or if the transaction's cached data in mapTx is incorrect. */
# 194 : : bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set& mapModifiedTx, CTxMemPool::setEntries& failedTx) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
# 195 : : /** Sort the package in an order that is valid to appear in a block */
# 196 : : void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
# 197 : : /** Add descendants of given transactions to mapModifiedTx with ancestor
# 198 : : * state updated assuming given transactions are inBlock. Returns number
# 199 : : * of updated descendants. */
# 200 : : int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set& mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
# 201 : : };
# 202 : :
# 203 : : int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
# 204 : :
# 205 : : /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
# 206 : : void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
# 207 : : } // namespace node
# 208 : :
# 209 : : #endif // BITCOIN_NODE_MINER_H
|