-
Notifications
You must be signed in to change notification settings - Fork 296
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
hdkeychain: Introduce v2 module. #1696
Conversation
An idea: also make the |
45db951
to
a368dbf
Compare
That seems like a good idea. It does mean the parameter should first be added to |
After discussing this with @jrick and considering it a bit more, changing the master key would actually break multi-currency wallets since the BIP defines the seed as a specific value and thus BIP44 implicitly relies on it. |
a368dbf
to
0c81833
Compare
Updated to account for renamed HD extended key accessor funcs in |
This serves as the final release of version 1 of the hdkeychain module. All future releases will be moving to version 2 of the module. Since there have been no changes since the last release version, this merely removes the hdkeychain override in the root module and updates it so building the software will still produce binaries based on the v1 module until the v2 module is fully released.
This corrects the master extended private key used in the benchmarks for Decred. This appears to have been missed when porting the code.
This corrects the serialized extended key examples in the package documentation. This appears to have been missed when porting the code.
Putting the test code in the same package makes it easier for forks since they don't have to change the import paths as much and makes it more consistent with the rest of the code base.
This removes the Address method from the ExtendedKey struct since ultimately there will be multiple address types and therefore it no longer makes sense to return an address which probably isn't the one the caller actually needs. Instead, the caller can make use of the ECPubKey method to obtain the public key and create the desired address from there. It also removes the related tests, updates the example to show the address conversion process for a standard pay-to-pubkey-hash address, and updates the README.md and doc.go files accordingly.
This removes the SetNet method from the ExtendedKey struct since its use in practice could lead to subtle bugs due to the fact that changing the network after keys have already been derived and then deriving more keys will not result in the same derivation as starting with the target network to begin with. It is better to simply avoid the possibility of misuse. It also removes the related tests.
This modifies the tests to use locals for the network parameter references to make it easier to mock the parameters in the future.
This modifies NewKeyFromString to accept the required network parameters for the provided encoded extended key and introduces a new error to indicate the provide extended key is for the wrong network. This means that NewKeyFromString will now return ErrWrongNetwork if the extended key being decoded is not for the provided network. This differs from the previous behavior relied on globally-registered networks in chaincfg to determine which network the encoded key was for followed by requiring the caller to check upon if the key was for the specific network it desired upon return. Finally, it removes the no longer necessary IsForNet method and updates the documentation accordingly.
This refactors the the extended key internals to keep track of the public and private network ids instead of a version slice in order to remove the need to rely on global state for looking up the extended public key ID for the network. Since the public and private network ids are 8 bytes and the version slice was 24 bytes, this also has the nice side effect of slightly optimizing the performance, particularly in the private to public case, as shown by the following benchmark comparison: benchmark old ns/op new ns/op delta -------------------------------------------------------- BenchmarkDeriveHardened 5795 5600 -3.36% BenchmarkDeriveNormal 6585 6263 -4.89% BenchmarkPrivToPub 137 118 -13.87% BenchmarkDeserialize 17618 17618 +0.00% BenchmarkSerialize 21672 21061 -2.82% benchmark old bytes new bytes delta -------------------------------------------------------- BenchmarkDeriveHardened 1552 1536 -1.03% BenchmarkDeriveNormal 1601 1585 -1.00% BenchmarkPrivToPub 128 112 -12.50% BenchmarkDeserialize 1640 1624 -0.98% BenchmarkSerialize 1712 1712 +0.00%
This introduces a new interface named NetworkParams and updates the functions that currently take a pointer to a chaincfg.Params struct to accept the interface instead. This removes the tight coupling between the two packages at the API boundary and allows callers to easily provide custom values without having to create and register and entire chaincfg network as previous required. Finally, the README.md is updated accordingly.
This implements a mock network params struct that implements the new interface and modifies the test code to make use of the mock params instead of chaincfg. This completely decouples the tests, with the exception of the example code, from chaincfg and therefore any updates to it such as introducing new test networks will not require changes to the tests.
This updates the docs/README.md file, module hierarchy graphviz, and module hierarchy diagram to reflect the new module version
0c81833
to
c1cf192
Compare
This is ready for final review and ready to be merged. |
NOTE: This currently contains a module replacement directive since it relies on an unreleased version of thechaincfg
module. It will need to be removed once the requisite modules is released before this can be merged. However, it is otherwise ready for review.The
hdkeychain
package currently has some less-than ideal APIs and behaviors that have been retained up to this point in order to avoid breaking existing caller code. However, now that versioned module support is available and in full use, these items can be addressed.A quick overview of the issues with
hdkeychain
this aims to address are:chaincfg
which are slated to be removed*chaincfg.Params
in its API funcs which tightly couples it to the specific version ofchaincfg
. The forces major version bumps of thehdkeychain
module when the major version ofchaincfg
is bumped even if nothing in it thathdkeychain
actually relies on changed.Address
only return addresses of a specific type and script version. Since there ultimately will be multiple address types and script versions, it no longer makes sense to return an address which probably isn't the one the caller actually needs. Instead, the caller can make use of theECPubKey
method to obtain the public key and create the desired address from there.SetNet
allows changing the network after keys have already been derived and then deriving more keys which will not result in the same derivation as starting with the target network to begin with. There is also no practical use for changing a network in the middle of a derivation or providing an extended key serialized for a network that the rest of the derivation does not apply to.NewKeyFromString
does not accept the network the serialized extended key is intended to be for and instead parses for any recognized network. This results in requiring the caller ensuring it is for the correct network via the separateIsForNet
which leads to to the next point. Instead,NewKeyFromString
should take the required network as a parameter and error if the serialized extended key is not for that network.IsForNet
is easy for a caller to forget which means it could lead to them inadvertently using keys for other networks.Consequently, this introduces
hdkeychain/v2
which addresses the aforementioned items. A series of individual commits to make the review process easier. Each commit message more thoroughly describes its purpose, but primarily they consist of the following:hdkeychain
modulehdkeychain
override so building the software will still produce binaries based on the v1 module until the v2 module is fully releasedAddress
SetNet
NewKeyFromString
to accept required network parameters and error in the case the provided serialized extended key does not correspond to the networkIsForNet
chaincfg
state which also leads to a slight optimization (benchmarks below)NetworkParams
interface that is limited specifically to the parameters needed and update all APIs that previously accepted*chaincfg.Params
to use the new interface instead.chaincfg
changesThe following is a before and after comparison of the allocations and performance as a side effect of the changes:
Finally, it should also be noted that this only introduces the new module and does not update anything to make use of it yet, so building the software will still produce binaries based on the v1 module.