Browse Source

[0.13] Create a new HD seed after encrypting the wallet

0.13
Jonas Schnelli 9 years ago
parent
commit
f142c11ac6
No known key found for this signature in database
GPG Key ID: 29D4BCB6416F53EC
  1. 2
      doc/release-notes.md
  2. 10
      qa/rpc-tests/keypool.py
  3. 2
      src/wallet/rpcwallet.cpp
  4. 9
      src/wallet/wallet.cpp

2
doc/release-notes.md

@ -135,6 +135,8 @@ Existing wallets will still use traditional key generation.
Backups of HD wallets, regardless of when they have been created, can Backups of HD wallets, regardless of when they have been created, can
therefore be used to re-generate all possible private keys, even the therefore be used to re-generate all possible private keys, even the
ones which haven't already been generated during the time of the backup. ones which haven't already been generated during the time of the backup.
**Attention:** Encrypting the wallet will create a new seed which requires
a new backup!
HD key generation for new wallets can be disabled by `-usehd=0`. Keep in HD key generation for new wallets can be disabled by `-usehd=0`. Keep in
mind that this flag only has affect on newly created wallets. mind that this flag only has affect on newly created wallets.

10
qa/rpc-tests/keypool.py

@ -12,6 +12,11 @@ class KeyPoolTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
nodes = self.nodes nodes = self.nodes
addr_before_encrypting = nodes[0].getnewaddress()
addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting)
wallet_info_old = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['masterkeyid'])
# Encrypt wallet and wait to terminate # Encrypt wallet and wait to terminate
nodes[0].encryptwallet('test') nodes[0].encryptwallet('test')
bitcoind_processes[0].wait() bitcoind_processes[0].wait()
@ -19,6 +24,11 @@ class KeyPoolTest(BitcoinTestFramework):
nodes[0] = start_node(0, self.options.tmpdir) nodes[0] = start_node(0, self.options.tmpdir)
# Keep creating keys # Keep creating keys
addr = nodes[0].getnewaddress() addr = nodes[0].getnewaddress()
addr_data = nodes[0].validateaddress(addr)
wallet_info = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['masterkeyid'])
assert(addr_data['hdmasterkeyid'] == wallet_info['masterkeyid'])
try: try:
addr = nodes[0].getnewaddress() addr = nodes[0].getnewaddress()
raise AssertionError('Keypool should be exhausted after one address') raise AssertionError('Keypool should be exhausted after one address')

2
src/wallet/rpcwallet.cpp

@ -2081,7 +2081,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp)
// slack space in .dat files; that is bad if the old data is // slack space in .dat files; that is bad if the old data is
// unencrypted private keys. So: // unencrypted private keys. So:
StartShutdown(); StartShutdown();
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
} }
UniValue lockunspent(const UniValue& params, bool fHelp) UniValue lockunspent(const UniValue& params, bool fHelp)

9
src/wallet/wallet.cpp

@ -626,6 +626,15 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
Lock(); Lock();
Unlock(strWalletPassphrase); Unlock(strWalletPassphrase);
// if we are using HD, replace the HD master key with a new one
if (!hdChain.masterKeyID.IsNull()) {
CKey key;
key.MakeNewKey(true);
if (!SetHDMasterKey(key))
return false;
}
NewKeyPool(); NewKeyPool();
Lock(); Lock();

Loading…
Cancel
Save