Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/node/miner.h
Line
Count
Source
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 <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 <memory>
17
#include <optional>
18
#include <stdint.h>
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()) {
  Branch (104:13): [True: 0, False: 0]
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