Repository navigation
fix(descriptor): reject raw pkh in Taproot leaves when parsing Tr - #1061
Conversation
- Validate Tr leaves with Tap::CONSENSUS minus allow_raw_pkh, matching Miniscript::from_str_insane, so Tr::from_str no longer accepts expr_raw_pkh like v12 did - Cover single, sibling and nested raw pkh leaves Fixes rust-bitcoin#1056 Assisted-by: Claude Opus 5.5
|
I used AI tools for development, did many reviews and fixing rounds locally before opening this. @Kixunil probably wont help here with review as he doesn't work on miniscript unfortunately |
|
Thanks! Yeah, this looks great. At some point I'll get back to this part of the code and remove the "hack" and hopefully we'll have something cleaner or more principled here. Could you also open a backport PR to the |
Taking care of the backport and version bump here: #1071 |
- Backport PR rust-bitcoin#1061 using ExtParams::insane() on release-13.x. - Preserve other accepted non-sane leaves and cover single, sibling and nested raw-pkh leaves. Backport-of: 3642826 Assisted-by: Claude Opus 5.5 Assisted-by: OpenAI GPT-6.1-Sol
c891370 chore(release): prepare 13.2.0 (Trevor Arjeski) f7b7f86 fix(descriptor): mark WalletPolicyError as non-exhaustive (Trevor Arjeski) b804c27 fix(descriptor): reject raw pkh in Taproot leaves when parsing Tr (PeterXMR) Pull request description: Backport #1054 to `release-13.x`, marking `WalletPolicyError` as non-exhaustive. Backport #1061 (20d7133), rejecting raw public-key hashes in directly parsed Taproot leaves. Bump to 13.2.0 and update the lockfiles and changelog for changes since 13.1.0. Both backports precede the version bump commit. ACKs for top commit: apoelstra: ACK c891370; successfully ran local tests Tree-SHA512: 649a829acccb474caffe487774e305dbf0394c03c975c02c27c1a9434db62a91edf43c5c74bce5095ba7bde1d09a4f166dd1da0532157c0b5b693b5e6fd04aef
Tr::from_tree (and therefore Tr::from_str) validated each tapscript leaf
with Tap::CONSENSUS plus a no-raw-pkh override, instead of Tap::SANE as
Miniscript parsing and Descriptor::from_str's later wrapper check do.
Signatureless leaves ("tr(K,or_i(pk(K),1))", "tr(K,after(1))") and
duplicate keys in "multi_a" script paths therefore parsed fine through
Tr::from_str / FromTree for Descriptor, while the same strings were
rejected by Descriptor::from_str -- a parser disagreement producing
anyone-can-spend tapleaves (or one-signer thresholds). rust-bitcoin#734.
Now Tr::from_tree (factored as from_tree_with_leaf_params with SANE at
the public entry points) validates every leaf with Tap::SANE, which
already includes the raw-pkh rejection from rust-bitcoin#1061. The redundant
tr-leaf validation loop in Descriptor::from_str is dropped, since the
public FromTree for Descriptor path now provides the same guarantee.
The taproot merkle fixed-vector tests intentionally use insane
(signatureless/unsatisfiable) leaves to exercise tree hashing; they now
use a test-only consensus-level parsing helper rather than depending on
the sane public parsers accepting non-sane leaves.
Not fixed by the still-open rust-bitcoin#991 refactor either (verified against its
PR head).
Assisted-by: kimi-k3
Fixes #1056.
Since #775,
Tr::from_treevalidates leaves withTap::CONSENSUS, which allowsraw pkh, so
Tr::from_stracceptsc:expr_raw_pkh(..)where 12.x rejected it.Descriptor::from_strwas unaffected because it re-validates leaves withTap::SANE.This validates leaves with
Tap::CONSENSUSminusallow_raw_pkh, the same paramsas
Miniscript::from_str_insane. I deliberately did not switch to fullTap::SANE.12.x
Tr::from_stralso rejected malleable, repeated-key, mixed-timelock andsigless leaves, and 13.x still accepts these via
Tr::from_str(but notDescriptor::from_str). That is the known #734 hack that theFromTreevalidationrework (#991) is meant to remove, so it is left unchanged here.
Out of scope:
wsh/sh/bare still accept raw pkh throughDescriptor::from_str;that is pre-existing and tracked in #734.
I'll follow up with a backport PR to
release-13.x.