-
Notifications
You must be signed in to change notification settings - Fork 153
Multipath descriptors #470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multipath descriptors #470
Conversation
I briefly looked at the code and I like the overall approach for the given BIP. Overall, a strong concept and approach ACK. Just two things:
On another note, I don't like the BIP changes in |
I very much agree. This is the feedback i gave to Achow when implementing this. I was kinda waiting for an answer from him about this, but looks like it won't come. I'll address your feedback. |
a45f320
to
f18d792
Compare
Implemented your suggestions and removed the WIP label from this PR. Having a
Rather returning |
/// Whether or not this key has multiple derivation paths. | ||
pub fn is_multipath(&self) -> bool { | ||
match *self { | ||
DescriptorSecretKey::Single(..) | DescriptorSecretKey::XPrv(..) => false, | ||
DescriptorSecretKey::MultiXPrv(_) => true, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems redundant with MiniscriptKey
's num_der_paths
introduced later on, but i kept it here in order to also have it for private keys.
f18d792
to
99bc84a
Compare
It didn't need to be a method of an extended public key, especially not since non-extended keys can have an origin too.
It's not specific to extended keys.
We'll need it for extended keys with multipath.
…cing This is prep work for the multipath keys, for which another ConversionError variant can occur. It's also cleaner on its own as returning a ConversionError is what we do in other places where we might fail on a conversion.
99bc84a
to
9b0d761
Compare
Rebased on master following the recent merges for the 8.0.0 release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've integrated this in my downstream project. I found a bug for which i'm pushing the fix and a unit test triggering it. Aside from this bug i've successfully used it and by doing so cross-checked it against the Python implementation i'm using in the functional testing framework of my software (darosior/python-bip380#21).
src/descriptor/key.rs
Outdated
} | ||
write!(f, ">")?; | ||
} | ||
write!(f, "/{}", child)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be in the else clause. And that should be caught by a unit test!
I'm adding roundtrip unit tests that fail without the patch for this bug.
7d756f2
to
d64e83f
Compare
Got a spurious io issue on the CPP tests:
Force-pushing to trigger a re-run. |
d64e83f
to
6d7864e
Compare
117171f commands: use a separate key chain for change addresses (Antoine Poinsot) d9f905a db: track the next unused derivation index for change, too (Antoine Poinsot) 58a0e57 db: record whether a coin was received on a change address (Antoine Poinsot) 9b04a55 db: store derivation index also for addresses from the change desc (Antoine Poinsot) 4f3daa7 descriptors: cache the receive and change descriptors (Antoine Poinsot) ca3d7c1 descriptors: introduce a newtype for the multipath descriptor (Antoine Poinsot) 1320ee3 daemon: use multipath descriptors (Antoine Poinsot) d4db804 qa: add a missing 'wait_for' in spend creation test (Antoine Poinsot) 7a18c58 bitcoind: filter received coins based on parent descriptors (Antoine Poinsot) ba4c1e0 bitcoind: include change outputs in listsinceblock (Antoine Poinsot) caaca1f descriptors: rename derive into derive_received (Antoine Poinsot) f985fd7 descriptors: remove as_inner method (Antoine Poinsot) 846d924 qa: upgrade python-bip380 to latest master (Antoine Poinsot) 3105b86 Use my own fork of rust-miniscript (Antoine Poinsot) Pull request description: This fixes #18 by implementing the de-facto standard of using a `/0/*` keychain for receiving addresses and a `/1/*` keychain for change addresses. Note that once we'll have multisig, reusing addresses will still be possible since wallet don't share the same "next derivation index". In order to avoid forcing the user to configure and backup two almost identical descriptors, we make use of the recently proposed BIP389 (bitcoin/bips#1354). In order to prevent as much as possible introducing a backward incompatibility in the configuration file after the first release, we restrict the usage of multipath descriptors to `<0;1>` here. We now derive public keys from `xpub/0/*` and `xpub/1/*` while we were previously deriving them from `xpub/*`. This triggered a pretty invasive refactoring, as most parts of the codebase had to be updated to support the new change/receive separation (even the functional test miniscript dependency had to be updated, see darosior/python-bip380#21). Broadly, this: 1. Update our Miniscript dependency to my upstream PR (rust-bitcoin/rust-miniscript#470) rebased on top of the 8.0.0 release. 2. Updates the descriptors module to handle somewhat safely the multipath descriptors (to avoid mixing up the single, multi, and derived descriptors). 3. Makes a multipath descriptor mandatory in the configuration file. 4. Updates the Bitcoin backend poller aware of descriptors for which to track coins. - Necessarily this updates the bitcoind implementation to import two descriptors 5. Record in database whether a coin was for the change or receive descriptor, in addition to its derivation index ACKs for top commit: edouardparis: ACK 117171f Tree-SHA512: efcb7267f1ba6a5a3072e96fd1c70272f81092e86ee1178833f83d0aa88f271f42c269b71ca9992e76bb3e103baf1a189a609cc20f14f29b7388ab133da99044
6d7864e
to
a63d5a2
Compare
I hadn't noticed the |
Friendly ping to know when you'll be able to review this, or if you think it is blocked by something? |
@darosior, this is on my list for this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done reviewing a63d5a2. Just Left a couple of comments. The rest of it is good to go. I have some other changes in mind to come in the future that would clean up the translatePk trait so which would make it impossible to create Miniscripts with different multi-path lengths even after translating.
Right now, it would fall upon the user to explicitly call the mismatching API to make sure that the translation is done correctly.
/// Whether this descriptor is a multipath descriptor that contains any 2 multipath keys | ||
/// with a different number of derivation paths. | ||
/// Such a descriptor is invalid according to BIP389. | ||
pub fn multipath_length_mismatch(&self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a review comment. Nothing to be addressed here. Ideally, we want to make sure that such invalid descriptors cannot be created in the first place. Adding this pub might confuse users to call it to double-check everything.
I think this is true for all APIs that deal with Miniscript, but not for the internal Terminal
. I have some changes in mind in future PRs to remove all the confusing sanity_check/check APIs.
This makes it possible to get multiple descriptors out of a multipath descriptor, and test the parsing and detection of multipath descriptors.
…ltipath keys This is invalid by BIP389 (as combinations would blowup when getting single descriptors otherwise). We add a num_der_paths method to MiniscriptKey in order to be able to check for this at parsing time without specializing from_str for Descriptor<DescriptorPublicKey>.
a63d5a2
to
ae0f3d9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK ae0f3d9.
This also updates the multipaths descriptor patch to the review PR rust-bitcoin/rust-miniscript#470 (rebased on 0.9)
3224f08 daemon: update rust-miniscript to 0.9 (Antoine Poinsot) Pull request description: This also updates the multipaths descriptor patch to the review PR rust-bitcoin/rust-miniscript#470 (rebased on 0.9) Fixes #123. ACKs for top commit: darosior: self-ACK 3224f08 -- trivial. Tree-SHA512: 03c8b181e96df8d73953cefadfbb090049859f01e6c8d03cf8417ad4d46795dc295b097f8df6c0f683fb9da03b78f39e824cb7768376d1d5718bdce177edcb6d
@apoelstra, any thoughts on merging this? This is not a merged BIP yet and could be changed. But so are many things in this repo that are not even BIP yet. |
Yeah, let's go for it. I took a quick look at the code and it looks good to me. |
This implements BIP389 multipath descriptors. Fixes #469.