mempool_entry.h raw
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 #include <util/time.h>
17
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 {
44 return a.get().GetTx().GetHash() < b.get().GetTx().GetHash();
45 }
46 template <typename T>
47 bool operator()(const T& a, const T& b) const
48 {
49 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 : 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 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 : tx{tx},
92 nFee{fee},
93 nTxWeight{GetTransactionWeight(*tx)},
94 nUsageSize{RecursiveDynamicUsage(tx)},
95 nTime{time},
96 entry_sequence{entry_sequence},
97 entryHeight{entry_height},
98 spendsCoinbase{spends_coinbase},
99 sigOpCost{sigops_cost},
100 m_modified_fee{nFee},
101 lockPoints{lp} {}
102
103 CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
104 CTxMemPoolEntry(CTxMemPoolEntry&&) = default;
105 CTxMemPoolEntry& operator=(CTxMemPoolEntry&&) = delete;
106
107 const CTransaction& GetTx() const { return *this->tx; }
108 CTransactionRef GetSharedTx() const { return this->tx; }
109 const CAmount& GetFee() const { return nFee; }
110 int32_t GetTxSize() const
111 {
112 return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
113 }
114 int32_t GetAdjustedWeight() const { return GetSigOpsAdjustedWeight(nTxWeight, sigOpCost, ::nBytesPerSigOp); }
115 int32_t GetTxWeight() const { return nTxWeight; }
116 std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
117 unsigned int GetHeight() const { return entryHeight; }
118 uint64_t GetSequence() const { return entry_sequence; }
119 int64_t GetSigOpCost() const { return sigOpCost; }
120 CAmount GetModifiedFee() const { return m_modified_fee; }
121 size_t DynamicMemoryUsage() const { return nUsageSize; }
122 const LockPoints& GetLockPoints() const { return lockPoints; }
123
124 // Updates the modified fees with descendants/ancestors.
125 void UpdateModifiedFee(CAmount fee_diff) const
126 {
127 m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff);
128 }
129
130 // Update the LockPoints after a reorg
131 void UpdateLockPoints(const LockPoints& lp) const
132 {
133 lockPoints = lp;
134 }
135
136 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 : m_tx{tx},
162 m_fee{fee},
163 m_virtual_transaction_size{vsize},
164 txHeight{height} {}
165 };
166
167 struct RemovedMempoolTransactionInfo {
168 TransactionInfo info;
169 explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
170 : 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 : info{tx, fee, vsize, height},
196 m_mempool_limit_bypassed{mempool_limit_bypassed},
197 m_submitted_in_package{submitted_in_package},
198 m_chainstate_is_current{chainstate_is_current},
199 m_has_no_mempool_parents{has_no_mempool_parents} {}
200 };
201
202 #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
203