Cluster mempool followups #33591

pull sdaftuar wants to merge 95 commits into bitcoin:master from sdaftuar:2025-10-rebase-cluster-mempool changing 69 files +2565 −3623
  1. sdaftuar commented at 7:06 pm on October 9, 2025: member

    As suggested in the main cluster mempool PR (https://github.com/bitcoin/bitcoin/pull/28676#pullrequestreview-3177119367), I’ve pulled out some of the non-essential optimizations and cleanups into this separate PR.

    Will continue to add more commits here to address non-blocking suggestions/improvements as they come up.

  2. txgraph: Make level of Cluster implicit (optimization)
    This reduces per-Cluster memory usage by making Clusters not aware of their
    own level. Instead, track it either in calling code, or infer it based on
    the transactions in them.
    8f24464796
  3. txgraph: avoid holes in DepGraph positions (mem optimization) 845d360f7d
  4. depgraph: add memory usage control (feature) 2bab86b0e4
  5. txgraph: keep data structures compact (mem optimization) 84d2c40449
  6. txgraph: keep track of Cluster memory usage (preparation) 2d69f23f02
  7. txgraph: expose memory usage estimate function (feature) cd621cd9f8
  8. txgraph: make Cluster an abstract class (refactor) 22e4c132d2
  9. txgraph: add Cluster functions to avoid downcasts in Merge/Split (refactor)
    This adds 4 functions to Cluster to help implement Merge() and Split() without
    explicit downcasts using static_cast (removing the assumption that the Clusters
    being merged/split are also GenericClusterImpls).
    64039e2d89
  10. txgraph: abstract out creation of empty Clusters (refactor) ded568a08d
  11. txgraph: add SingletonClusterImpl (mem optimization)
    This adds a specialized Cluster implementation for singleton clusters, saving
    a significant amount of memory by avoiding the need for m_depgraph, m_mapping,
    and m_linearization, and their overheads.
    6bb7e1c630
  12. Allow moving an Epoch::Marker 53e09225ce
  13. mempool: Store iterators into mapTx in mapNextTx
    This takes the same amount of space as CTransaction pointers, and saves a map
    lookup in many common uses.
    f7393f9cf1
  14. Allow moving CTxMemPoolEntry objects, disallow copying f4ab3b49d6
  15. Make CTxMemPoolEntry derive from TxGraph::Ref ad4a382164
  16. Create a txgraph inside CTxMemPool 2626753d24
  17. Use named constant for acceptable iters 47d551ffe2
  18. Add sigops adjusted weight calculator df17ddd8bd
  19. Add accessor for sigops-adjusted weight c84b03b916
  20. Add transactions to txgraph, but without cluster dependencies
    Effectively this is treating all transactions in txgraph as being in a cluster
    of size 1.
    2052cfdca7
  21. Add new (unused) limits for cluster size/count a731896263
  22. test: update feature_rbf.py replacement test
    Preparatory commit to the rbf functional test, before changes are made to the
    rbf rules as part of cluster mempool.
    6bdafccdfb
  23. [test] rework/delete feature_rbf tests requiring large clusters cf48d1f533
  24. Do not allow mempool clusters to exceed configured limits
    Include an adjustment to mempool_tests.cpp due to the additional memory used by
    txgraph.
    
    Includes a temporary change to the mempool_ephemeral_dust.py functional test,
    due to validation checks being reordered. This change will revert once the RBF
    rules are changed in a later commit.
    ca06a2fb51
  25. Check cluster limits when using -walletrejectlongchains 1157153ce9
  26. Rework miner_tests to not require large cluster limit ec290751c8
  27. Limit mempool size based on chunk feerate
    Rather than evicting the transactions with the lowest descendant feerate,
    instead evict transactions that have the lowest chunk feerate.
    
    Once mining is implemented based on choosing transactions with highest chunk
    feerate (see next commit), mining and eviction will be opposites, so that we
    will evict the transactions that would be mined last.
    f7a96f0e6b
  28. bench: rewrite ComplexMemPool to not create oversized clusters aec794a592
  29. Select transactions for blocks based on chunk feerate 2f68c5cfee
  30. test: rewrite PopulateMempool to not violate mempool policy (cluster size) limits 61bcdb9770
  31. policy: Remove CPFP carveout rule
    The addition of a cluster size limit makes the CPFP carveout rule useless,
    because carveout cannot be used to bypass the cluster size limit. Remove this
    policy rule and update tests to no longer rely on the behavior.
    0b084b7fa5
  32. Implement new RBF logic for cluster mempool
    With a total ordering on mempool transactions, we are now able to calculate a
    transaction's mining score at all times. Use this to improve the RBF logic:
    
    - we no longer enforce a "no new unconfirmed parents" rule
    
    - we now require that the mempool's feerate diagram must improve in order
      to accept a replacement
    
    - the topology restrictions for conflicts in the package rbf setting have been
      eliminated
    
    Revert the temporary change to mempool_ephemeral_dust.py that were previously
    made due to RBF validation checks being reordered.
    
    Co-authored-by: Gregory Sanders <gsanders87@gmail.com>, glozow <gloriajzhao@gmail.com>
    d14e1674cf
  33. ==== END CLUSTER IMPLEMENTATION ==== d40248902c
  34. ==== BEGIN MEMPOOL CLEANUP ==== 1ddd372d81
  35. Remove the ancestor and descendant indices from the mempool f7851e44ec
  36. Use cluster linearization for transaction relay sort order
    Previously, transaction batches were first sorted by ancestor count and then
    feerate, to ensure transactions are announced in a topologically valid order,
    while prioritizing higher feerate transactions. Ancestor count is a crude
    topological sort criteria, so replace this with linearization order so that the
    highest feerate transactions (as would be observed by the mining algorithm) are
    relayed before lower feerate ones, in a topologically valid way.
    
    This also fixes a test that only worked due to the ancestor-count-based sort
    order.
    40d44c9606
  37. Remove CTxMemPool::GetSortedDepthAndScore
    The mempool clusters and linearization permit sorting the mempool topologically
    without making use of ancestor counts (as long as the graph is not oversized).
    
    Co-authored-by: Pieter Wuille <pieter@wuille.net>
    e00c93df3d
  38. Reimplement GetTransactionAncestry() to not rely on cached data
    In preparation for removing ancestor data from CTxMemPoolEntry, recalculate the
    ancestor statistics on demand wherever needed.
    b3d39f559a
  39. rpc: Calculate ancestor data from scratch for mempool rpc calls 9cda20ab11
  40. Remove dependency on cached ancestor data in mini-miner 5c9f53f9f0
  41. Stop enforcing ancestor size/count limits
    The cluster limits should be sufficient.
    
    Co-Authored-By: Gregory Sanders <gsanders87@gmail.com>
    599dd59247
  42. Add test case for cluster size limits to TRUC logic 12b323dffc
  43. Use mempool/txgraph to determine if a tx has descendants
    Remove a reference to GetCountWithDescendants() in preparation for removing
    this function and the associated cached state from the mempool.
    4aa2d48d7b
  44. Calculate descendant information for mempool RPC output on-the-fly
    This is in preparation for removing the cached descendant state from the
    mempool.
    254cf3e1d4
  45. test: remove rbf carveout test from mempool_limit.py 0a2057d4dd
  46. Stop enforcing descendant size/count limits
    Cluster size limits should be enough.
    7e247c8914
  47. Eliminate RBF workaround for CPFP carveout transactions
    The new cluster mempool RBF rules take into account clusters sizes exactly, so
    with the removal of descendant count enforcement this idea is obsolete.
    68fc65369a
  48. wallet: Replace max descendantsize with clustersize
    With the descendant size limits removed, replace the concept of "max number of
    descendants of any ancestor of a given tx" with the cluster count of the cluster
    that the transaction belongs to.
    18314e85b7
  49. mempool: Remove unused function CalculateDescendantMaximum 2831c354fc
  50. Eliminate use of cached ancestor data in miniminer_tests and truc_policy f44db4cf53
  51. mempool: eliminate accessors to mempool entry ancestor/descendant cached state a0e689025a
  52. Remove unused members from CTxMemPoolEntry bd6b9fb7a7
  53. Remove mempool logic designed to maintain ancestor/descendant state 7f990f59f5
  54. mempool: addUnchecked no longer needs ancestors 89ae9bc126
  55. Remove unused limits from CalculateMemPoolAncestors a1cabdd463
  56. Make removeConflicts private 2098d51e13
  57. ==== END MEMPOOL CLEANUP ==== 300d18919d
  58. ==== BEGIN OPTIMIZATIONS ==== 37e3b9f3fa
  59. Simplify ancestor calculation functions
    Now that ancestor calculation never fails (due to ancestor/descendant limits
    being eliminated), we can eliminate the error handling from
    CalculateMemPoolAncestors.
    d9a6f7c223
  60. Use txgraph to calculate ancestors 5dea10af99
  61. Use txgraph to calculate descendants 1c17630d2a
  62. Rework truc_policy to use descendants, not children b215f9c872
  63. Make getting parents/children a function of the mempool, not a mempool entry 66dd3857f6
  64. Eliminate CheckPackageLimits, which no longer does anything e77c975fcb
  65. Fix miniminer_tests to work with cluster limits 615834b8b1
  66. Rewrite GatherClusters to use the txgraph implementation d2bed27185
  67. Stop tracking parents/children outside of txgraph 922e379ccc
  68. ==== END OPTIMIZATIONS ==== aec47d483d
  69. ==== BEGIN DOCS/TESTING ==== 6351df153e
  70. Avoid violating mempool policy limits in tests
    Changes AddToMempool() helper to only apply changes if the mempool limits are
    respected.
    
    Fix package_rbf fuzz target to handle mempool policy violations
    06c83c9776
  71. bench: add more mempool benchmarks
    Add benchmarks for:
    
      - mempool update time when blocks are found
      - adding a transaction
      - performing the mempool's RBF calculation
      - calculating mempool ancestors/descendants
    3a6b676e4a
  72. fuzz: try to add more code coverage for mempool fuzzing
    Including test coverage for mempool eviction and expiry
    f256fbfd7e
  73. Expose cluster information via rpc
    Co-authored-by: glozow <gloriajzhao@gmail.com>
    63f60ec25b
  74. doc: Update mempool_replacements.md to reflect feerate diagram checks f894859933
  75. test: add functional test for new cluster mempool RPCs 09defe5de0
  76. fuzz: remove comparison between mini_miner block construction and miner
    This is in preparation for eliminating the block template building happening in
    mini_miner, in favor of directly using the linearizations done in the mempool.
    775624928f
  77. Invoke TxGraph::DoWork() at appropriate times ba45cbd05c
  78. Update comments for CTxMemPool class a27aa1ecbb
  79. Add check that GetSortedScoreWithTopology() agrees with CompareMiningScoreWithTopology()
    We use CompareMiningScoreWithTopology() for sorting transaction announcements
    during tx relay, and we use GetSortedScoreWithTopology() in
    CTxMemPool::check().
    368c036259
  80. Rework RBF and TRUC validation
    Calculating mempool ancestors for a new transaction should not be done until
    after cluster size limits have been enforced, to limit CPU DoS potential.
    
    Achieve this by reworking TRUC and RBF validation logic:
    
    - TRUC policy enforcement is now done using only mempool parents of
      new transactions, not all mempool ancestors.
    - RBF replacement checks are performed earlier (which allows for checking
      cluster size limits earlier, because cluster size checks cannot happen until
      after all conflicts are staged for removal).
    - Verifying that a new transaction doesn't conflict with an ancestor now
      happens later, in AcceptSingleTransaction() rather than in PreChecks(). This
      means that the test is not performed at all in AcceptMultipleTransactions(),
      but in package acceptance we already disallow RBF in situations where a
      package transaction has in-mempool parents.
    
    Also to ensure that all RBF validation logic is applied in both the single
    transaction and multiple transaction cases, remove the optimization that skips
    the PackageMempoolChecks() in the case of a single transaction being validated
    in AcceptMultipleTransactions().
    989827e56e
  81. ==== FOLLOWUPS ==== cfd472a8b7
  82. Remove unused variable (cacheMap) in mempool 59f3af647b
  83. Remove unused argument to RemoveStaged 60c58f15a2
  84. Simplify removeRecursive 0d777c1a95
  85. scripted-diff: rename AddToMempool -> TryAddToMempool
    -BEGIN VERIFY SCRIPT-
    find src/test -type f -exec sed -i 's/AddToMempool/TryAddToMempool/g' {} +
    find src/bench -type f -exec sed -i 's/AddToMempool/TryAddToMempool/g' {} +
    -END VERIFY SCRIPT-
    4993b93e29
  86. Rewrite removeForReorg to avoid using sets ee0c5cace3
  87. Rewrite GetChildren without sets 6d560148ad
  88. Invoke removeUnchecked() directly in removeForBlock() d6e76b48fa
  89. DrahtBot commented at 7:06 pm on October 9, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33591.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33421 (node: add BlockTemplateCache by ismaelsadeeq)
    • #33335 (txgraph: randomize order of same-feerate distinct-cluster transactions by sipa)
    • #33214 (rpc: require integer verbosity; remove boolean ‘verbose’ by fqlx)
    • #33192 (refactor: unify container presence checks by l0rinc)
    • #33191 (net: Provide block templates to peers on request by ajtowns)
    • #33157 (cluster mempool: control/optimize TxGraph memory usage by sipa)
    • #33062 (truc: optimize the in package relation calculation by HowHsu)
    • #32587 (test: Fix reorg patterns in tests to use proper fork-based approach by yuvicc)
    • #31974 (Drop testnet3 by Sjors)
    • #31803 (fuzz: Extend mini_miner fuzz coverage to max block weight by fjahr)
    • #31682 ([IBD] specialize CheckBlock’s input & coinbase checks by l0rinc)
    • #31382 (kernel: Flush in ChainstateManager destructor by TheCharlatan)
    • #30277 ([DO NOT MERGE] Erlay: bandwidth-efficient transaction relay protocol (Full implementation) by sr-gi)
    • #29641 (scripted-diff: Use LogInfo over LogPrintf [WIP, NOMERGE, DRAFT] by maflcko)
    • #28690 (build: Introduce internal kernel library by TheCharlatan)
    • #17783 (common: Disallow calling IsArgSet() on ALLOW_LIST options by ryanofsky)
    • #17581 (refactor: Remove settings merge reverse precedence code by ryanofsky)
    • #17580 (refactor: Add ALLOW_LIST flags and enforce usage in CheckArgFlags by ryanofsky)
    • #17493 (util: Forbid ambiguous multiple assignments in config file by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  90. glozow added the label Mempool on Oct 9, 2025
  91. Warn user if using -limitancestorsize/-limitdescendantsize that the options have no effect 325b539157
  92. Use cluster limit rather than descendant limit to sanity check mempool max size 51915db802
  93. Remove ancestor and descendant vsize limits from MemPoolLimits 5229a14a20
  94. Use cluster limits instead of ancestor/descendant limits when sanity checking package policy limits 573343ab5b
  95. Use cluster size limit instead of ancestor/descendant size limits when sanity checking TRUC policy limits 585a7c16bb
  96. Use cluster size limit instead of ancestor size limit in txpackage unit test 56d98f9ec3
  97. Remove unused DEFAULT_ANCESTOR_SIZE_LIMIT_KVB and DEFAULT_DESCENDANT_SIZE_LIMIT_KVB 6829ef27d7
  98. Add a GetFeePerVSize() accessor to CFeeRate, and use it in the BlockAssembler 554d8d406d

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-10-10 15:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me