Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 3: [PATCH 03/68] feat(policy): preserve Roots relay and network controls on Core 30.3

src/kernel/mempool_entry.h

Before: src/kernel/mempool_entry.h · After: src/kernel/mempool_entry.h

File metadata
index 51a1f26642f48f18de71026ccd598b505a1b399e..ee0f360e3c183e5e58e9b143d7bcf25434f1aa00 100644

Download original patch · Release notes

Diff rows 1–166 of 166. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

src/kernel/mempool_entry.h CHANGED
@@ -8,12 +8,14 @@
8
8
  #include <consensus/amount.h>
9
9
  #include <consensus/validation.h>
10
10
  #include <core_memusage.h>
11
+ #include <policy/coin_age_priority.h>
11
12
  #include <policy/policy.h>
12
13
  #include <policy/settings.h>
13
14
  #include <primitives/transaction.h>
14
15
  #include <util/epochguard.h>
15
16
  #include <util/overflow.h>
16
17
 
18
+ #include <cassert>
17
19
  #include <chrono>
18
20
  #include <cstddef>
19
21
  #include <cstdint>
@@ -35,6 +37,15 @@ struct LockPoints {
35
37
  CBlockIndex* maxInputBlock{nullptr};
36
38
  };
37
39
 
40
+ enum MemPool_SPK_State {
41
+ MSS_UNSEEN = 0,
42
+ MSS_SPENT = 1, // .second
43
+ MSS_CREATED = 2, // .first
44
+ MSS_BOTH = 3,
45
+ };
46
+
47
+ typedef std::map<uint160, enum MemPool_SPK_State> SPKStates_t;
48
+
38
49
  struct CompareIteratorByHash {
39
50
  // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T>
40
51
  // (e.g. a wrapped CTxMemPoolEntry&)
@@ -84,9 +95,15 @@ private:
84
95
  const size_t nUsageSize; //!< ... and total memory usage
85
96
  const int64_t nTime; //!< Local time when entering the mempool
86
97
  const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
98
+ const int64_t sigOpCost; //!< Total sigop cost
99
+ const int32_t m_extra_weight; //!< Policy-only additional transaction weight beyond nTxWeight
100
+ const size_t nModSize; //!< Cached modified size for priority
101
+ const double entryPriority; //!< Priority when entering the mempool
87
102
  const unsigned int entryHeight; //!< Chain height when entering the mempool
103
+ double cachedPriority; //!< Last calculated priority
104
+ unsigned int cachedHeight; //!< Height at which priority was last calculated
105
+ CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain
88
106
  const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
89
- const int64_t sigOpCost; //!< Total sigop cost
90
107
  CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block
91
108
  mutable LockPoints lockPoints; //!< Track the height and time at which tx was final
92
109
 
@@ -108,7 +125,9 @@ private:
108
125
  public:
109
126
  CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
110
127
  int64_t time, unsigned int entry_height, uint64_t entry_sequence,
128
+ CoinAgeCache coin_age_cache,
111
129
  bool spends_coinbase,
130
+ int32_t extra_weight,
112
131
  int64_t sigops_cost, LockPoints lp)
113
132
  : tx{tx},
114
133
  nFee{fee},
@@ -116,16 +135,32 @@ public:
116
135
  nUsageSize{RecursiveDynamicUsage(tx)},
117
136
  nTime{time},
118
137
  entry_sequence{entry_sequence},
138
+ sigOpCost{sigops_cost},
139
+ m_extra_weight{extra_weight},
140
+ nModSize{CalculateModifiedSize(*tx, GetTxSize())},
141
+ entryPriority{ComputePriority2(coin_age_cache.inputs_coin_age, nModSize)},
119
142
  entryHeight{entry_height},
143
+ cachedPriority{entryPriority},
144
+ // Since entries arrive *after* the tip's height, their entry priority is for the height+1
145
+ cachedHeight{entry_height + 1},
146
+ inChainInputValue{coin_age_cache.in_chain_input_value},
120
147
  spendsCoinbase{spends_coinbase},
121
- sigOpCost{sigops_cost},
122
148
  m_modified_fee{nFee},
123
149
  lockPoints{lp},
124
150
  nSizeWithDescendants{GetTxSize()},
125
151
  nModFeesWithDescendants{nFee},
126
152
  nSizeWithAncestors{GetTxSize()},
127
153
  nModFeesWithAncestors{nFee},
128
- nSigOpCostWithAncestors{sigOpCost} {}
154
+ nSigOpCostWithAncestors{sigOpCost} {
155
+ CAmount nValueIn = tx->GetValueOut() + nFee;
156
+ assert(inChainInputValue <= nValueIn);
157
+ }
158
+
159
+ CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
160
+ int64_t time, unsigned int entry_height, uint64_t entry_sequence,
161
+ bool spends_coinbase, int64_t sigops_cost, LockPoints lp)
162
+ : CTxMemPoolEntry(tx, fee, time, entry_height, entry_sequence, COIN_AGE_CACHE_ZERO,
163
+ spends_coinbase, /*extra_weight=*/0, sigops_cost, lp) {}
129
164
 
130
165
  CTxMemPoolEntry(ExplicitCopyTag, const CTxMemPoolEntry& entry) : CTxMemPoolEntry(entry) {}
131
166
  CTxMemPoolEntry& operator=(const CTxMemPoolEntry&) = delete;
@@ -136,18 +171,36 @@ public:
136
171
 
137
172
  const CTransaction& GetTx() const { return *this->tx; }
138
173
  CTransactionRef GetSharedTx() const { return this->tx; }
174
+ double GetStartingPriority() const {return entryPriority; }
175
+ CoinAgeCache GetInternalCoinAgeCache() const {
176
+ return {
177
+ .inputs_coin_age = ReversePriority2(cachedPriority, nModSize),
178
+ .in_chain_input_value = inChainInputValue,
179
+ };
180
+ }
181
+ /**
182
+ * Fast calculation of priority as update from cached value, but only valid if
183
+ * currentHeight is greater than last height it was recalculated.
184
+ */
185
+ double GetPriority(unsigned int currentHeight) const;
186
+ /**
187
+ * Recalculate the cached priority as of currentHeight and adjust inChainInputValue by
188
+ * valueInCurrentBlock which represents input that was just added to or removed from the blockchain.
189
+ */
190
+ void UpdateCachedPriority(unsigned int currentHeight, CAmount valueInCurrentBlock);
139
191
  const CAmount& GetFee() const { return nFee; }
140
192
  int32_t GetTxSize() const
141
193
  {
142
- return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp);
194
+ return GetVirtualTransactionSize(nTxWeight + m_extra_weight, sigOpCost, ::nBytesPerSigOp);
143
195
  }
144
196
  int32_t GetTxWeight() const { return nTxWeight; }
145
197
  std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
146
198
  unsigned int GetHeight() const { return entryHeight; }
147
199
  uint64_t GetSequence() const { return entry_sequence; }
200
+ int32_t GetExtraWeight() const { return m_extra_weight; }
148
201
  int64_t GetSigOpCost() const { return sigOpCost; }
149
202
  CAmount GetModifiedFee() const { return m_modified_fee; }
150
- size_t DynamicMemoryUsage() const { return nUsageSize; }
203
+ size_t DynamicMemoryUsage() const { return nUsageSize + memusage::DynamicUsage(mapSPK); }
151
204
  const LockPoints& GetLockPoints() const { return lockPoints; }
152
205
 
153
206
  // Adjusts the descendant state.
@@ -186,6 +239,8 @@ public:
186
239
 
187
240
  mutable size_t idx_randomized; //!< Index in mempool's txns_randomized
188
241
  mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms
242
+
243
+ SPKStates_t mapSPK;
189
244
  };
190
245
 
191
246
  using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
@@ -226,7 +281,7 @@ struct NewMempoolTransactionInfo {
226
281
  * This boolean indicates whether the transaction was added
227
282
  * without enforcing mempool fee limits.
228
283
  */
229
- const bool m_mempool_limit_bypassed;
284
+ const ignore_rejects_type m_ignore_rejects;
230
285
  /* This boolean indicates whether the transaction is part of a package. */
231
286
  const bool m_submitted_in_package;
232
287
  /*
@@ -239,14 +294,22 @@ struct NewMempoolTransactionInfo {
239
294
 
240
295
  explicit NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
241
296
  const int64_t vsize, const unsigned int height,
242
- const bool mempool_limit_bypassed, const bool submitted_in_package,
297
+ const ignore_rejects_type& ignore_rejects, const bool submitted_in_package,
243
298
  const bool chainstate_is_current,
244
299
  const bool has_no_mempool_parents)
245
300
  : info{tx, fee, vsize, height},
246
- m_mempool_limit_bypassed{mempool_limit_bypassed},
301
+ m_ignore_rejects{ignore_rejects},
247
302
  m_submitted_in_package{submitted_in_package},
248
303
  m_chainstate_is_current{chainstate_is_current},
249
304
  m_has_no_mempool_parents{has_no_mempool_parents} {}
305
+
306
+ NewMempoolTransactionInfo(const CTransactionRef& tx, const CAmount& fee,
307
+ const int64_t vsize, const unsigned int height,
308
+ const bool mempool_limit_bypassed, const bool submitted_in_package,
309
+ const bool chainstate_is_current, const bool has_no_mempool_parents)
310
+ : NewMempoolTransactionInfo(tx, fee, vsize, height,
311
+ empty_ignore_rejects,
312
+ submitted_in_package, chainstate_is_current, has_no_mempool_parents) {}
250
313
  };
251
314
 
252
315
  #endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H