-
Notifications
You must be signed in to change notification settings - Fork 314
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
[keys] Improve the API of DerivableKey
#274
[keys] Improve the API of DerivableKey
#274
Conversation
ff60904
to
6a4b7bb
Compare
This looks like a nice improvement, I'll take a stab at fixing the tests and updating #272 . |
Is there a proper way to suggest a commit for a PR? Anyway I created notmandatory@65ba408 in my repo from a clone of your PR branch. It fixes the unit tests that are failing with I also changed the default network to |
I don't think you can suggest an entire commit but you can suggest changes when adding comments to the code, and GitHub gives you an option to then commit those changes directly (though I don't really like it because making commits from the web UI means that they sign it with their GPG key)
Yeah this shouldn't really matter, because we have our own way of keeping track of which networks are valid for a key.. we just need something there as a "placeholder", but all our traits like And actually that was the bug that was making my tests fail: I forgot to make a custom implementation for Lines 55 to 62 in 6a4b7bb
So the fix in this case would be to add the same code to the other BIP39 types as well, but I don't like how verbose it gets. I'll try to see if I can improve this with some Rust magic, and also try to document it better |
6a4b7bb
to
9618dd1
Compare
src/keys/mod.rs
Outdated
)? | ||
.into_extended_key()?; | ||
let xprv = xkey.into_xprv(Network::Bitcoin).unwrap(); | ||
# Ok(()) } |
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.
need to add ``` between line 476 and 477
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 was getting errors when adding that so I assumed they were being added automatically. I tried building the docs locally and the code snippet was looking good.
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.
With 1.48.0
tool chain this test also passed for me. But I was only able to get the doc tests to work with 1.49.0
if I added the first ``` on the same line as the opening r##" and then didn't seem to matter where i put the closing ``` as long as it was before the closing "##
Can you verify your default toolchain is stable 1.49.0
?
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.
Ah yeah, it looks like I was also using 1.48
locally
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.
Getting these errors on 1.49.0
:
failures:
---- src/keys/mod.rs - keys::DerivableKey::into_extended_key (line 461) stdout ----
error: unknown start of token: `
--> src/keys/mod.rs:475:5
|
16 | ```
| ^
|
help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
|
16 | '``
| ^
error: unknown start of token: `
--> src/keys/mod.rs:475:6
|
16 | ```
| ^
|
help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
|
16 | `'`
| ^
error: unknown start of token: `
--> src/keys/mod.rs:475:7
|
16 | ```
| ^
|
help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
|
16 | ``'
| ^
error: aborting due to 3 previous errors
Couldn't compile the test.
failures:
src/keys/mod.rs - keys::DerivableKey::into_extended_key (line 461)
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.
Ah okay, the solution is to remove the tab before every line. I think it considers it code if there's a tab before the line
A new `ExtendedKey` type has been added, which is basically an enum of `bip32::ExtendedPubKey` and `bip32::ExtendedPrivKey`, with some extra metadata regarding the `ScriptContext`. This type has some methods that make it very easy to extract its content as either an `xprv` or `xpub`. The `DerivableKey` trait has been updated so that the user now only has to implement a method (`DerivableKey::into_extended_key()`) to perform the conversion into an `ExtendedKey`. The method that was previously called `add_metadata()` has now been renamed to `into_descriptor_key()`, and it has a blanket implementation.
9618dd1
to
ccbbad3
Compare
I noticed while trying to handle error results for I don't see a way to make this better in I also think the |
ACK ccbbad3 I verified docs and |
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.
Networks (mainnet etc) are fast becoming one of my least liked parts of cryptocurrency software, code that deals with them is almost always contrived. It would be nice to improve this valid network stuff at some stage if we can ...
let (mnemonic, passphrase) = self; | ||
let seed = Seed::new(&mnemonic, passphrase.as_deref().unwrap_or("")); |
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.
let (mnemonic, passphrase) = self; | |
let seed = Seed::new(&mnemonic, passphrase.as_deref().unwrap_or("")); | |
let (mnemonic, passphrase) = self; | |
let passphrase = passphrase.unwrap_or_default(); | |
let seed = Seed::new(&mnemonic, &passphrase); |
self, | ||
source: Option<bip32::KeySource>, | ||
derivation_path: bip32::DerivationPath, | ||
) -> Result<DescriptorKey<Ctx>, KeyError> { | ||
let (mnemonic, passphrase) = self; | ||
let seed = Seed::new(&mnemonic, passphrase.as_deref().unwrap_or("")); |
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.
Same as above if you like the suggestion.
match self { | ||
ExtendedKey::Private(_) => true, | ||
ExtendedKey::Public(_) => false, | ||
} |
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.
Might be slightly nicer to use matches!
, depending on your point of view.
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.
Networks (mainnet etc) are fast becoming one of my least liked parts of cryptocurrency software, code that deals with them is almost always contrived. It would be nice to improve this valid network stuff at some stage if we can ...
Do you mean you'd like to avoid validating against specific blockchains such as Bitcoin or just make it easier to expand the possibly instances of the Bitcoin blockchain such as to support new custom signet networks?
I do agree it would be nice to be able to easily use a custom genesis block for testing against custom signet networks which core and some other projects are beginning to use.
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.
Do you mean you'd like to avoid validating against specific blockchains such as Bitcoin or just make it easier to expand the possibly instances of the Bitcoin blockchain such as to support new custom signet networks?
I'm not well versed enough in the bdk codebase to be making any claims at the moment :) I was merely commenting that including the network in code seems to always lead to contrived code. My personal opinion is that software shouldn't care or know which network it is attached too. If the point of testnets is to test the code then there should be no difference in the code irrespective of the network, if the code is different depending on the network then we are not testing the same code that would run when connected to mainnet. I'm only 18 months deep in cryptocurrency software so don't put too much weight in my opinions but this came up last week in my day job too (and it happened in my last job too) so when I saw it again so soon in bdk I felt like commenting :)
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 think the main point against reusing the same encoding for everything is to make sure users don't accidentally mix up addresses/keys/etc.
One thing I'd like to have is an extended key format that has a set of valid networks, or at least doesn't include one at all: most of the "hacks" we have to do in BDK come from the fact that the "base type" we reduce everything to is ExtendedPrivKey
(or ExtendedPubKey
) and they both contain a single network.
So when you take a different key type, like a mnemonic, and try to convert it to the "base type" you are forced to pick one single network, which means that you have to use a random one as a placeholder but also remember that the original key type didn't encode any network information, so while the key inside says that it's i.e. a Testnet
key, it should also be considered valid on Mainnet
.
Also it doesn't help that different key formats encode different information inside: some don't encode anything at all, just the key, (BIP39), some encode the network but not the type of script (xprv
/tprv
), others include whether the script is legacy or segwit as well (Electrum mnemonics).
Description
A new
ExtendedKey
type has been added, which is basically an enum ofbip32::ExtendedPubKey
andbip32::ExtendedPrivKey
, with some extra metadata regarding theScriptContext
.This type has some methods that make it very easy to extract its content as either an
xprv
orxpub
.The
DerivableKey
trait has been updated so that the user now only has to implement a method (DerivableKey::into_extended_key()
) to perform the conversion into anExtendedKey
.The method that was previously called
add_metadata()
has now been renamed tointo_descriptor_key()
, and it has a blanket implementation.Checklists
All Submissions:
cargo fmt
andcargo clippy
before committingNew Features:
CHANGELOG.md
Bugfixes: