Skip to content

Idea: add a PhantomData tag to differentiate DescriptorPublicKey before and after derivation #181

@afilini

Description

@afilini

I am starting to realize that most operations one might want to do on a Descriptor are only meaningful either if the descriptor has all the keys in their "extended" form or if all of them are "derived", not both: generally speaking, all the operations that need to call to_public_key() somewhere want the derived keys (and there are actual assertions in the code to ensure that), while other functions that work on the full paths of the keys like matches() want the original descriptor with the wildcard keys.

I think it would be nice to have the compiler check that the right methods are called on the right descriptor, and one way to do that would be to add a PhatomData "tag" to the Pk type that basically carries this information. For instance, the MiniscriptKey trait could be changed to take a type argument which we could call, let's say, "KeyState" and there would be two possibile "states", one called "Extended" and one called "Derived".

For key types that cannot be derived further by definition, only the "Derived" type would be implemented (i.e. impl MiniscriptKey<Derived> for bitcoin::PublicKey), while for types that can be derived like DescriptorPublicKey both would be implemented with a generic. Then, ToPublicKey would only be implemented for the Derived version, which would ensure that all the methods that need to_public_key() cannot possibly be called on a non-derived key. Other methods like derive() and matches() would instead only be available for Descriptors where their key type is Extended, like: impl<Pk: MiniscriptKey<Extended>> Descriptor<Pk> ... . The derive() method would obviously be responsible for translating the keys from the Extended state to the Derived state.

I haven't actually tried implementing this concept (yet), so there's a good chance that this is either not useful at all, completely broken, or just not the best way to do it, but I'm curious to hear your feedback on this topic!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions