Add DescriptorSecretKey and Descriptor::parse_secret()#116
Add DescriptorSecretKey and Descriptor::parse_secret()#116apoelstra merged 5 commits intorust-bitcoin:masterfrom
DescriptorSecretKey and Descriptor::parse_secret()#116Conversation
|
I pushed some experiments I've been doing with the I initially liked the first approach better because it hides the logic of pushing the signature in the I guess the The other big question is whether I should add an explicit flag to ask for a BIP143 signature or try to automatically determine it by looking at the |
I don't completely follow this, what is the issue to determine by looking at As for the role of miniscript in PSBT stack, we originally thought that miniscript should only be required for finalizing
Please note that the My understanding that the overall flow should be as follows: (cc @apoelstra ) I did not look at all of the code yet, but most of it looks good. |
I don't know how realistic this is, I was just thinking that maybe some wallets could decide in the future to always include
If you feel like the signers are out of scope I can totally remove them. There was #93 (comment) that said "and have our [signers] map use the Satisfier trait to allow users to produce signatures etc with it." so I interpreted that as "implement Satisfier on SignersContaner so that it can produce signatures on-demand", but I might have just misunderstood something.
Yeah, I think you are right. I was trying to keep the structs "parallel" (Miniscript -> MiniscriptWithSigners, Descriptor -> DescriptorWithSigners) but now that I think about it, the signers pretty much only make sense with descriptors, so I could remove it |
|
I agree that PSBT signing is out of scope ... if only because it is so simple. As Sanket says, you just compute the sighash (which rust-bitcoin has functionality for), produce a signature (i.e. call As for implementing |
|
Some more thoughts:
|
|
Regarding my comment in 93 about "using |
src/miniscript/context.rs
Outdated
| fn sighash( | ||
| psbt: &psbt::PartiallySignedTransaction, | ||
| input_index: usize, | ||
| ) -> Result<(SigHash, SigHashType), SignerError>; |
There was a problem hiding this comment.
This is a cool idea, putting this into ScriptContext. I think it should be changed though as
fn sighash(tx: &bitcoin::Transaction, input_index: usize, sighash_type: SigHashType) -> SigHash;
Then the function is more generic than just PSBT, and also it can't fail.
There was a problem hiding this comment.
The existing functionality I think is still worth including in the library, but as a standalone function which takes a PSBT and input index, does the appropriate lookups (which may fail) then calls ScriptContext::sighash to do the actual sighash computation.
|
The reason why I kinda liked the idea of connecting the signing flow with the So here's what I'll try to do for this PR:
Hope I understood everything right, thanks for the feedback! |
|
Just so we are on the same page: Another thing I noticed is that we might want to add a |
|
That's a neat idea to generate only the actually-used signatures. Unfortunately it doesn't really fit into the workflows we imagined or the API of the If you wanted to do this, it is possible to do outside the library, by writing your own type that knows how to sign (I guess it would include a sighash or means to compute this) and implementing Everything else you say @afilini sounds good to me! @sgeisler that does sound like the right method signature. |
|
@sgeisler regarding a |
|
Even I don't know why but there is an Also, the current implementation of PSBT finalizer is incomplete. I hope to have PR for it tomorrow. |
b6bd9aa to
10728dd
Compare
|
@afilini what do you think about extending xpub/xpriv derivation paths with arbitrary tweaks, which can be useful for situations like in RGB? |
|
It's probably out of scope in my opinion, considering that you can very easily define your own |
b016f4e to
dc4e0b5
Compare
|
I think I will have some time this weekend to come back to this and finish it up. I think most of the code is already there, it needs cleanup and docs. I was also planning to add commit d9fa945 from @sgeisler in this branch since I think it could be useful. The only thing that's missing with the "refactoring" I've done is the sighash computation part, which I was trying to rewrite as suggested to take a transaction instead of a PSBT, but for whatever reason I got kinda stuck (IIRC the interface was awful and I couldn't figure out a way to improve it) and never ended up finishing it. But since this PR doesn't do signing anymore maybe we could also go ahead without sighash and open a separate PR if we really want it. The only thing (other than me rebasing and finishing the code) that could block merging this PR is the fact that it needs a git version of rust-bitcoin, since I don't think there has been a release yet since the required changes have been merged. I don't know the release schedule of rust-bitcoin, but I think it's been a while since the last release, so hopefully that's coming soon. As a side note, I've been using this branch in some of my projects for the past few weeks and I don't think I've noticed any particular issue/regression with it, which is nice I guess. |
Yeah, @sanket1729 has been doing some PSBT stuff related to sighash too lately if i'm not mistaking.
It has just been bumped, and my cleaned up / improved version of #93 is rebased on top of #130 can be found here https://github.com/darosior/rust-miniscript/commits/descriptor_publickey (currently WIP, need some more tests squashed and raw pubkey with origin implementation: working on it locally). |
c6862fe to
f1061c3
Compare
37a88b3 to
807d99c
Compare
sanket1729
left a comment
There was a problem hiding this comment.
Left some minor nits. It would be great if we can use Keysource from bitcoin 0.25 wherever possible.
src/descriptor/mod.rs
Outdated
|
|
||
| #[derive(Debug)] | ||
| pub struct DescriptorSinglePriv { | ||
| pub origin: Option<(bip32::Fingerprint, bip32::DerivationPath)>, |
There was a problem hiding this comment.
If you rebase to latest master which has rust-bitcoin 0.25 we can use
type KeySource = (Fingerprint, DerivationPath)
src/descriptor/mod.rs
Outdated
| .expect("Translation fn can't fail.") | ||
| } | ||
|
|
||
| pub fn parse_secret(s: &str) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap), Error> { |
There was a problem hiding this comment.
Nit: Doccomment for a public API. More important for this one because of its return type.
There was a problem hiding this comment.
I think this should be renamed to parse_descriptor
There was a problem hiding this comment.
I'm still not thrilled but I can't think of anything better :). parse_descriptor_with_keymap is probably too long for such an important function.
In any case, I'm not going to hold up the PR for this.
There was a problem hiding this comment.
Yeah it sounds a bit weird to me as well, but I also don't have any better ideas unfortunately..
e01b6c6 to
2ba85b9
Compare
|
Just rebased this on master, it's ready to be reviewed :) |
src/descriptor/mod.rs
Outdated
|
|
||
| impl InnerXKey for bip32::ExtendedPrivKey { | ||
| fn xkey_fingerprint(&self) -> bip32::Fingerprint { | ||
| self.fingerprint(&secp256k1::Secp256k1::signing_only()) |
There was a problem hiding this comment.
☠️ we definitely should not be creating a one-off secp context for this
src/descriptor/mod.rs
Outdated
| /// # } | ||
| /// # body().unwrap() | ||
| /// ``` | ||
| pub fn matches(&self, keysource: &bip32::KeySource) -> Option<bip32::DerivationPath> { |
There was a problem hiding this comment.
I think most all of the clones in this function can be avoided
There was a problem hiding this comment.
Ah, not the ones in the assignment to path_excluding_wildcard, since that result gets returned and needs to be owned.
src/descriptor/mod.rs
Outdated
| } | ||
|
|
||
| impl DescriptorSecretKey { | ||
| pub fn as_public(&self) -> Result<DescriptorPublicKey, DescriptorKeyParseError> { |
There was a problem hiding this comment.
Needs a doccomment, and should mention that it will drop some of the derivation path if this involves hardened derivations. (Maybe it should be renamed to reflect this, but I'm not sure what a better name would be.)
There was a problem hiding this comment.
Can you rebase so that the doccomment was there originally? Otherwise the individual commits do not compile.
You can check whether the commits compile by running git rebase -x 'cargo test && cargo +1.29.0 test' master on your branch.
There was a problem hiding this comment.
It should be good now..
| Ok((descriptor, keymap_pk)) | ||
| } | ||
|
|
||
| pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String { |
There was a problem hiding this comment.
This could also be done with far fewer allocations, but we can leave it to a followup PR
2ba85b9 to
f7e992e
Compare
|
Thanks, sorry it took me a while to fix this! I think most of the comments should have been addressed: everything public is now documented and I removed pretty much all the ephemeral secp contexts except for one in Other than that, I don't think I see what you mean with your comment on |
|
What I was thinking with then impl Unfortunately you still have to translate the input descriptor to a descriptor which uses this weird type as keys, so you can't avoid the allocations inherent in that. |
95d826c to
4a1e94c
Compare
|
Lol, I meant "audit" not "allocate" |
I'm opening this right PR now mostly to gather feedback, since many things are still missing and need a lot of polishing.
This PR builds on top of #93 (here's the diff with it), so it incorporates the
DescriptorKeyconcept from @sgeisler and extends it to also support parsing of secrets (WIF or xprv) in Descriptors.It implements pretty much what @apoelstra described in #93, which is having a way to parse a descriptor with secrets, but immediately separate them out and store them in a map, and only have public types in the descriptor. This is achieved with the
SplitSecrettrait that can be implemented on types that areMiniscriptKeythat may contain secrets, and it adds a methodsplit_secret()that when called returns a tuple of, roughly speaking,(PublicType, Option<SecretType>).This PR also adds the
Signertrait which at the moment is very simple but again, I wanted to hear some feedback on how to move forward with it, and especially how to make it interact in a nice way with theSatisfiertrait.Also, I don't particularly like the name I chose for some structs, like
DescriptorKeyWithSecretsorDescriptorAndSignersso if you have better ideas I'd love to hear them!