Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 3: [PATCH 03/17] feat(policy): preserve cluster accounting and repair dynamic dust

src/txmempool.h

Before: src/txmempool.h · After: src/txmempool.h

File metadata
index 94b0b35cd7ff7187d532fe3eeb1e0d694ac6a1aa..ead4886c63d2762add916e52a6e79aa8beea32eb 100644

Download original patch · Release notes

Diff rows 1–78 of 78. 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/txmempool.h CHANGED
@@ -189,6 +189,12 @@ protected:
189
189
  std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
190
190
 
191
191
  uint64_t totalTxSize GUARDED_BY(cs){0}; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
192
+ // An absolute-fee budget makes every native graph subset sum representable.
193
+ uint64_t m_modified_fee_usage GUARDED_BY(cs){0};
194
+ uint64_t m_staged_fee_usage GUARDED_BY(cs){0};
195
+ uint64_t m_policy_weight_usage GUARDED_BY(cs){0};
196
+ uint64_t m_staged_weight_usage GUARDED_BY(cs){0};
197
+ CFeeRate m_dust_relay_feerate GUARDED_BY(cs);
192
198
  CAmount m_total_fee GUARDED_BY(cs){0}; //!< sum of all mempool tx's fees (NOT modified fee)
193
199
  uint64_t cachedInnerUsage GUARDED_BY(cs){0}; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
194
200
 
@@ -285,7 +291,7 @@ private:
285
291
 
286
292
  static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
287
293
  {
288
- return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
294
+ return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), SaturatingAdd(it->GetModifiedFee(), -it->GetFee())};
289
295
  }
290
296
 
291
297
  // Helper to remove all transactions that conflict with a given
@@ -300,6 +306,13 @@ public:
300
306
 
301
307
  const Options m_opts;
302
308
 
309
+ CFeeRate GetDustRelayFee() const;
310
+ StandardnessOptions GetStandardnessOptions() const;
311
+ /** Select the actual-fee rate at a native graph-ordered policy-vsize position. */
312
+ std::optional<CFeeRate> EstimateDustFromMempool(int32_t target_kvb) const;
313
+ /** Publish a scaled estimate or the configured floor. Existing entry deficits are immutable. */
314
+ void UpdateDynamicDustFee(std::optional<CFeeRate> estimate);
315
+
303
316
  /** Create a new CTxMemPool.
304
317
  * Sanity checks will be off by default for performance, because otherwise
305
318
  * accepting transactions becomes O(N^2) where N is the number of transactions
@@ -342,7 +355,9 @@ public:
342
355
  bool HasNoInputsOf(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs);
343
356
 
344
357
  /** Affect CreateNewBlock prioritisation of transactions */
345
- void PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta);
358
+ bool PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta);
359
+ bool CanAddModifiedFee(CAmount fee) const EXCLUSIVE_LOCKS_REQUIRED(cs);
360
+ bool CanAddPolicyWeight(int64_t weight) const EXCLUSIVE_LOCKS_REQUIRED(cs);
346
361
  void ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs);
347
362
  void ClearPrioritisation(const Txid& hash) EXCLUSIVE_LOCKS_REQUIRED(cs);
348
363
 
@@ -623,6 +638,8 @@ public:
623
638
  if (m_pool->m_txgraph->HaveStaging()) {
624
639
  m_pool->m_txgraph->AbortStaging();
625
640
  }
641
+ m_pool->m_staged_fee_usage = 0;
642
+ m_pool->m_staged_weight_usage = 0;
626
643
  m_pool->m_have_changeset = false;
627
644
  }
628
645
 
@@ -631,7 +648,16 @@ public:
631
648
 
632
649
  using TxHandle = CTxMemPool::txiter;
633
650
 
634
- TxHandle StageAddition(const CTransactionRef& tx, CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp);
651
+ TxHandle StageAddition(const CTransactionRef& tx, CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp, int32_t extra_weight = 0, CAmount dust_penalty = 0, std::map<CScript, unsigned> script_claims = {});
652
+
653
+ bool HasStagedScriptConflict(const CScript& script, bool creating) const
654
+ {
655
+ for (const auto& entry : m_to_add) {
656
+ const auto claim = entry.m_script_claims.find(script);
657
+ if (claim != entry.m_script_claims.end() && (creating || (claim->second & 1))) return true;
658
+ }
659
+ return false;
660
+ }
635
661
 
636
662
  void StageRemoval(CTxMemPool::txiter it);
637
663
 
@@ -696,6 +722,10 @@ public:
696
722
  return std::make_unique<ChangeSet>(this);
697
723
  }
698
724
 
725
+ // Every creator/spender is retained across reorg exceptions, not just the last one.
726
+ std::map<CScript, std::pair<std::set<Txid>, std::set<Txid>>> m_used_scripts GUARDED_BY(cs);
727
+ std::set<Txid> GetScriptConflicts(const CScript& script, bool creating) const EXCLUSIVE_LOCKS_REQUIRED(cs);
728
+
699
729
  bool m_have_changeset GUARDED_BY(cs){false};
700
730
 
701
731
  friend class CTxMemPool::ChangeSet;