Skip to content

fix(wasm-utxo): infer input script type in fromPsbt with nonstandard derivations - #361

Merged
davidkaplanbitgo merged 2 commits into
masterfrom
otto/WCN-2155-infer-input-script-type
Aug 18, 2026
Merged

fix(wasm-utxo): infer input script type in fromPsbt with nonstandard derivations#361
davidkaplanbitgo merged 2 commits into
masterfrom
otto/WCN-2155-infer-input-script-type

Conversation

@OttoAllmendinger

@OttoAllmendinger OttoAllmendinger commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Dimensions.from_psbt classified inputs based on BIP32 derivation chain codes, falling back to P2shP2pk (replay protection) when no standard BitGo chain was found. For P2WSH PSBTs with nonstandard derivation paths this inflated vsize ~2.5x, understating feeRate, triggering maxfeerate broadcast rejections (WCN-2155).

Replace the entire classification path with a single call to infer_input_script_type for every input. Classification is now based solely on script metadata (witness_script, redeem_script, taproot fields, output-script shape), independent of BIP32 derivation chain codes.

Changes

  • psbt_wallet_input.rs — Add infer_input_script_type, which classifies from script/witness metadata: witness_script (verified as 2-of-3 multisig) → P2wsh/P2shP2wsh; redeem_script (P2PK or 2-of-3 multisig) → P2shP2pk/P2sh; taproot metadata → P2trMusig2 variants; is_p2mr output → P2mr. Every candidate is cross-checked against the output-script shape. Errors on bare inputs (only witness_utxo) or shape mismatches.
  • dimensions.rs — Replace the entire from_psbt input classification loop with a call to infer_input_script_type. The old BIP32 derivation-chain-code path and P2shP2pk default fallback are removed.
  • address/mod.rs — Re-export is_p2mr as pub(crate) for P2MR (BIP-360) detection.
  • test/dimensions.ts — Red test (commit 1) reproduces the bug with nonstandard derivation paths via the WrapPsbt/descriptor API; fix commit flips assertions to green and adds a replay-protection test case.

Refs: WCN-2155

@linear-code

linear-code Bot commented Aug 17, 2026

Copy link
Copy Markdown

WCN-2155

@OttoAllmendinger
OttoAllmendinger force-pushed the otto/WCN-2155-infer-input-script-type branch 10 times, most recently from cd6e72f to f294161 Compare August 18, 2026 10:12
…erivations

Dimensions.fromPsbt classifies inputs using BIP32 derivation chain codes,
falling back to P2shP2pk when no standard BitGo chain is found. PSBTs
with nonstandard chain codes on valid P2WSH 2-of-3 multisig inputs cause
misclassification as non-segwit P2shP2pk. This inflates vsize ~2.5x,
understates feeRate, and triggers maxfeerate broadcast rejections
(WCN-2155).

This test asserts the current (buggy) behavior: a P2WSH PSBT built with
nonstandard chain codes (0/1 instead of 20/21) via the WrapPsbt/descriptor
API is classified as non-segwit P2shP2pk, producing a larger vsize than
the equivalent wallet-built PSBT. Also asserts the P2shP2pk fallback for
replay-protection inputs without derivations.

Refs: WCN-2155
…ard derivations

Dimensions.from_psbt unconditionally classified inputs lacking BIP32
derivation paths as P2shP2pk (replay protection), regardless of the
actual script type. For P2WSH PSBTs with nonstandard derivation paths
this inflated vsize ~2.5x, understating feeRate and triggering
maxfeerate broadcast rejections (WCN-2155).

Replace the entire classification path with a single call to
infer_input_script_type for every input. Classification is now based
solely on script metadata: witness_script (verified as 2-of-3 multisig
via parse_multisig_script_2_of_3) → P2wsh/P2shP2wsh; redeem_script
(P2PK via parse_p2pk_script, or 2-of-3 multisig) → P2shP2pk/P2sh;
taproot metadata (tap_scripts/tap_internal_key) → P2trMusig2 variants;
is_p2mr output → P2mr. Every candidate is cross-checked against the
output-script shape; mismatches and bare inputs (only witness_utxo)
error rather than guessing.

The old BIP32 derivation-chain-code path is removed entirely — script
metadata is sufficient and more authoritative. The P2shP2pk default
fallback is gone; replay protection inputs are now correctly detected
via their P2PK redeem_script.

Refs: WCN-2155
@OttoAllmendinger
OttoAllmendinger force-pushed the otto/WCN-2155-infer-input-script-type branch from f294161 to 5499ca0 Compare August 18, 2026 10:15
@OttoAllmendinger OttoAllmendinger changed the title fix(wasm-utxo): infer input script type in fromPsbt without derivations fix(wasm-utxo): infer input script type in fromPsbt with nonstandard derivations Aug 18, 2026
@OttoAllmendinger
OttoAllmendinger marked this pull request as ready for review August 18, 2026 10:30
@OttoAllmendinger
OttoAllmendinger requested a review from a team as a code owner August 18, 2026 10:30
@davidkaplanbitgo
davidkaplanbitgo merged commit a10e4e5 into master Aug 18, 2026
13 checks passed
@davidkaplanbitgo
davidkaplanbitgo deleted the otto/WCN-2155-infer-input-script-type branch August 18, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants