Coverage Report

Created: 2025-03-18 19:34

/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