Skip to content

Feature discussion: partial descriptors/miniscript #24114

@sipa

Description

@sipa

So far, we effectively have two levels of "solvability" in descriptors:

  • addr() and raw() which can encode scriptPubKey with effectively no solvability information at all
  • Everything else, which encodes scriptPubKeys that are fully solvable.

I've long held that there shouldn't be any level in between, in the sense that you shouldn't be using a descriptor if you don't know everything about its construction. I'm starting to think that's not a tenable position:

  • Already, key origin information - which may be no less critical than other parts of descriptors for certain roles - is optional. There is no way to force that information to be included, because it may not exist (for non-BIP32-derived keys, for example), but it may also simply be omitted.
  • Add rawtr() descriptor for P2TR with specified (tweaked) output key #23480 proposes the introduction of a descriptor like tr(), except it encodes the post-tweak key rather than the inner key. This too may be because the information doesn't exist, but it cannot prevent situations where it is simply omitted.
  • It has been suggested before (e.g. Basic Taproot signing support for descriptor wallets #21365 (comment)) to permit tr() descriptors to contain hashes for omitted script subtrees. That too could represent non-existent information (Merkle path entries that are chosen rather than actual hashes), or omitted information. And it is useful - there are certainly scenarios where one might want to participate in, and sign for, taproot outputs for which certain subtrees are not known.
  • If we're going to accept that the previous 3 examples will occur, we might as well bite the bullet and also add a way to encode "pkh with known keyhash, but not known key".

If all these mechanisms become permitted in descriptors (and miniscript), we get the nice logistical benefit of being able to represent all information extracted from PSBT/SPKM/scripts/... into a descriptor regardless of what is present or missing. I believe this would logistically simplify things later on too: Miniscript would not need separate instantiations for its descriptor-decoding use case and its signing/solving use case. Perhaps even further out, this can mean that many fields in SignatureData are replaced with just a descriptor object (everything except signatures/preimages), and the signing logic becomes a descriptor method.

Straw man proposal:

  • Do Add rawtr() descriptor for P2TR with specified (tweaked) output key #23480 (adding rawtr(KEY)), for P2TR outputs with specified tweaked key, but no specified internal key or script tree.
  • Add a rawnode(HEX) fragment, only usable inside P2TR script tree expressions, indicating a tree node with specified hash, but no specified subtree.
  • Add a rawpkh(HEX) fragment, usable wherever pkh(KEY) is usable, indicating a PKH script (DUP HASH160 <hex> EQUALVERIFY CHECKSIG), without specified public key. Post-miniscript this would also add a rawpk_h(HEX) fragment, corresponding to pk_h(KEY).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions