fix(wallet): treat unreachable relative locktimes as unsatisfied - #565
Open
trakshan-mishra wants to merge 1 commit into
Open
trakshan-mishra wants to merge 1 commit into
trakshan-mishra wants to merge 1 commit into
Conversation
`Older::check_older` added the relative locktime to the previous
transaction's confirmation height and unwrapped the sum with
`expect("Overflowing addition")`. `Wallet::finalize_psbt` maps an
unconfirmed previous transaction to a confirmation height of `u32::MAX`,
so finalizing a PSBT that spends an unconfirmed UTXO of a descriptor
carrying an `older(n)` branch panicked for every `n` greater than zero.
The `Older` satisfier is only consulted when the input's `nSequence` does
not already satisfy the CSV branch, so this is reachable through ordinary
use: spending an unconfirmed output through a branch that is not the
`older()` one, which `Wallet::sign` finalizes by default.
Return `false` when the satisfaction height does not fit in a `u32`. Such
a height can never be reached, so the branch is simply not satisfied,
which is the same answer the comparison would give with wider integers.
2 tasks
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.
Fixes #557.
Problem
Older::check_older(src/wallet/utils.rs) computes the height at which a relative locktime is satisfied ascreate_height + nand unwraps the sum withexpect("Overflowing addition").Wallet::finalize_psbtmaps an unconfirmed previous transaction to acreate_heightofu32::MAX, so that addition overflows and panics for anyolder(n)withngreater than zero.The
Oldersatisfier is only consulted when the input'snSequencedoes not already satisfy the CSV branch, so this is reachable through ordinary use: spending an unconfirmed UTXO of a descriptor that contains anolder()branch which is not the one being used, e.g. spending viapk(A)ofor_d(pk(A),and_v(v:pk(B),older(144))). SinceWallet::signfinalizes by default, callers reach it without opting in.Fix
Return
falsewhen the satisfaction height does not fit in au32, rather than panicking. Such a height can never be reached, so the branch is simply not satisfied — the same answer the comparison would give with wider integers. This matches the behaviour the issue asks for ("theolder()branch should simply be treated as not satisfied").The change is in the
Satisfierimpl, so it covers both call sites: finalization insrc/wallet/mod.rsand policy extraction insrc/descriptor/policy.rs.After::check_afterperforms no addition and is unaffected.Tests
test_finalize_psbt_with_unconfirmed_input_and_unused_csv_branch(tests/wallet.rs) reproduces the reported panic end to end. Verified to fail on master withpanicked at src/wallet/utils.rs:117: Overflowing addition, and to pass with this change.test_check_older_unreachable_satisfaction_height_is_not_satisfiedcovers the overflow directly at the unit level.test_check_older_compares_against_the_satisfaction_heightcovers the ordinary satisfied and unsatisfied heights, which had no unit coverage before.Checklist
just pre-pushsteps locally:cargo +nightly fmt --all -- --check, bothcargo checkvariants,clippywith-D warningson the stable and unstable surfaces,cargo test --workspaceon both surfaces, andcargo docwith-D warnings. All pass.One note:
cargo +nightly fmton current master also wants to reformatsrc/descriptor/policy.rs, which is unrelated to this fix (and looks like the nightly drift tracked in #535), so I left that file untouched.