aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schnelli <dev@jonasschnelli.ch>2016-07-22 11:03:30 +0200
committerJonas Schnelli <dev@jonasschnelli.ch>2016-07-27 16:02:41 +0200
commitde45c065f0648c4c41b57cb492420ceeed29dd11 (patch)
treece1f43fe8bba2d118ea3b3ac00b69bb5dadcf58b
parentf142c11ac634df487cc4bc65a5f1c9a3e3563dd9 (diff)
downloadbitcoin-de45c065f0648c4c41b57cb492420ceeed29dd11.tar.xz
[Wallet] Add CKeyMetadata record for HDMasterKey(s), factor out HD key generation
-rwxr-xr-xqa/rpc-tests/keypool.py6
-rw-r--r--src/wallet/wallet.cpp49
-rw-r--r--src/wallet/wallet.h5
3 files changed, 43 insertions, 17 deletions
diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py
index 735b91ee9f..fa39476568 100755
--- a/qa/rpc-tests/keypool.py
+++ b/qa/rpc-tests/keypool.py
@@ -15,7 +15,7 @@ class KeyPoolTest(BitcoinTestFramework):
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'])
+ assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid'])
# Encrypt wallet and wait to terminate
nodes[0].encryptwallet('test')
@@ -26,8 +26,8 @@ class KeyPoolTest(BitcoinTestFramework):
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'])
+ assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
+ assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
try:
addr = nodes[0].getnewaddress()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index a1d9c4a598..e5ee5063a5 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -627,11 +627,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
Lock();
Unlock(strWalletPassphrase);
- // if we are using HD, replace the HD master key with a new one
+ // if we are using HD, replace the HD master key (seed) with a new one
if (!hdChain.masterKeyID.IsNull()) {
CKey key;
- key.MakeNewKey(true);
- if (!SetHDMasterKey(key))
+ CPubKey masterPubKey = GenerateNewHDMasterKey();
+ if (!SetHDMasterKey(masterPubKey))
return false;
}
@@ -1175,20 +1175,43 @@ CAmount CWallet::GetChange(const CTransaction& tx) const
return nChange;
}
-bool CWallet::SetHDMasterKey(const CKey& key)
+CPubKey CWallet::GenerateNewHDMasterKey()
+{
+ CKey key;
+ key.MakeNewKey(true);
+
+ int64_t nCreationTime = GetTime();
+ CKeyMetadata metadata(nCreationTime);
+
+ // calculate the pubkey
+ CPubKey pubkey = key.GetPubKey();
+ assert(key.VerifyPubKey(pubkey));
+
+ // set the hd keypath to "m" -> Master, refers the masterkeyid to itself
+ metadata.hdKeypath = "m";
+ metadata.hdMasterKeyID = pubkey.GetID();
+
+ {
+ LOCK(cs_wallet);
+
+ // mem store the metadata
+ mapKeyMetadata[pubkey.GetID()] = metadata;
+
+ // write the key&metadata to the database
+ if (!AddKeyPubKey(key, pubkey))
+ throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
+ }
+
+ return pubkey;
+}
+
+bool CWallet::SetHDMasterKey(const CPubKey& pubkey)
{
LOCK(cs_wallet);
// ensure this wallet.dat can only be opened by clients supporting HD
SetMinVersion(FEATURE_HD);
- // store the key as normal "key"/"ckey" object
- // in the database
- // key metadata is not required
- CPubKey pubkey = key.GetPubKey();
- if (!AddKeyPubKey(key, pubkey))
- throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
-
// store the keyid (hash160) together with
// the child index counter in the database
// as a hdchain object
@@ -3308,8 +3331,8 @@ bool CWallet::InitLoadWallet()
if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) {
// generate a new master key
CKey key;
- key.MakeNewKey(true);
- if (!walletInstance->SetHDMasterKey(key))
+ CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey();
+ if (!walletInstance->SetHDMasterKey(masterPubKey))
throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed");
}
CPubKey newDefaultKey;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index efed2ba11d..0c95fdf4b0 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -901,8 +901,11 @@ public:
bool SetHDChain(const CHDChain& chain, bool memonly);
const CHDChain& GetHDChain() { return hdChain; }
+ /* Generates a new HD master key (will not be activated) */
+ CPubKey GenerateNewHDMasterKey();
+
/* Set the current HD master key (will reset the chain child index counters) */
- bool SetHDMasterKey(const CKey& key);
+ bool SetHDMasterKey(const CPubKey& key);
};
/** A key allocated from the key pool. */