Skip to content

Conversation

@apoelstra
Copy link
Member

@apoelstra apoelstra commented Oct 26, 2025

This PR contains two mostly-unrelated commits.

The first removes the Ctx::check_witness function, which is a no-op for the overwhelmingly common case that users are working with sane Miniscripts, and probably wrong in uncommon cases.

The second one removes the decode_insane method, replacing it with decode_consensus which allows much more stuff. The premise here is that "insane" Miniscripts are about allowing well-formed scripts that might not be analyzable because they violate some sanity rules, while "consensus" Miniscripts are anything the library can parse, no matter how half-baked or incomplete it is. When parsing strings we want "insane", when parsing on-chain scripts we want "consensus". The difference, for now, is that "consensus" Miniscripts can have raw pkhs while "insane" ones cannot.

More details in the commit messages.

This is a weird function. Its role is to double-check a witness after it
has been produced to ensure that it falls within limits. If you are
working with a sane miniscript this is impossible to fail, and if you're
working with an insane miniscript then the checks are too strong -- it
verifies standardness rules rather than consensus.

This was introduced in rust-bitcoin#189 without much discussion. It had no tests
then and has no tests now -- everything continues to pass.

I am removing it for now. I will later replace it with an API where you
call Plan::validate if you want to do checks like this. If the user wants
to do something oddball like "parse a miniscript without checking satisfaction
limits, then produce a satisfaction and see if the result is nonetheless
within limits" the workflow will be:

1. Parse an insane Miniscript
2. Produce a Plan
3. Run Plan::validate with tighter validation params than were used in
   step 1.

This gives the user a fair bit more flexibility. It is an awkward and
hard to discover workflow, but IMO it's better than we have now.
@apoelstra
Copy link
Member Author

@sanket1729 this one should be easy to review -- the diff is big but it's mostly about updating test cases. The actual code changes are to remove obscure functionality that I doubt any user has ever (intentionally) used.

Since it removes the decode_insane method, which we just renamed a couple PRs ago, I'd like to get this in before the 13.0 release.

@apoelstra
Copy link
Member Author

The next PR will be about making satisfaction non-recursive, which is a big job and I don't want to block 13.0 on. (And it is closely related to #868 which requires API changes we haven't quite finalized, so I don't want to do it right before a release even if it were technically easy.)

…nsensus

Currently we have decode() and decode_insane() (which were both called
parse_* before PR rust-bitcoin#845). In practice though, throughout the codebase we
see that when decoding from script we want to relax more than sanity.

In particular, we frequently with ExtParams::allow_all, which beyond
relaxing the sanity rules, also allows raw pubkeyhashes. We do this in
the script interpreter and in PSBT, on the basis that once we're working
with a script, we should just deal with whatever the library is capable
of dealing with. (Is this the right decision? IMO yes. It could be
argued. But regardless, it's the decision we've made for the past many
versions of rust-miniscript.)

I also propose to backport this with deprecation, telling users that if
they really want parse_insane, they now need to call decode_with_ext and
specify ExtParams::insane. But if their goal was "parse anything that
might be allowed", they actually want decode_consensus.

There is now an asymmetry between parsing from string and parsing from
script: with strings we have parse() and parse_insane(). With script we
have decode() and decode_consensus(). I think this is correct, and
reflects the fact that somebody "breaking the rules" with a string is
likely trying to use syntactically valid Miniscripts without the library
whining at him, while somebody "breaking the rules" with a Script is
probably trying to deal with some immutable on-chain thing and wants the
library to work if at-all possible.

Right now the distinction is simply "do we support raw pkh or not" but I
think we could accept more-or-less arbitrary extensions to Miniscript in
this library that worked the same way (allowed when decoded from script
but disallowed from strings since there's no serialization).
@apoelstra apoelstra force-pushed the 2025-10/validation-cruft branch from 553c2ae to bd8fca6 Compare October 26, 2025 13:08
@apoelstra
Copy link
Member Author

Locally I see the error

 Documenting miniscript v13.0.0 (/home/apoelstra/code/rust-bitcoin/rust-miniscript/master)
error: unresolved link to `doc/compiler.md`
   --> src/policy/concrete.rs:349:36
    |
349 |     /// the compiler document in [`doc/compiler.md`] for more details.
    |                                    ^^^^^^^^^^^^^^^ no item named `doc/compiler.md` in scope
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
    = note: requested on the command line with `-D rustdoc::broken-intra-doc-links`

error: could not document `miniscript`

which is about using [] around backticks in a link to a md document. This has been wrong since #565. I think it's a new nightly compiler thing to notice it, so it shouldn't affect CI, so I'm not gonna bother fixing it for now.

Copy link
Member Author

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On bd8fca6 successfully ran local tests

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK bd8fca6 - My review does not hold much weight.

@tcharding
Copy link
Member

tcharding commented Oct 27, 2025

FWIW this seems sane to me (pun intended).

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK bd8fca6

There is now an asymmetry between parsing from string and parsing from
script: with strings we have parse() and parse_insane(). With script we
have decode() and decode_consensus(). I think this is correct, and
reflects the fact that somebody "breaking the rules" with a string is
likely trying to use syntactically valid Miniscripts without the library
whining at him, while somebody "breaking the rules" with a Script is
probably trying to deal with some immutable on-chain thing and wants the
library to work if at-all possible

Makes sense to me.

@apoelstra apoelstra merged commit 609d4fb into rust-bitcoin:master Oct 27, 2025
31 checks passed
@apoelstra apoelstra deleted the 2025-10/validation-cruft branch October 27, 2025 13:11
@apoelstra apoelstra mentioned this pull request Oct 27, 2025
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.

3 participants