Skip to content

fix(descriptor): make descriptor_id fallible for unsupported derivations - #1102

Open
Arowolokehinde wants to merge 1 commit into
bitcoindevkit:masterfrom
Arowolokehinde:descriptor-id-abort
Open

Arowolokehinde wants to merge 1 commit into
bitcoindevkit:masterfrom
Arowolokehinde:descriptor-id-abort

Conversation

@Arowolokehinde

@Arowolokehinde Arowolokehinde commented Aug 27, 2026

Copy link
Copy Markdown

Description

Descriptor::descriptor_id panics for parseable descriptors that cannot be derived
at a concrete index: multipath descriptors, and descriptors retaining hardened
public key derivations or hardened wildcards. It now returns
DescriptorError::MultiPath or DescriptorError::HardenedDerivationXpub instead.

The signature becomes Result<Arc<DescriptorId>, DescriptorError>, which is a
breaking change for Kotlin and Swift callers.

Fixes #1094.

Notes to the reviewers

  • Scoped to descriptor_id. derive_address has the same hardened-derivation
    problem, but that's already covered by DRAFT fix(descriptor): reject hardened public derivation paths #1079, so I've left it untouched.

  • The check has to run before at_derivation_index, not via map_err on its
    result.
    For the hardened cases miniscript panics inside
    DescriptorPublicKey::at_derivation_index rather than returning
    ConversionError, so there's no Err to map. Only multipath returns cleanly.

  • The guard is still required once a fixed Miniscript release is pinned, since
    bdk_chain::DescriptorExt::descriptor_id unwraps at_derivation_index(0).

    Multipath already shows this: miniscript returns Err cleanly and the unwrap
    panics regardless.

Documentation

  • bdk_walletbdk_chain::DescriptorExt::descriptor_id, re-exported as bdk_wallet::chain::DescriptorExt
  • Other: rust-miniscriptDescriptorPublicKey::at_derivation_index

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing
  • I've linked the relevant upstream docs or specs above

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

`Descriptor::descriptor_id` panicked for parseable descriptors that cannot be
derived at a concrete index: multipath descriptors, and descriptors retaining
hardened public key derivations or hardened wildcards.

The check must run before calling `at_derivation_index` rather than mapping its
error. For the hardened cases miniscript panics inside
`DescriptorPublicKey::at_derivation_index` instead of returning `ConversionError`,
so there is no `Err` to map.

The guard is still required once a fixed Miniscript release is pinned, since
`bdk_chain::DescriptorExt::descriptor_id` unwraps `at_derivation_index(0)` and
these descriptors remain panicable there regardless.

The signature becomes `Result<Arc<DescriptorId>, DescriptorError>`, a breaking
change for Kotlin and Swift callers.
@Arowolokehinde Arowolokehinde changed the title fix(descriptor): reject unsupported derivations in descriptor_id fix(descriptor): make descriptor_id fallible for unsupported derivations Aug 27, 2026
Comment thread bdk-ffi/src/descriptor.rs
// Miniscript 12.3.7 panics before returning `ConversionError` for these paths, and
// `bdk_chain`'s `descriptor_id` unwraps the result — so this check is still needed
// even once a fixed Miniscript release is pinned.
let contains_hardened_public_key_derivation = self.extended_descriptor.for_any_key(|key| {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since #1079 adds this same key traversal to derive_address, could we extract the hardened-public-derivation check into a private helper and reuse it in both methods when the branches are reconciled? Both methods guard the same at_derivation_index precondition, and duplicating it risks the two panic protections drifting as key handling changes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, i thought so too.
i can create a followup for this when the two PRs has been merged

@j-kon

j-kon commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

@reez, could you approve the first-time contributor CI run and apply changelog: breaking when convenient? This PR changes the exported descriptor_id() signature to return a Result.

@reez

reez commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

@reez, could you approve the first-time contributor CI run and apply changelog: breaking when convenient? This PR changes the exported descriptor_id() signature to return a Result.

For sure, thanks for the heads up!

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Descriptor::descriptor_id can abort on unsupported derivations

4 participants