-
Notifications
You must be signed in to change notification settings - Fork 38.7k
[0.13] Create a new HD seed after encrypting the wallet #8389
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
Conversation
src/wallet/rpcwallet.cpp
Outdated
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.
Maybe the code should just check if HD is being used?
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 have though about that but I think it's not worth adding another check here.
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 don't think that's worth it either, just for the message
|
Will this destroy the old HD seed? Seems like it'd be valuable to keep it around somewhere... |
|
@jonasschnelli Could you open this against master, please? (The backport can be done after merge and discussion/nits etc.) |
|
@luke-jr The old HD seed is still available over dumpwallet. You can get the CKeyID from the used masterkey when calling |
qa/rpc-tests/keypool.py
Outdated
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.
Nit: please_use_lowercase_and_underscore
f2a14f8 to
5a2b0a9
Compare
|
Fixed the nits. |
|
So this makes it impossible to encrypt a seed which is already in use and is planned to be used in the future, but I guess for 0.13 this is fair enough. Concept ACK |
src/wallet/wallet.cpp
Outdated
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.
SetHDMasterKey() can only return true. When it fails it throws an exception. Do we need to catch that exception?
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.
Agree that it is confusing to have bool SomeFunction(), where the return value indicates if something bad happens but at the same time this is unused and exceptions are thrown. This should be made consistent.
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 this solution is fine for the moment. The return value of SetHDMasterKey() is for future extensions and I think its useful even if its not possible to get a false returned with the current implementation.
The exception will already be caught though the RPC/Server logic (EncryptWallet() will only be called in the RPC context where we "handle" exceptions).
|
@jonasschnelli Does BDB guarantee the order in which keys are iterated? If not then this isn't guaranteed to work. |
|
@jonasschnelli Indeed you're going to need to use the key metadata timestamp to select which hdchain to use. |
|
@pstratem It reads to me as if the old This WriteHDChain() function is used each time a new address is generated: The original chain could be stored under a different database key if we need to keep it around somewhere. |
|
@dooglus indeed you're right... I'm not sure that is any better certainly the old hd seed needs to be saved, possibly just with a prefix to make it not conflict or be used. |
|
@pstratem: CWalletDB and BDB is a key value storage as far as I know. Writing the same key at later stage should replace the current value. It may be possible to have the old K/V still stored in the database, though, CWalletDB/BDB needs to make sure the later write operation will result in the laster read/mem-map operation during load wallet. But I agree we need to keep track of the older/replaced seed. Maybe we should add something to the CKeyMetadata in that case (or at least CAddressBook). |
|
Pushed a commit that...
https://github.com/bitcoin/bitcoin/pull/8206/files would make use of this. It would show old/rewritten master keys in the dumped wallet. |
src/wallet/wallet.h
Outdated
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.
nit: argument is never used anywhere, but I could see this being useful in future
0242ea4 to
f162e7a
Compare
src/wallet/wallet.cpp
Outdated
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 this error detection case is extremely unlikely and probably on the same level then an exception during NewKeyPool().
I don't see a better way of handling this case.
|
Fixed @instagibbs nits. |
|
@jonasschnelli needs to be one commit |
|
Is this only aimed at 0.13 on purpose? |
|
No. I should have opened this PR against master. I'll open a PR against master as soon as this one is "final" (maybe it cleanly applies to master). |
|
|
|
utACK 77c912d |
f162e7a to
6165210
Compare
6165210 to
de45c06
Compare
|
Rebased (against 0.13). |
|
code-review ACK de45c06, going to test |
|
I did this: $ rm ~/.bitcoin/regtest/wallet.dat
$ src/bitcoind -regtest -rpcport=1234 -daemon -usehd=1
Bitcoin server starting
$ src/bitcoin-cli -regtest -rpcport=1234 dumpwallet "/tmp/dump_pre"
$ src/bitcoin-cli -regtest -rpcport=1234 encryptwallet "pass"
wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.
$ src/bitcoind -regtest -rpcport=1234 -daemon -usehd=1
Bitcoin server starting
$ src/bitcoin-cli -regtest -rpcport=1234 walletpassphrase "pass" 12345
$ src/bitcoin-cli -regtest -rpcport=1234 dumpwallet "/tmp/dump_post"
$ src/bitcoin-cli -regtest -rpcport=1234 stop
$ diff -du /tmp/dump_pre /tmp/dump_postLooks OK to me. The old reserve keys have been demoted to "change", and there are new reserve keys in the keypool. These keys are different, suggesting a new master key was used to generate them. The old master key was kept around as "oldhdmaster": -cSoMD7tEsoJNfSS3cL6N3E9gXpuQh7wgs79RDUBE6NjTEWS6Ptda 2016-07-28T10:48:28Z hdmaster=1 # addr=msqHNkZcD6ybT7xdCkquN4esLPLmoRyk8b hdkeypath=m
+cSoMD7tEsoJNfSS3cL6N3E9gXpuQh7wgs79RDUBE6NjTEWS6Ptda 2016-07-28T10:48:28Z inactivehdmaster=1 # addr=msqHNkZcD6ybT7xdCkquN4esLPLmoRyk8b hdkeypath=mAnd a new one was added +cRrbkixFuTz1esCbJTz3QqNGyEcPjFCjVyHRTy1JDxKDbHYXn9Qd 2016-07-28T10:48:43Z hdmaster=1 # addr=n3phnt6MDc2xUvKXrf8iW6ZiwtL2i7Rusm hdkeypath=mThe single key that is automatically generated (with empty label) at initialization stayed the same cRj4c74AFYdH9W1vbM3UgnaCeGbwztu3qb11NgDReiudtS2Q1ZAr 2016-07-28T10:48:28Z label= # addr=mwR8SR9sfKk7Q8z99xpdcCUNtccq81iRup hdkeypath=m/0'/0'/0'For the new reserve keys it starts counting again at +cNRrj6BtSxcXySqU6WgWgGEHMARifd1VXCVECdsXx4ervHE7iS4t 2016-07-28T10:48:43Z reserve=1 # addr=moBwgfzRf8H4ZjweCbQcckuJbMC16jwtD1 hdkeypath=m/0'/0'/0'I think everything is as expected. Tested ACK. |
|
Removed "needs backport" |
|
|
||
| // if we are using HD, replace the HD master key (seed) with a new one | ||
| if (!hdChain.masterKeyID.IsNull()) { | ||
| CKey key; |
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.
Unused variable.
Reported by @dooglus.
Fixes #8383