Commit Graph
100 Commits
Author SHA1 Message Date
Suhas Daftuar 72f60c877e doc: Update mempool_replacements.md to reflect feerate diagram checks 2025-11-18 11:14:52 -05:00
Suhas Daftuarandglozow 21693f031a Expose cluster information via rpc
Co-authored-by: glozow <gloriajzhao@gmail.com>
2025-11-18 11:14:52 -05:00
Suhas Daftuar f107417490 bench: add more mempool benchmarks
Add benchmarks for:

  - adding a transaction
  - calculating mempool ancestors/descendants
2025-11-18 10:48:23 -05:00
Suhas Daftuar 7976eb1ae7 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
2025-11-18 10:48:23 -05:00
Suhas Daftuar 1ca4f01090 Fix miniminer_tests to work with cluster limits 2025-11-18 10:48:23 -05:00
Suhas Daftuar 1902111e0f Eliminate CheckPackageLimits, which no longer does anything 2025-11-18 10:48:23 -05:00
Suhas Daftuar 3a646ec462 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 (note that it's fine to calculate
  ancestors of in-mempool transactions, if the number of such calls is
  reasonably bounded).
- 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().
2025-11-18 10:48:22 -05:00
Suhas Daftuar 5560913e51 Rework truc_policy to use descendants, not children 2025-11-18 10:35:19 -05:00
Suhas Daftuar 241a3e666b 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.
2025-11-18 09:29:36 -05:00
Suhas Daftuar b9cec7f0a1 Make removeConflicts private 2025-11-18 09:29:36 -05:00
Suhas Daftuar 0402e6c780 Remove unused limits from CalculateMemPoolAncestors 2025-11-18 09:29:35 -05:00
Suhas Daftuar 08be765ac2 Remove mempool logic designed to maintain ancestor/descendant state 2025-11-18 09:28:31 -05:00
Suhas Daftuar fc4e3e6bc1 Remove unused members from CTxMemPoolEntry 2025-11-18 09:28:31 -05:00
Suhas Daftuar ff3b398d12 mempool: eliminate accessors to mempool entry ancestor/descendant cached state 2025-11-18 09:28:31 -05:00
Suhas Daftuar ba09fc9774 mempool: Remove unused function CalculateDescendantMaximum 2025-11-18 09:02:48 -05:00
Suhas Daftuar 8e49477e86 wallet: Replace max descendant count with cluster_count
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.
2025-11-18 09:02:48 -05:00
Suhas Daftuar e031085fd4 Eliminate Single-Conflict RBF Carve Out
The new cluster mempool RBF rules take into account clusters sizes exactly, so
with the removal of descendant count enforcement this idea is obsolete.
2025-11-18 09:02:05 -05:00
Suhas Daftuar cf3ab8e1d0 Stop enforcing descendant size/count limits
Cluster size limits should be enough.
2025-11-18 08:57:51 -05:00
Suhas Daftuar 89ae38f489 test: remove rbf carveout test from mempool_limit.py 2025-11-18 08:57:51 -05:00
Suhas Daftuar c0bd04d18f Calculate descendant information for mempool RPC output on-the-fly
This is in preparation for removing the cached descendant state from the
mempool.
2025-11-18 08:57:51 -05:00
Suhas Daftuar bdcefb8a8b 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.
2025-11-18 08:57:51 -05:00
Suhas DaftuarandGregory Sanders 9cda64b86c Stop enforcing ancestor size/count limits
The cluster limits should be sufficient.

Co-Authored-By: Gregory Sanders <gsanders87@gmail.com>
2025-11-18 08:57:51 -05:00
Suhas Daftuar 1f93227a84 Remove dependency on cached ancestor data in mini-miner 2025-11-18 08:57:51 -05:00
Suhas Daftuar 9fbe0a4ac2 rpc: Calculate ancestor data from scratch for mempool rpc calls 2025-11-18 08:57:51 -05:00
Suhas Daftuar 7961496dda Reimplement GetTransactionAncestry() to not rely on cached data
In preparation for removing ancestor data from CTxMemPoolEntry, recalculate the
ancestor statistics on demand wherever needed.
2025-11-18 08:57:51 -05:00
Suhas DaftuarandPieter Wuille feceaa42e8 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>
2025-11-18 08:53:59 -05:00
Suhas Daftuar 21b5cea588 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.
2025-11-18 08:53:59 -05:00
Suhas Daftuar 6445aa7d97 Remove the ancestor and descendant indices from the mempool 2025-11-18 08:53:59 -05:00
Suhas DaftuarandGregory Sanders <gsanders87@gmail.com>, glozow 216e693729 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>
2025-11-18 08:53:59 -05:00
Suhas Daftuar ff8f115dec 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.
2025-11-18 08:53:59 -05:00
Suhas Daftuar c3f1afc934 test: rewrite PopulateMempool to not violate mempool policy (cluster size) limits 2025-11-18 08:53:59 -05:00
Suhas DaftuarandGregory Sanders 47ab32fdb1 Select transactions for blocks based on chunk feerate
Co-Authored-By: Gregory Sanders <gsanders87@gmail.com>
2025-11-18 08:53:58 -05:00
Suhas Daftuar dec138d1dd fuzz: remove comparison between mini_miner block construction and miner
After cluster mempool, the mini_miner will no longer match the miner's block
construction. Eventually mini_miner should be reworked to directly use
linearizations done in the mempool.
2025-11-18 08:53:58 -05:00
Suhas Daftuar 6c2bceb200 bench: rewrite ComplexMemPool to not create oversized clusters 2025-11-18 08:53:58 -05:00
Suhas Daftuar 1ad4590f63 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.
2025-11-18 08:53:58 -05:00
Suhas Daftuar b11c89cab2 Rework miner_tests to not require large cluster limit 2025-11-18 08:53:58 -05:00
Suhas Daftuar 95a8297d48 Check cluster limits when using -walletrejectlongchains 2025-11-18 08:53:58 -05:00
Suhas Daftuar 95762e6759 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.
2025-11-18 08:53:58 -05:00
Suhas Daftuar 435fd56711 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.
2025-11-18 08:53:58 -05:00
Suhas Daftuar 34e32985e8 Add new (unused) limits for cluster size/count 2025-11-18 08:53:58 -05:00
Suhas Daftuar 838d7e3553 Add transactions to txgraph, but without cluster dependencies
Effectively this is treating all transactions in txgraph as being in a cluster
of size 1.
2025-11-18 08:53:58 -05:00
Suhas Daftuar d5ed9cb3eb Add accessor for sigops-adjusted weight 2025-11-10 16:01:34 -05:00
Suhas Daftuar 1bf3b51396 Add sigops adjusted weight calculator 2025-11-10 15:55:43 -05:00
Suhas Daftuar c18c68a950 Create a txgraph inside CTxMemPool 2025-11-10 15:54:53 -05:00
Suhas Daftuar 29a94d5b2f Make CTxMemPoolEntry derive from TxGraph::Ref 2025-11-10 15:46:11 -05:00
Suhas Daftuar 92b0079fe3 Allow moving CTxMemPoolEntry objects, disallow copying 2025-11-10 15:45:55 -05:00
Suhas Daftuar 6c73e47448 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.
2025-10-14 14:03:42 -04:00
Suhas Daftuar 51430680ec Allow moving an Epoch::Marker 2025-10-14 14:03:42 -04:00
Suhas Daftuar a4ec07f194 doc: add comments for CTxMemPool::ChangeSet 2024-11-13 13:27:01 -05:00
Suhas Daftuar 83f814b1d1 Remove m_all_conflicts from SubPackageState 2024-11-13 13:27:01 -05:00
Suhas Daftuar d3c8e7dfb6 Ensure that we don't add duplicate transactions in rbf fuzz tests 2024-11-13 13:27:01 -05:00
Suhas Daftuar d7dc9fd2f7 Move CalculateChunksForRBF() to the mempool changeset 2024-11-13 13:27:01 -05:00
Suhas Daftuar 284a1d33f1 Move prioritisation into changeset 2024-11-13 13:27:01 -05:00
Suhas Daftuar 446b08b599 Don't distinguish between direct conflicts and all conflicts when doing cluster-size-2-rbf checks 2024-11-13 13:27:01 -05:00
Suhas Daftuar b53041021a Duplicate transactions are not permitted within a changeset 2024-11-13 13:27:01 -05:00
Suhas Daftuar 2b30f4d36c Make RemoveStaged() private 2024-11-13 13:27:01 -05:00
Suhas Daftuar 18829194ca Enforce that there is only one changeset at a time 2024-11-13 13:27:01 -05:00
Suhas Daftuar 7fb62f7db6 Apply mempool changeset transactions directly into the mempool
Rather than individually calling addUnchecked for each transaction added in a
changeset (after removing all the to-be-removed transactions), instead we can
take advantage of boost::multi_index's splicing features to extract and insert
entries directly from the staging multi_index into mapTx.

This has the immediate advantage of saving allocation overhead for mempool
entries which have already been allocated once. This also means that the memory
locations of mempool entries will not change when transactions go from staging
to the main mempool.

Additionally, eliminate addUnchecked and require all new transactions to enter
the mempool via a CTxMemPoolChangeSet.
2024-11-13 13:26:56 -05:00
Suhas Daftuar 34b6c5833d Clean up FinalizeSubpackage to avoid workspace-specific information
Also, use the "package hash" for logging replacements in the package rbf
setting.
2024-11-13 13:19:58 -05:00
Suhas Daftuar 57983b8add Move LimitMempoolSize to take place outside FinalizeSubpackage 2024-11-13 13:17:28 -05:00
Suhas Daftuar 01e145b975 Move changeset from workspace to subpackage
Removes a redundant check that mempool limits will not be violated during
package acceptance.
2024-11-13 13:17:27 -05:00
Suhas Daftuar 802214c083 Introduce mempool changesets
Introduce the CTxMemPool::ChangeSet, a wrapper for creating (potential) new
mempool entries and removing conflicts.
2024-11-13 13:15:12 -05:00
Suhas Daftuar 87d92fa340 test: Add unit test coverage of package rbf + prioritisetransaction 2024-11-13 13:10:57 -05:00
Suhas Daftuar 15d982f91e Add package hash to package-rbf log message 2024-11-13 13:10:57 -05:00
Suhas Daftuar f8a141c2da test: Don't rely on incentive incompatible replacement in mempool_accept_v3.py 2024-04-29 12:15:30 -04:00
Suhas Daftuar cc15c5bfd1 fuzz: don't allow adding duplicate transactions to the mempool 2024-04-28 15:39:10 -04:00
b73d3bbd23 net_processing: Request assumeutxo background chain blocks
Add new PeerManagerImpl::TryDownloadingHistoricalBlocks method and use it to
request background chain blocks in addition to blocks normally requested by
FindNextBlocksToDownload.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Co-authored-by: James O'Beirne <james.obeirne@gmail.com>
2023-09-30 05:45:37 -04:00
Suhas Daftuar a733dd79e2 Remove unused function reliesOnAssumedValid 2023-07-24 16:27:04 -04:00
Suhas Daftuar d4a11abb19 Cache block index entry corresponding to assumeutxo snapshot base blockhash
This is to (a) avoid repeated lookups into the block index for an entry that
should never change and (b) emphasize that the snapshot base should always
exist when set and not change during the runtime of the program.

Thanks to Russ Yanofsky for suggesting this approach.
2023-07-24 16:23:38 -04:00
Suhas Daftuar 3556b85022 Move CheckBlockIndex() from Chainstate to ChainstateManager
Also rewrite CheckBlockIndex() to perform tests on all chainstates.

This increases sanity-check coverage, as any place in our code where we were
invoke CheckBlockIndex() on a single chainstate will now invoke the sanity
checks on all chainstates.

This change also tightens up the checks on setBlockIndexCandidates and
mapBlocksUnlinked, to more precisely match what we aim for even in the presence
of assumed-valid blocks.
2023-07-24 16:23:38 -04:00
Suhas Daftuar 768690b7ce Fix initialization of setBlockIndexCandidates when working with multiple chainstates
When using assumeutxo and multiple chainstates are active, the background
chainstate should consider all HAVE_DATA blocks that are ancestors of the
snapshotted block and that have more work than the tip as potential candidates.
2023-07-24 16:23:38 -04:00
Suhas Daftuar d43a1f1a2f Tighten requirements for adding elements to setBlockIndexCandidates
When using assumeutxo, we only need the background chainstate to consider
blocks that are on the chain leading to the snapshotted block.

Note that this introduces the new invariant that we can only have an assumeutxo
snapshot where the snapshotted blockhash is in our block index. Unknown block
hashes that are somehow passed in will cause assertion failures when processing
new blocks.

Includes test fixes and improvements by Andrew Chow and Fabian Jahr.
2023-07-24 16:23:38 -04:00
Suhas Daftuar d0d40ea9a6 Move block-storage-related logic to ChainstateManager
Separate the notion of which blocks are stored on disk, and what data is in our
block index, from what tip a chainstate might be able to get to. We can use
chainstate-agnostic data to determine when to store a block on disk (primarily,
an anti-DoS set of criteria) and let the chainstates figure out for themselves
when a block is of interest for being a candidate tip.

Note: some of the invariants in CheckBlockIndex are modified, but more work is
needed (ie to move CheckBlockIndex to ChainstateManager, as most of what
CheckBlockIndex is doing is checking the consistency of the block index, which
is outside of Chainstate).
2023-07-21 10:09:44 -04:00
Suhas Daftuar 3cfc75366e test: Clear block index flags when testing snapshots
When simulating a snapshot, remove the HAVE_DATA status for blocks below the
snapshot height, to simulate never having downloaded them at all. This makes
tests more realistic (and more closely match what will happen when using
assumeutxo).
2023-07-14 17:10:49 -04:00
Suhas Daftuar 272fbc370c Update CheckBlockIndex invariants for chains based on an assumeutxo snapshot 2023-07-14 17:09:06 -04:00
Suhas Daftuar 10c05710ce Add wrapper for adding entries to a chainstate's block index candidates 2023-07-14 17:09:06 -04:00
Suhas Daftuar 471da5f6e7 Move block-arrival information / preciousblock counters to ChainstateManager
Block arrival information (and the preciousblock RPC, a related concept) are
both chainstate-agnostic, so these are moved to ChainstateManager. This should
just be a refactor, without any observable behavior changes.
2023-07-14 17:09:06 -04:00
Suhas Daftuar 1cfc887d00 Remove CChain dependency in node/blockstorage 2023-07-14 14:54:57 -04:00
Suhas Daftuar fe86a7cd48 Explicitly track maximum block height stored in undo files
When writing a new block to disk, if we have filled up the current block file,
then we flush and truncate that block file (to free allocated but unused
space) before advancing to the next one. When this happens, we have to
determine whether to also flush and truncate the corresponding undo file.

Undo data is only written when blocks are connected, not when blocks are
received. Thus it's possible that the corresponding undo file already has all
the data it will ever have, and we should flush/truncate it as we advance
files; or it's possible that there is more data we expect to write, and should
therefore defer flush/truncation until undo data is later written.

Prior to this commit, we made the determination of whether the undo file was
full of all requisite data by comparing against the chain tip. This patch
replaces that dependence on validation data structures by instead just tracking
the highest height of any block written in the undo file as we go.
2023-07-14 14:47:00 -04:00
Suhas Daftuar 52e52071e0 p2p: Avoid prematurely clearing download state for other peers 2023-05-09 13:52:13 -04:00
Suhas Daftuar ccb8ca42a4 Always enforce SCRIPT_VERIFY_WITNESS with P2SH 2018-04-13 10:35:27 -04:00
Suhas Daftuar 95749a5836 Separate NULLDUMMY enforcement from SEGWIT enforcement
This is in preparation for enforcing SCRIPT_VERIFY_WITNESS from
the genesis block.
2018-04-13 10:35:27 -04:00
Suhas Daftuar ce650182f4 Use P2SH consensus rules for all blocks
This commit moves P2SH activation back to the genesis block, with
a hardcoded exception for the one historical block in the chain that
violated this rule.
2018-04-13 09:52:50 -04:00
Suhas Daftuar c60fd71a65 Disconnecting from bad outbound peers in IBD
When in IBD, we'd like to use all our outbound peers to help us
sync the chain.  Disconnect any outbound peers whose headers have
insufficient work.
2017-10-26 13:43:53 -04:00
Suhas Daftuar 6d51eaefe9 qa: Fix race condition in sendheaders.py 2017-10-23 08:55:21 -04:00
Suhas Daftuar c96b2e4f09 qa: Fix replace-by-fee race condition failures 2017-10-20 16:10:12 -04:00
Suhas Daftuar 01b52cedd4 Add comment explaining forced processing of compact blocks 2017-10-19 20:52:30 -04:00
Suhas Daftuar 08fd822771 qa: add test for minchainwork use in acceptblock 2017-10-19 20:38:22 -04:00
Suhas Daftuar ce8cd7a7da Don't process unrequested, low-work blocks
A peer could try to waste our resources by sending us unrequested blocks with
low work, eg to fill up our disk.  Since
e2652002b6 we no longer request blocks until we
know we're on a chain with more than nMinimumChainWork (our anti-DoS
threshold), but we would still process unrequested blocks that had more work
than our tip.  This commit fixes that behavior.
2017-10-19 20:33:45 -04:00
Suhas Daftuar f97ab35fa9 qa: Fix bug introduced in p2p-segwit.py
Changing __init__() -> set_test_params() in the tests should not have
applied to NodeConnCB-derived objects.
2017-09-13 09:21:27 -04:00
Suhas Daftuar a7820422e0 qa: Treat mininode p2p exceptions as fatal 2017-09-13 09:17:15 -04:00
Suhas Daftuar d01a9682b1 wallet: update stored witness in AddToWallet
Replace witness-stripped wallet transactions with full transactions;
this can happen when upgrading from a pre-segwit wallet to a segwit-
aware wallet.
2017-09-03 08:57:17 -04:00
Suhas Daftuar f1bf31186c [qa] Fix block message processing error in sendheaders.py 2017-08-11 21:36:28 -04:00
Suhas Daftuar e2652002b6 Delay parallel block download until chain has sufficient work
nMinimumChainWork is an anti-DoS threshold; wait until we have a proposed
tip with more work than that before downloading blocks towards that tip.
2017-05-08 14:27:04 -04:00
Suhas Daftuar f19abd9053 [qa] Fixes segwit block relay test after inv-direct-fetch was disabled
This test was passing because we never fetch blocks if we only receive
an inv and not the header (after 037159cebf),
and this test wasn't delivering the header.
2017-05-06 05:25:18 -04:00
Suhas Daftuar 9522b53a91 rpc: bumpfee: handle errors more gracefully 2017-01-31 20:03:45 -05:00
Suhas Daftuar f62659448c rpc: bumpfee: use correct maximum signed tx size for fee calculation
More accurate than simply adding one byte per input, and properly handles the
case where the original transaction happened to have very small signatures
2017-01-31 20:03:45 -05:00
Suhas Daftuar d625b907a1 wallet: Refactor dummy signature signing for reusability 2017-01-30 11:47:10 -05:00
Suhas Daftuar 2f10f06196 qa: Increase a sync_blocks timeout in pruning.py 2017-01-25 10:21:37 -05:00
Suhas Daftuar 4b06e41c30 Add unit test for FindEarliestAtLeast 2017-01-12 14:22:15 +00:00