Skip to content

Mempool: Do not enforce TRUC checks on reorg - #33504

Merged
fanquake merged 3 commits into
bitcoin:masterfrom
instagibbs:2025-09-truc-reorg-fix
Oct 2, 2025
Merged

fanquake merged 3 commits into
bitcoin:masterfrom
instagibbs:2025-09-truc-reorg-fix

Conversation

@instagibbs

@instagibbs instagibbs commented Sep 29, 2025 •

Copy link
Copy Markdown
Member

This was the intended behavior but our tests didn't cover the scenario where in-block transactions themselves violate TRUC topological constraints.

The behavior in master will potentially lead to many erroneous evictions during a reorg, where evicted TRUC packages may be very high feerate and make sense to mine all together in the next block and are well within the normal anti-DoS chain limits.

This issue exists since the merge of https://github.com/bitcoin/bitcoin/pull/28948/files#diff-97c3a52bc5fad452d82670a7fd291800bae20c7bc35bb82686c2c0a4ea7b5b98R956

@DrahtBot

DrahtBot commented Sep 29, 2025 •

Copy link
Copy Markdown
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/33504.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK sdaftuar, glozow, ismaelsadeeq

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32587 (test: Fix reorg patterns in tests to use proper fork-based approach by yuvicc)
  • #28676 (Cluster mempool implementation by sdaftuar)

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.

@instagibbs

instagibbs commented Sep 29, 2025 •

Copy link
Copy Markdown
Member Author

cc @glozow @sdaftuar candidate for backport(s)? Should be trivial for all effected versions.

@fanquake

Copy link
Copy Markdown
Member

https://github.com/bitcoin/bitcoin/actions/runs/18108538923/job/51529011305?pr=33504#step:8:1778:

Error processing input "/Users/runner/work/bitcoin/bitcoin/ci/scratch/qa-assets/fuzz_corpora/tx_pool/93f59991917f0dc980deabf80d553cf4573ebdd5"

test/util/txmempool.cpp:191 CheckMempoolTRUCInvariants: Assertion `entry.GetCountWithDescendants() <= TRUC_DESCENDANT_LIMIT' failed.
Error processing input "/Users/runner/work/bitcoin/bitcoin/ci/scratch/qa-assets/fuzz_corpora/tx_pool/93f59991917f0dc980deabf80d553cf4573ebdd5"

⚠️ Failure generated from target with exit code 1: ['/Users/runner/work/bitcoin/bitcoin/ci/scratch/build-aarch64-apple-darwin23.6.0/bin/fuzz', PosixPath('/Users/runner/work/bitcoin/bitcoin/ci/scratch/qa-assets/fuzz_corpora/tx_pool')]

@instagibbs
instagibbs force-pushed the 2025-09-truc-reorg-fix branch from a6cd2cb to 62f6c78 Compare September 29, 2025 19:49
@instagibbs

instagibbs commented Sep 29, 2025 •

Copy link
Copy Markdown
Member Author

@fanquake thanks, TRUC topology is no longer actually being stopped when limits are bypassed(when a reorg happens), so invariants checks for TRUC may fail now. I now removed the bypass_limits flags from all but one harness because they're not actually being used to model reorgs. If we want to fuzz reorgs, we should do that instead.

Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.
@instagibbs
instagibbs force-pushed the 2025-09-truc-reorg-fix branch from 62f6c78 to 06df14b Compare September 29, 2025 20:26
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Sep 30, 2025
Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.

Github-Pull: bitcoin#33504
Rebased-From: bbe8e90
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Sep 30, 2025
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.

Github-Pull: bitcoin#33504
Rebased-From: 26e71c2
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@bitcoin bitcoin deleted a comment Sep 30, 2025
@sdaftuar

Copy link
Copy Markdown
Member

ACK 06df14b

@glozow glozow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 06df14b

We don't re-check TRUC rules for descendants of reorged transactions because (1) there would be a performance hit and (2) we'd prefer to keep those fee-paying transactions: #28948 (comment). I agree it makes sense to also skip the ones in blocks themselves for similar reasons, especially as there are miners that don't apply the TRUC rules - it'd be good to re-mine their transactions if there are reorgs.

Comment thread src/validation.cpp
// have a non-TRUC and non-BIP125 descendant is due to a reorg.
} else {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
if (!args.m_bypass_limits) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While PackageTRUCChecks isn't in the reorg calling path, I think it would be cleaner and more future-proof to also gate that using if (!args.m_bypass_limits). There are Assumes in that function relying on the fact that SingleTRUCChecks is called first.

If you'd prefer not to, I'd recommend a comment in the commit message explaining that PackageTRUCChecks are not gated here because reorgs do not ever go through AcceptMultipleTransactions.

def test_truc_reorg(self):
node = self.nodes[0]
self.log.info("Test that, during a reorg, TRUC rules are not enforced")
tx_v2_block = self.wallet.send_self_transfer(from_node=node, version=2)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion for a few more within-block test cases, if you're interested (can also just open a followup, have some other test ideas as well)

diff --git a/test/functional/mempool_truc.py b/test/functional/mempool_truc.py
index 098631b5c41..58c69f07819 100755
--- a/test/functional/mempool_truc.py
+++ b/test/functional/mempool_truc.py
@@ -167,34 +167,76 @@ class MempoolTRUC(BitcoinTestFramework):
         self.log.info("Test that, during a reorg, TRUC rules are not enforced")
         self.check_mempool([])
 
+        # TRUC violations across the block + mempool
         # Testing 2<-3 versions allowed
         tx_v2_block = self.wallet.create_self_transfer(version=2)
-
         # Testing 3<-2 versions allowed
         tx_v3_block = self.wallet.create_self_transfer(version=3)
-
         # Testing overly-large child size
-        tx_v3_block2 = self.wallet.create_self_transfer(version=3)
+        tx_v3_large_parent = self.wallet.create_self_transfer(version=3)
+
+        # TRUC violations within the block
+        # 2<-3 versions
+        tx_v2_parent = self.wallet.create_self_transfer(version=2)
+        tx_v3_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v2_parent["new_utxo"], version=3)
+        # 3<-2 versions
+        tx_v3_parent = self.wallet.create_self_transfer(version=3)
+        tx_v2_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent["new_utxo"], version=2)
 
         # Also create a linear chain of 3 TRUC transactions that will be directly mined, followed by one v2 in-mempool after block is made
         tx_chain_1 = self.wallet.create_self_transfer(version=3)
         tx_chain_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_1["new_utxo"], version=3)
         tx_chain_3 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_2["new_utxo"], version=3)
 
-        tx_to_mine = [tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_block2["hex"], tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"]]
+        # 1-parent-2-child group of TRUC transactions that will be directly mined.
+        tx_1p2c_parent = self.wallet.create_self_transfer_multi(num_outputs=2, version=3)
+        tx_1p2c_child1 = self.wallet.create_self_transfer(utxo_to_spend=tx_1p2c_parent["new_utxos"][0], version=3)
+        tx_1p2c_child2 = self.wallet.create_self_transfer(utxo_to_spend=tx_1p2c_parent["new_utxos"][1], version=3)
+
+        # 2-parent-1-child group of TRUC transactions that will be directly mined.
+        tx_2p1c_parent1 = self.wallet.create_self_transfer(version=3)
+        tx_2p1c_parent2 = self.wallet.create_self_transfer(version=3)
+        tx_2p1c_child = self.wallet.create_self_transfer_multi(utxos_to_spend=[tx_2p1c_parent1["new_utxo"], tx_2p1c_parent2["new_utxo"]], version=3)
+
+        tx_to_mine = [
+            tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_large_parent["hex"],
+            tx_v2_parent["hex"], tx_v3_child["hex"],
+            tx_v3_parent["hex"], tx_v2_child["hex"],
+            tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"],
+            tx_1p2c_parent["hex"], tx_1p2c_child1["hex"], tx_1p2c_child2["hex"],
+            tx_2p1c_parent1["hex"], tx_2p1c_parent2["hex"], tx_2p1c_child["hex"]
+        ]
         block = self.generateblock(node, output="raw(42)", transactions=tx_to_mine)
 
         self.check_mempool([])
         tx_v2_from_v3 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block["new_utxo"], version=2)
         tx_v3_from_v2 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v2_block["new_utxo"], version=3)
-        tx_v3_child_large = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block2["new_utxo"], target_vsize=1250, version=3)
-        assert_greater_than(node.getmempoolentry(tx_v3_child_large["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE)
+        tx_v3_large_child = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_large_parent["new_utxo"], target_vsize=1250, version=3)
+        assert_greater_than(node.getmempoolentry(tx_v3_large_child["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE)
+
         tx_chain_4 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_chain_3["new_utxo"], version=2)
-        self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_4["txid"]])
+        self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_large_child["txid"], tx_chain_4["txid"]])
 
         # Reorg should have all block transactions re-accepted, ignoring TRUC enforcement
         node.invalidateblock(block["hash"])
-        self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"]])
+        self.check_mempool([
+            # 3<-2 block + mempool
+            tx_v3_block["txid"], tx_v2_from_v3["txid"],
+            # 2<-3 block + mempool
+            tx_v2_block["txid"], tx_v3_from_v2["txid"],
+            # oversized child block + mempool
+            tx_v3_large_parent["txid"], tx_v3_large_child["txid"],
+            # 2<-3 within the block
+            tx_v2_parent["txid"], tx_v3_child["txid"],
+            # 3<-2 within the block
+            tx_v3_parent["txid"], tx_v2_child["txid"],
+            # chain of 3 in block + 1 in mempool
+            tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"],
+            # 1-parent-2-child in block
+            tx_1p2c_parent["txid"], tx_1p2c_child1["txid"], tx_1p2c_child2["txid"],
+            # 2-parent-1-child in block
+            tx_2p1c_parent1["txid"], tx_2p1c_parent2["txid"], tx_2p1c_child["txid"],
+        ])
 
     @cleanup(extra_args=["-limitdescendantsize=10"])
     def test_nondefault_package_limits(self):

Comment thread src/validation.cpp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: documentation for bypass_limits in validation.h could mention that TRUC rules are not enforced and it's intended for reorgs

@ismaelsadeeq ismaelsadeeq left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 06df14b

I've reviewed the code and verify that after this PR TRUC rules are not enforced when limit is bypassed only for single transactions validation path.

Few nits on tests which can come in follow-up with glozow suggestions as well.

# Testing 3<-2 versions allowed
tx_v3_block = self.wallet.create_self_transfer(version=3)

# Testing overly-large child size

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In "test: add more TRUC reorg coverge" 06df14b

What does "Testing overly-large child size" mean here? the tx being created has a normal size
maybe use the pointer as used above 3<-2 (large size)?

block = self.generateblock(node, output="raw(42)", transactions=tx_to_mine)

block = self.generate(node, 1)
self.check_mempool([])

@ismaelsadeeq ismaelsadeeq Oct 2, 2025 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In "test: add more TRUC reorg coverge" 06df14b

This empty mempool check in between the block generation is redundant, because we have not send any transaction to the mempool.

@fanquake
fanquake merged commit 1ed00a0 into bitcoin:master Oct 2, 2025
20 checks passed
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Oct 2, 2025
Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.

Github-Pull: bitcoin#33504
Rebased-From: bbe8e90
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Oct 2, 2025
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.

Github-Pull: bitcoin#33504
Rebased-From: 26e71c2
javierpmateos added a commit to javierpmateos/bitcoin that referenced this pull request Apr 7, 2026
…emoveForReorg

When a transaction with nSequence=0 (BIP68 relative locktime 0) enters
the mempool with an unconfirmed parent, CalculatePrevHeights assigns
nCoinHeight=tip+1 and the resulting LockPoints are cached with
maxInputBlock=genesis. After invalidateblock lowers the tip,
TestLockPointValidity returns true for genesis (always on chain),
so the stale cached lockpoints are reused. CheckSequenceLocksAtTip
then incorrectly determines the lock is not satisfied and removes
the transaction.

Fix: detect the genesis sentinel (maxInputBlock->nHeight==0 with
lp.height>0) which indicates lockpoints computed with mempool parent
inputs, and force fresh recalculation via CalculateLockPointsAtTip.

This is the same class of issue fixed for TRUC in bitcoin#33504.

Closes bitcoin#35007
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.

Github-Pull: bitcoin#33504
Rebased-From: bf91a2d
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.

Github-Pull: bitcoin#33504
Rebased-From: e4df298
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
5fdf35d doc: update example bitcoin conf for 30.0rc3 (fanquake)
ad8bbca doc: update manual pages for v30.0rc3 (fanquake)
2eb2492 build: bump version to v30.0rc3 (fanquake)
0bcfe23 contrib: fix using macdploy script without translations. (amisha)
a6887c7 depends: static libxcb_cursor (fanquake)
979b902 test: add more TRUC reorg coverge (Greg Sanders)
d401c89 Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
308084f fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)
00b17a9 datacarrier: Undeprecate configuration option (Anthony Towns)
94f253a doc: rpc: fix case typo in `finalizepsbt` help (final_scriptwitness) (Sebastian Falbesoner)
2684d86 miner: fix `addPackageTxs` unsigned integer overflow (ismaelsadeeq)
729b46a rpc: fix getblock(header) returns target for tip (Sjors Provoost)
a24ef55 test: add block 2016 to mock mainnet (Sjors Provoost)

Pull request description:

  Backports:
  * bitcoin#33434
  * bitcoin#33446
  * bitcoin#33453
  * bitcoin#33475
  * bitcoin#33482
  * bitcoin#33484
  * bitcoin#33504

  Includes changes for `v30.0rc3`:
  * Version bump
  * Regen manpages
  * Regen exmaple .conf

ACKs for top commit:
  marcofleon:
    lgtm ACK 5fdf35d
  dergoegge:
    ACK 5fdf35d
  hebasto:
    ACK 5fdf35d, I agree on the backported PRs. I've reproduced locally all backports, the manpages update, and the example `bitcoin.conf` updated, and obtained zero diff with this PR.
  Zero-1729:
    LGTM ACK 5fdf35d

Tree-SHA512: 90bffbb6dfe2b512167b5e08253ea163b714505ec3ef2247d798c40b30713a7db13cf0b5486b5f9e0e5b3ba53108dfaeea47276c40816eeb81065d42bd402379
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.

Github-Pull: bitcoin#33504
Rebased-From: bf91a2d
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.

Github-Pull: bitcoin#33504
Rebased-From: e4df298
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
b5def28 doc: update release notes for 28.x (fanquake)
90a9e4e test: add more TRUC reorg coverge (Greg Sanders)
520fc8e Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
8930c36 fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)

Pull request description:

  Backports:
  * bitcoin#33504

ACKs for top commit:
  darosior:
    utACK b5def28.
  dergoegge:
    ACK b5def28
  instagibbs:
    ACK b5def28

Tree-SHA512: 50495b75dec6dbbe24686cd7f1e832a79c841d29983d6be415783ba4ad3a1f7657459d491fc214de4d45f60467abc92f1daf75479f3db854fc6b3410368e67fc
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Using bypass_limits=true is essentially fuzzing part of a
reorg only, and results in TRUC invariants unable to be
checked. Remove most instances of bypassing limits, leaving
one harness able to do so.

Github-Pull: bitcoin#33504
Rebased-From: bf91a2d
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
Not enforcing TRUC topology on reorg was the intended
behavior, but the appropriate bypass argument was not
checked.

This mistake means we could potentially invalidate a long
chain of perfectly incentive-compatible transactions that
were made historically, including subsequent non-TRUC
transactions, all of which may have been very high feerate.

Lastly, it wastes CPU cycles doing topology checks since
this behavior cannot actually enforce the topology in
general for the reorg setting.

Github-Pull: bitcoin#33504
Rebased-From: e4df298
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
morozow pushed a commit to morozow/bitcoin_rd that referenced this pull request May 8, 2026
e3820d4 doc: update release notes for 29.x (fanquake)
69c4661 test: add more TRUC reorg coverge (Greg Sanders)
e439ed1 Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
54377c7 fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)
cf82bb4 doc: rpc: fix case typo in `finalizepsbt` help (final_scriptwitness) (Sebastian Falbesoner)
ff55cf5 rpc: fix getblock(header) returns target for tip (Sjors Provoost)
b29bbb0 test: add block 2016 to mock mainnet (Sjors Provoost)

Pull request description:

  Backports:
  * bitcoin#33446
  * bitcoin#33484
  * bitcoin#33504

ACKs for top commit:
  luke-jr:
    ACK e3820d4
  dergoegge:
    ACK e3820d4
  marcofleon:
    ACK e3820d4

Tree-SHA512: 27b852177d8502d6c703cb0eeb1e4df9d651c9c8add5fbf6ae4eeb4b8aefc145471f38f9794c0ed276bf7ebba1844ecbaf5a84cb5913ca7d0a546f5216ea3b2d
Kino1994 pushed a commit to Kino1994/bitcoin-full-history that referenced this pull request Jun 28, 2026
…eorg

ab0e2f1 test: add more TRUC reorg coverge (Greg Sanders)
331063f Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
a31db34 fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)

Pull request description:

  This was the intended behavior but our tests didn't cover the scenario where in-block transactions themselves violate TRUC topological constraints.

  The behavior in master will potentially lead to many erroneous evictions during a reorg, where evicted TRUC packages may be very high feerate and make sense to mine all together in the next block and are well within the normal anti-DoS chain limits.

  This issue exists since the merge of https://github.com/bitcoin/bitcoin/pull/28948/files#diff-97c3a52bc5fad452d82670a7fd291800bae20c7bc35bb82686c2c0a4ea7b5b98R956

ACKs for top commit:
  sdaftuar:
    ACK ab0e2f1
  glozow:
    ACK ab0e2f1
  ismaelsadeeq:
    Code review ACK ab0e2f1

Tree-SHA512: bdb6e4dd622ed8b0b11866263fff559fcca6e0ca1c56a884cca9ac4572f0026528a63a9f4c8a0660df2f5efe0766310a30e5df1d6c560f31e4324ea5d4b3c1a8
Kino1994 pushed a commit to Kino1994/bitcoin-full-history that referenced this pull request Jun 28, 2026
8e776bb policy: don't CheckEphemeralSpends on reorg (Greg Sanders)

Pull request description:

  Similar reasoning to bitcoin/bitcoin#33504

  During a deeper reorg it's possible that a long sequence of dust-having transactions that are connected in a linear fashion. On reorg, this could cause each subsequent "generation" to be rejected. These rejected transactions may contain a large amount of competitive fees via normal means.

  PreCheck based `PreCheckEphemeralSpends` is left in place because we wouldn't have relayed them prior to the reorg.

ACKs for top commit:
  darosior:
    re-ACK 8e776bb
  ismaelsadeeq:
    reACK 8e776bb
  sedited:
    ACK 8e776bb

Tree-SHA512: cf0a6945066e9f5f8f9a847394c2c1225facf475a8aa4bc811b436513eff79c0a720d4ad21ba6b0f1cc4dfdd61cf46acb148333ac592b2ee252953732326ad1d
BigcoinBGC pushed a commit to BigcoinBGC/bigcoin that referenced this pull request Jun 30, 2026
…eorg

3fec028 test: add more TRUC reorg coverge (Greg Sanders)
e4df298 Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
bf91a2d fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)

Pull request description:

  This was the intended behavior but our tests didn't cover the scenario where in-block transactions themselves violate TRUC topological constraints.

  The behavior in master will potentially lead to many erroneous evictions during a reorg, where evicted TRUC packages may be very high feerate and make sense to mine all together in the next block and are well within the normal anti-DoS chain limits.

  This issue exists since the merge of https://github.com/bitcoin/bitcoin/pull/28948/files#diff-97c3a52bc5fad452d82670a7fd291800bae20c7bc35bb82686c2c0a4ea7b5b98R956

ACKs for top commit:
  sdaftuar:
    ACK 3fec028
  glozow:
    ACK 3fec028
  ismaelsadeeq:
    Code review ACK 3fec028

Tree-SHA512: bdb6e4dd622ed8b0b11866263fff559fcca6e0ca1c56a884cca9ac4572f0026528a63a9f4c8a0660df2f5efe0766310a30e5df1d6c560f31e4324ea5d4b3c1a8
BigcoinBGC pushed a commit to BigcoinBGC/bigcoin that referenced this pull request Jun 30, 2026
f95291d policy: don't CheckEphemeralSpends on reorg (Greg Sanders)

Pull request description:

  Similar reasoning to bitcoin/bitcoin#33504

  During a deeper reorg it's possible that a long sequence of dust-having transactions that are connected in a linear fashion. On reorg, this could cause each subsequent "generation" to be rejected. These rejected transactions may contain a large amount of competitive fees via normal means.

  PreCheck based `PreCheckEphemeralSpends` is left in place because we wouldn't have relayed them prior to the reorg.

ACKs for top commit:
  darosior:
    re-ACK f95291d
  ismaelsadeeq:
    reACK f95291d
  sedited:
    ACK f95291d

Tree-SHA512: cf0a6945066e9f5f8f9a847394c2c1225facf475a8aa4bc811b436513eff79c0a720d4ad21ba6b0f1cc4dfdd61cf46acb148333ac592b2ee252953732326ad1d
Kino1994 pushed a commit to Kino1994/bitcoin-full-history that referenced this pull request Aug 19, 2026
…eorg

06df14ba75be5f48cf9c417424900ace17d1cf4d test: add more TRUC reorg coverge (Greg Sanders)
26e71c237d9d2197824b547f55ee3a0a60149f92 Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)
bbe8e9063c15dc230553e0cbf16d603f5ad0e4cf fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)

Pull request description:

  This was the intended behavior but our tests didn't cover the scenario where in-block transactions themselves violate TRUC topological constraints.

  The behavior in master will potentially lead to many erroneous evictions during a reorg, where evicted TRUC packages may be very high feerate and make sense to mine all together in the next block and are well within the normal anti-DoS chain limits.

  This issue exists since the merge of https://github.com/bitcoin/bitcoin/pull/28948/files#diff-97c3a52bc5fad452d82670a7fd291800bae20c7bc35bb82686c2c0a4ea7b5b98R956

ACKs for top commit:
  sdaftuar:
    ACK 06df14ba75be5f48cf9c417424900ace17d1cf4d
  glozow:
    ACK 06df14ba75b
  ismaelsadeeq:
    Code review ACK 06df14ba75be5f48cf9c417424900ace17d1cf4d

Tree-SHA512: bdb6e4dd622ed8b0b11866263fff559fcca6e0ca1c56a884cca9ac4572f0026528a63a9f4c8a0660df2f5efe0766310a30e5df1d6c560f31e4324ea5d4b3c1a8
Kino1994 pushed a commit to Kino1994/bitcoin-full-history that referenced this pull request Aug 19, 2026
33fbaed310a6a37d41d26af8fb34308d088d72c8 policy: don't CheckEphemeralSpends on reorg (Greg Sanders)

Pull request description:

  Similar reasoning to bitcoin/bitcoin#33504

  During a deeper reorg it's possible that a long sequence of dust-having transactions that are connected in a linear fashion. On reorg, this could cause each subsequent "generation" to be rejected. These rejected transactions may contain a large amount of competitive fees via normal means.

  PreCheck based `PreCheckEphemeralSpends` is left in place because we wouldn't have relayed them prior to the reorg.

ACKs for top commit:
  darosior:
    re-ACK 33fbaed310a
  ismaelsadeeq:
    reACK 33fbaed310a6a37d41d26af8fb34308d088d72c8
  sedited:
    ACK 33fbaed310a6a37d41d26af8fb34308d088d72c8

Tree-SHA512: cf0a6945066e9f5f8f9a847394c2c1225facf475a8aa4bc811b436513eff79c0a720d4ad21ba6b0f1cc4dfdd61cf46acb148333ac592b2ee252953732326ad1d
@bitcoin bitcoin locked and limited conversation to collaborators Oct 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants