fix: BTC swap robustness — extension runway, RBF/canonical-chain, 2 confs#316
Merged
Conversation
remaining=4 (240 sub-blocks) + max(current, deadline) anchor put target_block - current at 240 + (deadline - current). Propose fires inside EXTEND_THRESHOLD_BLOCKS (=18) of the deadline, so target - current landed in [249, 257] — only the [9, 10] window fit the contract's hard 250-block cap (lib.rs:670, :1090). Anchor on current_block only; runway past the existing deadline is still ~220+ blocks (~44 min).
BIP-125 only replaces mempool txs; with min_confirmations=2 the tx is already buried under another block by the time verify returns confirmed, so RBF is mechanically moot. Canonical-chain check still covers reorg. Removing avoids false-rejecting modern wallets that flag RBF by default.
No method body reads it anymore — tier-1's confirmation gate and the remaining = min_confs - observed math were both removed when remaining collapsed to a fixed 4. Drop it from the four method signatures, the four forward.py call sites, and the test fixtures so the surface matches the behaviour.
anderdc
approved these changes
May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem → Solution
Problem 1 — tier-0 extension too short for BTC variance
remaining=1 → 4. Lands at +240 sub-blocks (~48 min runway from current).Problem 2 — tier-1 deadlocks when conf=1 arrives late
confs≥1gate + 8-block challenge-window guard intersect at zero when BTC polling lags by ≥1 block at the deadlineProblem 3 —
VALIDATOR_FORWARD_STEP_BLOCKS_ESTIMATEis 15× more conservative than realitystep=NlogsEXTEND_THRESHOLD_BLOCKS = ESTIMATE + CHALLENGE_WINDOW_BLOCKS = 18(was 28)Problem 4 — RBF-flagged BTC txs are replaceable post-broadcast
sequence < 0xfffffffein both verify paths (RPC + Esplora)Problem 5 — Esplora confirmation count doesn't verify canonical chain
confirmations → 0)tip_height − block_height + 1— doesn't checkin_best_chain/block/{hash}/statusand reject ifin_best_chain == falseProblem 6 — 3 BTC confs is conservative inertia, not necessity
min_confirmations: 3 → 2Anchor fix (commit
0ebace7)Originally landed with
compute_extension_targetanchoring onmax(current, deadline). Self-review caught that the contract enforcestarget_block - current_at_exec ≤ MAX_EXTENSION_BLOCKS = 250(lib.rs:670, :1090), soremaining=4(240 sub-blocks) anchored on deadline producedtarget - current ∈ [249, 257]at propose time — only a 2-block fitting window. Now anchored on current_block only; cap-safe at any propose time, with ~44-46 min runway past the existing deadline.Total budget math
Need 2 BTC confs in ~98 min. Time-to-2nd-block ~ Gamma(2, μ):
Well under the 1% target across reasonable conditions. Sized using https://en.bitcoin.it/wiki/Confirmation.
Test plan
ruff check allways/ neurons/— cleanruff format --check .— all formattedpytest tests/— 411/411 passing locallycompute_extension_target('btc', 4, 1000)→ 1240, delta 240 ≤ 250 capaw-valicontainer, watch next BTC swap for tier-0 propose attarget_block ≈ current + 240