Skip to content

fix(compile): compile only for the requested script context - #317

Open
vadim-anfv wants to merge 1 commit into
bitcoindevkit:masterfrom
vadim-anfv:fix/compile-per-context
Open

vadim-anfv wants to merge 1 commit into
bitcoindevkit:masterfrom
vadim-anfv:fix/compile-per-context

Conversation

@vadim-anfv

Copy link
Copy Markdown
Collaborator

The policy is compiled for all three script contexts one after another, before --type is looked at, and any of those failing aborts the command. So a policy that is valid for the type you asked for is rejected because it is invalid for one of the other two.

Here a 9-of-16 multisig is compiled with --type tr and fails on the legacy context: CHECKMULTISIG takes at most 15 keys, and what the compiler falls back to goes past MAX_SCRIPT_ELEMENT_SIZE, the 520-byte consensus limit. Taproot has no such limit.

$ cargo run --all-features -- compile "thresh(9,pk(a),pk(b),pk(c),pk(d),pk(e),pk(f),pk(g),pk(h),pk(i),pk(j),pk(k),pk(l),pk(m),pk(n),pk(o),pk(p))" --type tr

thread 'main' panicked at miniscript-12.3.7/src/policy/compiler.rs:506:52:
Terminal creation must always succeed: ContextError(MaxRedeemScriptSizeExceeded)

The fix moves the compilation into the matching branch, so only the requested context is compiled.

Changelog notice

  • Fixed compile rejecting policies that are valid for the requested script type

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@codecov

codecov Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.09%. Comparing base (1282553) to head (6e64d8f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #317      +/-   ##
==========================================
+ Coverage   59.79%   60.09%   +0.29%     
==========================================
  Files          22       22              
  Lines        3878     3869       -9     
==========================================
+ Hits         2319     2325       +6     
+ Misses       1559     1544      -15     
Flag Coverage Δ
rust 60.09% <100.00%> (+0.29%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vadim-anfv
vadim-anfv force-pushed the fix/compile-per-context branch from c626394 to eb8ca3f Compare September 17, 2026 10:11
@vadim-anfv vadim-anfv self-assigned this Sep 25, 2026
@vadim-anfv
vadim-anfv force-pushed the fix/compile-per-context branch from eb8ca3f to 6ed624e Compare September 25, 2026 06:46
@tvpeter tvpeter added this to the CLI 4.1.0 milestone Sep 28, 2026
@vadim-anfv
vadim-anfv force-pushed the fix/compile-per-context branch from 6ed624e to 85a7144 Compare September 30, 2026 09:30
@Musab1258

Musab1258 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

ACK 6ed624e

  • I pulled the change locally and ran the new test, which passes. I confirmed it fails on master with the miniscript MaxRedeemScriptSizeExceeded panic. I also ran a 2-of-20 pk threshold policy manually with --all-features: --type tr returns a tr(…,multi_a(2,…)) descriptor and --type wsh returns a wsh(multi(2,…)) descriptor. On master, wsh panics on the same policy.

  • I suggest you add a wsh test with the same policy. The fix helps wsh, but only tr is covered in tests.

  • --type sh with a legacy-oversized policy (same 2-of-20) still panics inside miniscript 12.3.7 (compiler.rs:506, exit 101) instead of returning an error. Worth a follow-up, either an upstream rust-miniscript issue or a clean error in bdk-cli?

Compiling for all three contexts let the narrowest one reject a policy
that is valid for the requested type: a 9-of-16 multisig, fine as
taproot multi_a, failed even for --type tr because legacy hit the
520-byte consensus limit on script elements.

The same policy also panicked for --type wsh,
which the test now covers.
@vadim-anfv
vadim-anfv force-pushed the fix/compile-per-context branch from 85a7144 to 6e64d8f Compare September 30, 2026 17:09
@vadim-anfv

Copy link
Copy Markdown
Collaborator Author

ACK 6ed624e

Thanks for testing!

I suggest you add a wsh test with the same policy. The fix helps wsh, but only tr is covered in tests.

Added the wsh case to the test with the same policy, so both contexts are covered now.

--type sh with a legacy-oversized policy (same 2-of-20) still panics inside miniscript 12.3.7 (compiler.rs:506, exit 101) instead of returning an error. Worth a follow-up, either an upstream rust-miniscript issue or a clean error in bdk-cli?

On --type sh: already fixed upstream. In 12.3.7 from_ast returns ContextError(MaxRedeemScriptSizeExceeded) for a 20-key threshold and the expect turns it into a panic. rust-bitcoin/rust-miniscript#828 dropped it, released in 13.0.0, and master handles it with if let Ok(...), skipping such a policy instead of aborting. bdk-cli is still on 12.3.7 through bdk_wallet, so we get this fix as soon as we move to miniscript 13.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready to Review

Development

Successfully merging this pull request may close these issues.

3 participants