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