fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

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