Branch data Line data Source code
1 : : // Copyright (c) 2009-2022 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 <util/epochguard.h>
15 : : #include <util/overflow.h>
16 : :
17 : : #include <chrono>
18 : : #include <functional>
19 : : #include <memory>
20 : : #include <set>
21 : : #include <stddef.h>
22 : : #include <stdint.h>
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 : 7711121 : bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const
43 : : {
44 : 7711121 : return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
45 : : }
46 : : template <typename T>
47 : 58375108 : bool operator()(const T& a, const T& b) const
48 : : {
49 : 58375108 : return a->GetTx().GetHash() < b->GetTx().GetHash();
50 : : }
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
66 : : {
67 : : public:
68 : : typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef;
69 : : // two aliases, should the types ever diverge
70 : : typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Parents;
71 : : typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Children;
72 : :
73 : : private:
74 [ + - + - : 98836 : CTxMemPoolEntry(const CTxMemPoolEntry&) = default;
+ - - - ]
75 : : struct ExplicitCopyTag {
76 : : explicit ExplicitCopyTag() = default;
77 : : };
78 : :
79 : : const CTransactionRef tx;
80 : : mutable Parents m_parents;
81 : : mutable Children m_children;
82 : : const CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups
83 : : const int32_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize())
84 : : const size_t nUsageSize; //!< ... and total memory usage
85 : : const int64_t nTime; //!< Local time when entering the mempool
86 : : const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
87 : : const unsigned int entryHeight; //!< Chain height when entering the mempool
88 : : const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
89 : : const int64_t sigOpCost; //!< Total sigop cost
90 : : CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
91 : : mutable LockPoints lockPoints; //!< Track the height and time at which tx was final
92 : :
93 : : // Information about descendants of this transaction that are in the
94 : : // mempool; if we remove this transaction we must remove all of these
95 : : // descendants as well.
96 : : int64_t m_count_with_descendants{1}; //!< number of descendant transactions
97 : : // Using int64_t instead of int32_t to avoid signed integer overflow issues.
98 : : int64_t nSizeWithDescendants; //!< ... and size
99 : : CAmount nModFeesWithDescendants; //!< ... and total fees (all including us)
100 : :
101 : : // Analogous statistics for ancestor transactions
102 : : int64_t m_count_with_ancestors{1};
103 : : // Using int64_t instead of int32_t to avoid signed integer overflow issues.
104 : : int64_t nSizeWithAncestors;
105 : : CAmount nModFeesWithAncestors;
106 : : int64_t nSigOpCostWithAncestors;
107 : :
108 : : public:
109 : 60255 : CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
110 : : int64_t time, unsigned int entry_height, uint64_t entry_sequence,
111 : : bool spends_coinbase,
112 : : int64_t sigops_cost, LockPoints lp)
113 [ + - - - ]: 60255 : : tx{tx},
114 : 60255 : nFee{fee},
115 : 60255 : nTxWeight{GetTransactionWeight(*tx)},
116 : 60255 : nUsageSize{RecursiveDynamicUsage(tx)},
117 : 60255 : nTime{time},
118 : 60255 : entry_sequence{entry_sequence},
119 : 60255 : entryHeight{entry_height},
120 : 60255 : spendsCoinbase{spends_coinbase},
121 : 60255 : sigOpCost{sigops_cost},
122 : 60255 : m_modified_fee{nFee},
123 : 60255 : lockPoints{lp},
124 : 120510 : nSizeWithDescendants{GetTxSize()},
125 : 60255 : nModFeesWithDescendants{nFee},
126 : 120510 : nSizeWithAncestors{GetTxSize()},
127 : 60255 : nModFeesWithAncestors{nFee},
128 [ + - + - ]: 120510 : nSigOpCostWithAncestors{sigOpCost} {}
129 : :
130 [ + - ]: 49418 : CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
131 : : CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
132 : : CTxMemPoolEntry(CTxMemPoolEntry&&) = delete;
133 : : CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete;
134 : :
135 : : static constexpr ExplicitCopyTag ExplicitCopy{};
136 : :
137 [ + + + + : 107741584 : const CTransaction& GetTx() const { return *this->tx; }
+ + ]
[ + + + + ]
[ - - - -
+ - + - ]
[ - - - -
+ - + - +
- ][ - - -
- + - + -
+ - + - +
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ][ + -
+ - - + +
- - + + -
+ + + + -
- - - + -
+ - + - +
+ - + + +
+ - + - -
- - - ]
138 [ + - + - : 789452 : CTransactionRef GetSharedTx() const { return this->tx; }
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
[ + - + - ]
[ + - + -
+ - + - +
- + - + -
- - - - +
- + - + -
+ - + - +
- ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - +
- ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ #
# # # # #
# # ]
139 [ + - ][ + - : 56184 : const CAmount& GetFee() const { return nFee; }
+ - + - +
- + - + -
+ - + - ]
140 : 263274552 : int32_t GetTxSize() const
141 : : {
142 : 263274552 : return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
143 : : }
144 [ + - ]: 14885 : int32_t GetTxWeight() const { return nTxWeight; }
145 [ + + + - ]: 16460289 : std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
146 [ + - ]: 47515 : unsigned int GetHeight() const { return entryHeight; }
147 [ + + ]: 11535 : uint64_t GetSequence() const { return entry_sequence; }
148 [ + - ]: 8473126 : int64_t GetSigOpCost() const { return sigOpCost; }
149 [ + - ][ + - : 55414568 : CAmount GetModifiedFee() const { return m_modified_fee; }
+ - + - ]
[ + - + -
# # # # #
# # # # #
# # ][ + -
+ - + - +
- + - + -
+ - + - ]
150 : 6905533 : size_t DynamicMemoryUsage() const { return nUsageSize; }
151 [ + - ]: 1752 : const LockPoints& GetLockPoints() const { return lockPoints; }
152 : :
153 : : // Adjusts the descendant state.
154 : : void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount);
155 : : // Adjusts the ancestor state
156 : : void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps);
157 : : // Updates the modified fees with descendants/ancestors.
158 : 283 : void UpdateModifiedFee(CAmount fee_diff)
159 : : {
160 : 283 : nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff);
161 : 283 : nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff);
162 : 283 : m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
163 : 283 : }
164 : :
165 : : // Update the LockPoints after a reorg
166 : 163 : void UpdateLockPoints(const LockPoints& lp) const
167 : : {
168 : 163 : lockPoints = lp;
169 : : }
170 : :
171 [ + + ][ + + : 1681835 : uint64_t GetCountWithDescendants() const { return m_count_with_descendants; }
+ - + + +
+ + + ]
172 [ + - + + ]: 42006619 : int64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
[ # # ]
173 [ + - ]: 33566387 : CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
174 : :
175 [ + + ]: 876 : bool GetSpendsCoinbase() const { return spendsCoinbase; }
176 : :
177 [ + + ][ + + : 83094904 : uint64_t GetCountWithAncestors() const { return m_count_with_ancestors; }
+ - + + +
+ + + + +
- + + - ]
[ # # # #
# # ]
178 [ + - + + : 6934100 : int64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
+ - ]
[ - + - + ]
[ # # ]
179 [ + - ][ + - : 12366490 : CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
+ + + - ]
[ + + - + ]
180 [ + - + + : 6847260 : int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
+ - ][ - + ]
181 : :
182 [ + + + + : 15454260 : const Parents& GetMemPoolParentsConst() const { return m_parents; }
+ + - + ]
[ # # ]
183 [ + + ]: 14902295 : const Children& GetMemPoolChildrenConst() const { return m_children; }
[ + + - + ]
184 [ + - ]: 11505 : Parents& GetMemPoolParents() const { return m_parents; }
185 [ + - ]: 11505 : Children& GetMemPoolChildren() const { return m_children; }
186 : :
187 : : mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
188 : : mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
189 : : };
190 : :
191 : : using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
192 : :
193 : 702396 : struct TransactionInfo {
194 : : const CTransactionRef m_tx;
195 : : /* The fee the transaction paid */
196 : : const CAmount m_fee;
197 : : /**
198 : : * The virtual transaction size.
199 : : *
200 : : * This is a policy field which considers the sigop cost of the
201 : : * transaction as well as its weight, and reinterprets it as bytes.
202 : : *
203 : : * It is the primary metric by which the mining algorithm selects
204 : : * transactions.
205 : : */
206 : : const int64_t m_virtual_transaction_size;
207 : : /* The block height the transaction entered the mempool */
208 : : const unsigned int txHeight;
209 : :
210 : 89495 : TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
211 : 178990 : : m_tx{tx},
212 : 89495 : m_fee{fee},
213 : 89495 : m_virtual_transaction_size{vsize},
214 : 89495 : txHeight{height} {}
215 : : };
216 : :
217 [ - - # # ]: 731884 : struct RemovedMempoolTransactionInfo {
[ - - + - ]
218 : : TransactionInfo info;
219 : 43052 : explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
220 [ + - + - : 172208 : : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
+ - + - ]
221 : : };
222 : :
223 [ + - - - : 185772 : struct NewMempoolTransactionInfo {
# # # # ]
[ + - - -
+ - - - ]
[ + - + -
+ - + - +
- + - - -
- - - - ]
224 : : TransactionInfo info;
225 : : /*
226 : : * This boolean indicates whether the transaction was added
227 : : * without enforcing mempool fee limits.
228 : : */
229 : : const bool m_mempool_limit_bypassed;
230 : : /* This boolean indicates whether the transaction is part of a package. */
231 : : const bool m_submitted_in_package;
232 : : /*
233 : : * This boolean indicates whether the blockchain is up to date when the
234 : : * transaction is added to the mempool.
235 : : */
236 : : const bool m_chainstate_is_current;
237 : : /* Indicates whether the transaction has unconfirmed parents. */
238 : : const bool m_has_no_mempool_parents;
239 : :
240 : 46443 : explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
241 : : const int64_t vsize, const unsigned int height,
242 : : const bool mempool_limit_bypassed, const bool submitted_in_package,
243 : : const bool chainstate_is_current,
244 : : const bool has_no_mempool_parents)
245 [ + - + - ]: 46443 : : info{tx, fee, vsize, height},
[ + - + -
+ - ]
246 : 46443 : m_mempool_limit_bypassed{mempool_limit_bypassed},
247 : 46443 : m_submitted_in_package{submitted_in_package},
248 : 46443 : m_chainstate_is_current{chainstate_is_current},
249 [ + - + - ]: 46443 : m_has_no_mempool_parents{has_no_mempool_parents} {}
[ + - + -
+ - ]
250 : : };
251 : :
252 : : #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
|