Bitcoin Core Fuzz Coverage Report

Coverage Report

Created: 2026-03-24 13:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/kernel/mempool_entry.h
Line
Count
Source
1
// Copyright (c) 2009-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#ifndef BITCOIN_KERNEL_MEMPOOL_ENTRY_H
6
#define BITCOIN_KERNEL_MEMPOOL_ENTRY_H
7
8
#include <consensus/amount.h>
9
#include <consensus/validation.h>
10
#include <core_memusage.h>
11
#include <policy/policy.h>
12
#include <policy/settings.h>
13
#include <primitives/transaction.h>
14
#include <txgraph.h>
15
#include <util/overflow.h>
16
17
#include <chrono>
18
#include <cstddef>
19
#include <cstdint>
20
#include <functional>
21
#include <memory>
22
#include <set>
23
24
class CBlockIndex;
25
26
struct LockPoints {
27
    // Will be set to the blockchain height and median time past
28
    // values that would be necessary to satisfy all relative locktime
29
    // constraints (BIP68) of this tx given our view of block chain history
30
    int height{0};
31
    int64_t time{0};
32
    // As long as the current chain descends from the highest height block
33
    // containing one of the inputs used in the calculation, then the cached
34
    // values are still valid even after a reorg.
35
    CBlockIndex* maxInputBlock{nullptr};
36
};
37
38
struct CompareIteratorByHash {
39
    // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T>
40
    // (e.g. a wrapped CTxMemPoolEntry&)
41
    template <typename T>
42
    bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const
43
0
    {
44
0
        return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
45
0
    }
46
    template <typename T>
47
    bool operator()(const T& a, const T& b) const
48
0
    {
49
0
        return a->GetTx().GetHash() < b->GetTx().GetHash();
50
0
    }
51
};
52
53
/** \class CTxMemPoolEntry
54
 *
55
 * CTxMemPoolEntry stores data about the corresponding transaction, as well
56
 * as data about all in-mempool transactions that depend on the transaction
57
 * ("descendant" transactions).
58
 *
59
 * When a new entry is added to the mempool, we update the descendant state
60
 * (m_count_with_descendants, nSizeWithDescendants, and nModFeesWithDescendants) for
61
 * all ancestors of the newly added transaction.
62
 *
63
 */
64
65
class CTxMemPoolEntry : public TxGraph::Ref
66
{
67
public:
68
    typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef;
69
70
private:
71
    CTxMemPoolEntry(const CTxMemPoolEntry&) = delete;
72
73
    const CTransactionRef tx;
74
    const CAmount nFee;             //!< Cached to avoid expensive parent-transaction lookups
75
    const int32_t nTxWeight;         //!< ... and avoid recomputing tx weight (also used for GetTxSize())
76
    const size_t nUsageSize;        //!< ... and total memory usage
77
    const int64_t nTime;            //!< Local time when entering the mempool
78
    const uint64_t entry_sequence;  //!< Sequence number used to determine whether this transaction is too recent for relay
79
    const unsigned int entryHeight; //!< Chain height when entering the mempool
80
    const bool spendsCoinbase;      //!< keep track of transactions that spend a coinbase
81
    const int64_t sigOpCost;        //!< Total sigop cost
82
    mutable CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
83
    mutable LockPoints lockPoints;  //!< Track the height and time at which tx was final
84
85
public:
86
0
    virtual ~CTxMemPoolEntry() = default;
87
    CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
88
                    int64_t time, unsigned int entry_height, uint64_t entry_sequence,
89
                    bool spends_coinbase,
90
                    int64_t sigops_cost, LockPoints lp)
91
0
        : tx{tx},
92
0
          nFee{fee},
93
0
          nTxWeight{GetTransactionWeight(*tx)},
94
0
          nUsageSize{RecursiveDynamicUsage(tx)},
95
0
          nTime{time},
96
0
          entry_sequence{entry_sequence},
97
0
          entryHeight{entry_height},
98
0
          spendsCoinbase{spends_coinbase},
99
0
          sigOpCost{sigops_cost},
100
0
          m_modified_fee{nFee},
101
0
          lockPoints{lp} {}
102
103
    CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
104
0
    CTxMemPoolEntry(CTxMemPoolEntry&&) = default;
105
    CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete;
106
107
0
    const CTransaction& GetTx() const { return *this->tx; }
108
0
    CTransactionRef GetSharedTx() const { return this->tx; }
109
0
    const CAmount& GetFee() const { return nFee; }
110
    int32_t GetTxSize() const
111
0
    {
112
0
        return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
113
0
    }
114
0
    int32_t GetAdjustedWeight() const { return GetSigOpsAdjustedWeight(nTxWeight, sigOpCost, ::nBytesPerSigOp); }
115
0
    int32_t GetTxWeight() const { return nTxWeight; }
116
0
    std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
117
0
    unsigned int GetHeight() const { return entryHeight; }
118
0
    uint64_t GetSequence() const { return entry_sequence; }
119
0
    int64_t GetSigOpCost() const { return sigOpCost; }
120
0
    CAmount GetModifiedFee() const { return m_modified_fee; }
121
0
    size_t DynamicMemoryUsage() const { return nUsageSize; }
122
0
    const LockPoints& GetLockPoints() const { return lockPoints; }
123
124
    // Updates the modified fees with descendants/ancestors.
125
    void UpdateModifiedFee(CAmount fee_diff) const
126
0
    {
127
0
        m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
128
0
    }
129
130
    // Update the LockPoints after a reorg
131
    void UpdateLockPoints(const LockPoints& lp) const
132
0
    {
133
0
        lockPoints = lp;
134
0
    }
135
136
0
    bool GetSpendsCoinbase() const { return spendsCoinbase; }
137
138
    mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
139
};
140
141
using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
142
143
struct TransactionInfo {
144
    const CTransactionRef m_tx;
145
    /* The fee the transaction paid */
146
    const CAmount m_fee;
147
    /**
148
     * The virtual transaction size.
149
     *
150
     * This is a policy field which considers the sigop cost of the
151
     * transaction as well as its weight, and reinterprets it as bytes.
152
     *
153
     * It is the primary metric by which the mining algorithm selects
154
     * transactions.
155
     */
156
    const int64_t m_virtual_transaction_size;
157
    /* The block height the transaction entered the mempool */
158
    const unsigned int txHeight;
159
160
    TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
161
0
        : m_tx{tx},
162
0
          m_fee{fee},
163
0
          m_virtual_transaction_size{vsize},
164
0
          txHeight{height} {}
165
};
166
167
struct RemovedMempoolTransactionInfo {
168
    TransactionInfo info;
169
    explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
170
0
        : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
171
};
172
173
struct NewMempoolTransactionInfo {
174
    TransactionInfo info;
175
    /*
176
     * This boolean indicates whether the transaction was added
177
     * without enforcing mempool fee limits.
178
     */
179
    const bool m_mempool_limit_bypassed;
180
    /* This boolean indicates whether the transaction is part of a package. */
181
    const bool m_submitted_in_package;
182
    /*
183
     * This boolean indicates whether the blockchain is up to date when the
184
     * transaction is added to the mempool.
185
     */
186
    const bool m_chainstate_is_current;
187
    /* Indicates whether the transaction has unconfirmed parents. */
188
    const bool m_has_no_mempool_parents;
189
190
    explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
191
                                       const int64_t vsize, const unsigned int height,
192
                                       const bool mempool_limit_bypassed, const bool submitted_in_package,
193
                                       const bool chainstate_is_current,
194
                                       const bool has_no_mempool_parents)
195
0
        : info{tx, fee, vsize, height},
196
0
          m_mempool_limit_bypassed{mempool_limit_bypassed},
197
0
          m_submitted_in_package{submitted_in_package},
198
0
          m_chainstate_is_current{chainstate_is_current},
199
0
          m_has_no_mempool_parents{has_no_mempool_parents} {}
200
};
201
202
#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H