/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 |