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 <node/types.h>
10 : : #include <policy/policy.h>
11 : : #include <primitives/block.h>
12 : : #include <txmempool.h>
13 : :
14 : : #include <memory>
15 : : #include <optional>
16 : : #include <stdint.h>
17 : :
18 : : #include <boost/multi_index/identity.hpp>
19 : : #include <boost/multi_index/indexed_by.hpp>
20 : : #include <boost/multi_index/ordered_index.hpp>
21 : : #include <boost/multi_index/tag.hpp>
22 : : #include <boost/multi_index_container.hpp>
23 : :
24 : : class ArgsManager;
25 : : class CBlockIndex;
26 : : class CChainParams;
27 : : class CScript;
28 : : class Chainstate;
29 : : class ChainstateManager;
30 : :
31 : : namespace Consensus { struct Params; };
32 : :
33 : : namespace node {
34 : : static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
35 : :
36 : : struct CBlockTemplate
37 : : {
38 : : CBlock block;
39 : : std::vector<CAmount> vTxFees;
40 : : std::vector<int64_t> vTxSigOpsCost;
41 : : std::vector<unsigned char> vchCoinbaseCommitment;
42 : : };
43 : :
44 : : // Container for tracking updates to ancestor feerate as we include (parent)
45 : : // transactions in a block
46 : : struct CTxMemPoolModifiedEntry {
47 : 36585 : explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
48 [ + - + - ]: 36585 : {
49 : : iter = entry;
50 [ + - + - ]: 36585 : nSizeWithAncestors = entry->GetSizeWithAncestors();
51 [ + - + - ]: 36585 : nModFeesWithAncestors = entry->GetModFeesWithAncestors();
52 [ + - + - ]: 36585 : nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
53 : : }
54 : :
55 : 3408406 : CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
56 : 1512566 : uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
57 : 3973052 : CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
58 [ + + ]: 2460486 : size_t GetTxSize() const { return iter->GetTxSize(); }
59 : 341045 : const CTransaction& GetTx() const { return iter->GetTx(); }
60 : :
61 : : CTxMemPool::txiter iter;
62 : : uint64_t nSizeWithAncestors;
63 : : CAmount nModFeesWithAncestors;
64 : : int64_t nSigOpCostWithAncestors;
65 : : };
66 : :
67 : : /** Comparator for CTxMemPool::txiter objects.
68 : : * It simply compares the internal memory address of the CTxMemPoolEntry object
69 : : * pointed to. This means it has no meaning, and is only useful for using them
70 : : * as key in other indexes.
71 : : */
72 : : struct CompareCTxMemPoolIter {
73 : 3650076 : bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
74 : : {
75 : 3650076 : return &(*a) < &(*b);
76 : : }
77 : : };
78 : :
79 : : struct modifiedentry_iter {
80 : : typedef CTxMemPool::txiter result_type;
81 : 3675264 : result_type operator() (const CTxMemPoolModifiedEntry &entry) const
82 : : {
83 [ + - - + : 3509163 : return entry.iter;
+ + + - +
- + - + +
+ + + + +
+ ]
84 : : }
85 : : };
86 : :
87 : : // A comparator that sorts transactions based on number of ancestors.
88 : : // This is sufficient to sort an ancestor package in an order that is valid
89 : : // to appear in a block.
90 : : struct CompareTxIterByAncestorCount {
91 : 149753 : bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
92 : : {
93 [ + + ]: 149753 : if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
94 : 138018 : return a->GetCountWithAncestors() < b->GetCountWithAncestors();
95 : : }
96 : 11735 : return CompareIteratorByHash()(a, b);
97 : : }
98 : : };
99 : :
100 : :
101 : : struct CTxMemPoolModifiedEntry_Indices final : 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 : : {};
115 : :
116 : : typedef boost::multi_index_container<
117 : : CTxMemPoolModifiedEntry,
118 : : CTxMemPoolModifiedEntry_Indices
119 : : > indexed_modified_transaction_set;
120 : :
121 : : typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
122 : : typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
123 : :
124 : : struct update_for_parent_inclusion
125 : : {
126 [ + - ]: 362710 : explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
127 : :
128 : 362710 : void operator() (CTxMemPoolModifiedEntry &e)
129 : : {
130 : 362710 : e.nModFeesWithAncestors -= iter->GetModifiedFee();
131 : 362710 : e.nSizeWithAncestors -= iter->GetTxSize();
132 : 362710 : e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
133 : 362710 : }
134 : :
135 : : CTxMemPool::txiter iter;
136 : : };
137 : :
138 : : /** Generate a new block, without valid proof-of-work */
139 [ + - ]: 116116 : class BlockAssembler
140 : : {
141 : : private:
142 : : // The constructed block template
143 : : std::unique_ptr<CBlockTemplate> pblocktemplate;
144 : :
145 : : // Information on the current status of the block
146 : : uint64_t nBlockWeight;
147 : : uint64_t nBlockTx;
148 : : uint64_t nBlockSigOpsCost;
149 : : CAmount nFees;
150 : : std::unordered_set<Txid, SaltedTxidHasher> inBlock;
151 : :
152 : : // Chain context for the block
153 : : int nHeight;
154 : : int64_t m_lock_time_cutoff;
155 : :
156 : : const CChainParams& chainparams;
157 : : const CTxMemPool* const m_mempool;
158 : : Chainstate& m_chainstate;
159 : :
160 : : public:
161 [ + - ]: 116116 : struct Options : BlockCreateOptions {
162 : : // Configuration parameters for the block size
163 : : size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
164 : : CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
165 : : // Whether to call TestBlockValidity() at the end of CreateNewBlock().
166 : : bool test_block_validity{true};
167 : : bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
168 : : };
169 : :
170 : : explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
171 : :
172 : : /** Construct a new block template with coinbase to scriptPubKeyIn */
173 : : std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
174 : :
175 : : inline static std::optional<int64_t> m_last_block_num_txs{};
176 : : inline static std::optional<int64_t> m_last_block_weight{};
177 : :
178 : : private:
179 : : const Options m_options;
180 : :
181 : : // utility functions
182 : : /** Clear the block's state and prepare for assembling a new block */
183 : : void resetBlock();
184 : : /** Add a tx to the block */
185 : : void AddToBlock(CTxMemPool::txiter iter);
186 : :
187 : : // Methods for how to add transactions to a block.
188 : : /** Add transactions based on feerate including unconfirmed ancestors
189 : : * Increments nPackagesSelected / nDescendantsUpdated with corresponding
190 : : * statistics from the package selection (for logging statistics).
191 : : *
192 : : * @pre BlockAssembler::m_mempool must not be nullptr
193 : : */
194 : : void addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(!m_mempool->cs);
195 : :
196 : : // helper functions for addPackageTxs()
197 : : /** Remove confirmed (inBlock) entries from given set */
198 : : void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
199 : : /** Test if a new package would "fit" in the block */
200 : : bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const;
201 : : /** Perform checks on each transaction in a package:
202 : : * locktime, premature-witness, serialized size (if necessary)
203 : : * These checks should always succeed, and they're here
204 : : * only as an extra check in case of suboptimal node configuration */
205 : : bool TestPackageTransactions(const CTxMemPool::setEntries& package) const;
206 : : /** Sort the package in an order that is valid to appear in a block */
207 : : void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
208 : : };
209 : :
210 : : int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
211 : :
212 : : /** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
213 : : void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
214 : :
215 : : /** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */
216 : : void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options);
217 : : } // namespace node
218 : :
219 : : #endif // BITCOIN_NODE_MINER_H
|