docs: five wallet-layer claims, verified — one of which was understated - #613
Merged
Conversation
Assertive text is a claim, and no test evaluates claims — tests pin that a
sentence is emitted, never that it is correct. Five docstrings/comments in the
swap wallet layer had drifted from the code beside them. Each correction says
what is true and what the text used to say, so anyone who relied on the old
wording knows to re-check. NO BEHAVIOUR CHANGES.
taproot.refund_leaf_script — "Any caller that builds a leaf ... gets the floor by
construction" was false: the refusal is scoped to TimeUnit.BLOCKS. BIP68 quantises
time locks to 512 s, so Timelock(0..511, SECONDS) all encode nSequence 0x00400000
(zero time units) — the same no-op relative lock a 0-block CSV is — and are emitted
without complaint. swap_state.NegotiatedTerms carried the identical over-broad claim
("unrepresentable for every caller") over an identically BLOCKS-scoped condition;
corrected too, since leaving one would have contradicted the other.
btc_wallet.htlc_leg — "txid_of resolves ... VIA THE NODE — never a local segwit
parse" had the mechanism exactly backwards, in the BtcFundingReader Protocol, in
its txid_of stub, and in confirmations_of_claim's own docstring, which contradicted
the comment three lines below it. All three shipped readers (mempool.space,
Bitcoin Core, MultiSource) call taproot.btc_txid_from_raw. The safety property is
unchanged and is better served by the local derivation: the gated txid must be that
of the exact bytes p was scraped from, and serialising them asks nobody.
eth_wallet.erc20_leg.claim — "checked alongside both parties" describes round 4's
address list; round 5 removed the refundee on purpose (a claim never touches it, so
refusing there refuses valid work and hands the counterparty a free unilateral veto)
and the call site passes claimant only.
eth_wallet.htlc_leg module docstring — "funded balance == negotiated amount" where
the check is `bal < expected_amount_wei`, a deliberate LOWER bound (an == check is
griefable by a 1-wei force-send). verify_funded documents it correctly at the check;
EthHtlcLocator.amount_wei repeated the same == claim and is corrected with it.
eth_wallet.locator.EthHtlcLocator.chain_id — "the leg refuses a chain_id mismatch
up front" is false; nothing in src/ or scripts/ compares locator.chain_id to
anything. EthRpc.assert_chain compares the NODE to the LEG's expected_chain_id, a
different check. The field is now documented as a record, not a gate.
Two gaps are REPORTED rather than fixed, because both are behaviour changes on
fund-moving code and need their own review: the BLOCKS-only scoping of the zero-
timelock floors, and the absent locator/leg chain-id comparison.
Verified: ruff check + ruff format --check clean; full suite 10985 passed,
197 skipped, 4 xfailed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Zyrtnin
pushed a commit
that referenced
this pull request
Sep 4, 2026
#613 documented the BLOCKS-only floor and said 'left as-is deliberately - widening the refusal is a behaviour change that needs its own review'. This branch IS that review, and the fix: the refusal now keys on the encoded magnitude, so it is unit-agnostic by construction. Kept the fix.
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.
Five prose claims in fund-moving wallet code, flagged by a reviewer that explicitly marked them unverified. All five held on checking — but one's secondary assertion was wrong, in the direction of understating the problem, and that turned into #612.
taproot.py"any caller gets the floor"htlc_leg.py"txid_ofresolves via the node"erc20_leg.py"checked alongside both parties"htlc_leg.py"funded balance == negotiated amount"<, a deliberate lower bound, correctly documented elsewherelocator.py"pins which network"Reported, not fixed
Nothing compares
locator.chain_idto anything.EthRpc.assert_chaincompares the node to the leg's expected chain id, so a leg pointed at the wrong network is caught — but a locator from a different network driven by a correctly-configured leg is not, andclaim()against an address with no code on the target chain does not revert.Adding that check is a behaviour change on fund-moving code and wants its own review, so it is reported rather than slipped into a prose pass.
Bonus, unprompted
EthHtlcLocator.amount_weicarried the identical false==claim, andswap_state.pycarried the twin over-broad "unrepresentable for every caller" — which would have contradicted the taproot correction sitting one call away.Comments and docstrings only; no behaviour changed. Verified independently: full suite green at baseline skip/xfail counts.
🤖 Generated with Claude Code