diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -9,6 +9,13 @@ `true` with sub-fields `ancestor`, `base`, `modified` and `descendant` denominated in BCH. This new field deprecates previous fee fields, such a `fee`, `modifiedfee`, `ancestorfee` and `descendantfee`. + - `hdmasterkeyid` in `getwalletinfo` has been deprecated in favor of + `hdseedid`. `hdmasterkeyid` will be removed in V0.21. + - `hdmasterkeyid` in `getaddressinfo` has been deprecated in favor of + `hdseedid`. `hdmasterkeyid` will be removed in V0.21. + - The `inactivehdmaster` property in the `dumpwallet` output has been + deprecated in favor of `inactivehdseed`. `inactivehdmaster` will be removed + in V0.21. Dynamic creation of wallets --------------------------------------- diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -894,10 +894,10 @@ // add the base58check encoded extended master if the wallet uses HD CKeyID seed_id = pwallet->GetHDChain().seed_id; if (!seed_id.IsNull()) { - CKey key; - if (pwallet->GetKey(seed_id, key)) { + CKey seed; + if (pwallet->GetKey(seed_id, seed)) { CExtKey masterKey; - masterKey.SetSeed(key.begin(), key.size()); + masterKey.SetSeed(seed.begin(), seed.size()); file << "# extended private masterkey: " << EncodeExtKey(masterKey) << "\n\n"; @@ -920,8 +920,8 @@ file << "hdmaster=1"; } else if (mapKeyPool.count(keyid)) { file << "reserve=1"; - } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") { - file << "inactivehdmaster=1"; + } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "s") { + file << "inactivehdseed=1"; } else { file << "change=1"; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3277,9 +3277,11 @@ "fee configuration, set in " + CURRENCY_UNIT + "/kB\n" - " \"hdmasterkeyid\": \"\" (string, optional) the " - "Hash160 of the HD master pubkey (only present when HD is " - "enabled)\n" + " \"hdseedid\": \"\" (string, optional) the " + "Hash160 of the HD seed (only present when HD is enabled)\n" + " \"hdmasterkeyid\": \"\" (string, optional) alias " + "for hdseedid retained for backwards-compatibility. Will be " + "removed in V0.21.\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") + @@ -3315,6 +3317,7 @@ } obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK())); if (!seed_id.IsNull()) { + obj.pushKV("hdseedid", seed_id.GetHex()); obj.pushKV("hdmasterkeyid", seed_id.GetHex()); } return obj; @@ -4356,8 +4359,11 @@ "GMT)\n" " \"hdkeypath\" : \"keypath\" (string, optional) The HD " "keypath if the key is HD and available\n" - " \"hdmasterkeyid\" : \"\" (string, optional) The " - "Hash160 of the HD master pubkey\n" + " \"hdseedid\" : \"\" (string, optional) The " + "Hash160 of the HD seed\n" + " \"hdmasterkeyid\" : \"\" (string, optional) alias for " + "hdseedid maintained for backwards compatibility. Will be removed " + "in V0.21.\n" "}\n" "\nExamples:\n" + HelpExampleCli("getaddressinfo", @@ -4410,6 +4416,7 @@ ret.pushKV("timestamp", meta->nCreateTime); if (!meta->hdKeypath.empty()) { ret.pushKV("hdkeypath", meta->hdKeypath); + ret.pushKV("hdseedid", meta->hd_seed_id.GetHex()); ret.pushKV("hdmasterkeyid", meta->hd_seed_id.GetHex()); } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1293,19 +1293,19 @@ /* Returns true if HD is enabled */ bool IsHDEnabled() const; - /* Generates a new HD master key (will not be activated) */ + /* Generates a new HD seed (will not be activated) */ CPubKey GenerateNewSeed(); /** - * Derives a new HD master key (will not be activated) + * Derives a new HD seed (will not be activated) */ CPubKey DeriveNewSeed(const CKey &key); /** - * Set the current HD master key (will reset the chain child index counters) - * Sets the master key's version based on the current wallet version (so the + * Set the current HD seed (will reset the chain child index counters) + * Sets the seed's version based on the current wallet version (so the * caller must ensure the current wallet version is correct before calling - * this function). + * this function). */ void SetHDSeed(const CPubKey &key); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -194,8 +194,8 @@ void CWallet::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, bool internal) { // for now we use a fixed keypath scheme of m/0'/0'/k - // master key seed (256bit) - CKey key; + // seed (256bit) + CKey seed; // hd master key CExtKey masterKey; // key at m/0' @@ -205,13 +205,12 @@ // key at m/0'/0'/' CExtKey childKey; - // try to get the master key - if (!GetKey(hdChain.seed_id, key)) { - throw std::runtime_error(std::string(__func__) + - ": Master key not found"); + // try to get the seed + if (!GetKey(hdChain.seed_id, seed)) { + throw std::runtime_error(std::string(__func__) + ": seed not found"); } - masterKey.SetSeed(key.begin(), key.size()); + masterKey.SetSeed(seed.begin(), seed.size()); // derive m/0' // use hardened derivation (child keys >= 0x80000000 are hardened after @@ -779,7 +778,7 @@ Lock(); Unlock(strWalletPassphrase); - // If we are using HD, replace the HD master key (seed) with a new one. + // If we are using HD, replace the HD seed with a new one if (IsHDEnabled()) { SetHDSeed(GenerateNewSeed()); } @@ -1549,26 +1548,26 @@ int64_t nCreationTime = GetTime(); CKeyMetadata metadata(nCreationTime); - // Calculate the pubkey. - CPubKey pubkey = key.GetPubKey(); - assert(key.VerifyPubKey(pubkey)); + // Calculate the seed + CPubKey seed = key.GetPubKey(); + assert(key.VerifyPubKey(seed)); - // Set the hd keypath to "m" -> Master, refers the masterkeyid to itself. - metadata.hdKeypath = "m"; - metadata.hd_seed_id = pubkey.GetID(); + // Set the hd keypath to "s" -> Seed, refers the seed to itself + metadata.hdKeypath = "s"; + metadata.hd_seed_id = seed.GetID(); LOCK(cs_wallet); // mem store the metadata - mapKeyMetadata[pubkey.GetID()] = metadata; + mapKeyMetadata[seed.GetID()] = metadata; - // Write the key&metadata to the database. - if (!AddKeyPubKey(key, pubkey)) { + // Write the key&metadata to the database + if (!AddKeyPubKey(key, seed)) { throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed"); } - return pubkey; + return seed; } void CWallet::SetHDSeed(const CPubKey &seed) { @@ -4478,9 +4477,9 @@ } walletInstance->SetMinVersion(FEATURE_LATEST); - // Generate a new master key. - CPubKey masterPubKey = walletInstance->GenerateNewSeed(); - walletInstance->SetHDSeed(masterPubKey); + // Generate a new seed + CPubKey seed = walletInstance->GenerateNewSeed(); + walletInstance->SetHDSeed(seed); // Top up the keypool if (!walletInstance->TopUpKeyPool()) { diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -63,7 +63,7 @@ public: uint32_t nExternalChainCounter; uint32_t nInternalChainCounter; - //!< master key hash160 + //!< seed hash160 CKeyID seed_id; static const int VERSION_HD_BASE = 1; @@ -101,7 +101,7 @@ int64_t nCreateTime; // optional HD/bip32 keypath. std::string hdKeypath; - // Id of the HD masterkey used to derive this key. + // Id of the HD seed used to derive this key. CKeyID hd_seed_id; CKeyMetadata() { SetNull(); } diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -32,7 +32,7 @@ addr_keypath = comment.split(" addr=")[1] addr = addr_keypath.split(" ")[0] keypath = None - if keytype == "inactivehdmaster=1": + if keytype == "inactivehdseed=1": # ensure the old master is still available assert(hd_master_addr_old == addr) elif keytype == "hdmaster=1": diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -30,7 +30,9 @@ connect_nodes_bi(self.nodes[0], self.nodes[1]) # Make sure we use hd, keep masterkeyid - masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] + masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] + assert_equal(masterkeyid, self.nodes[1].getwalletinfo()[ + 'hdmasterkeyid']) assert_equal(len(masterkeyid), 40) # create an internal key @@ -57,6 +59,7 @@ hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].getaddressinfo(hd_add) assert_equal(hd_info["hdkeypath"], "m/0'/0'/" + str(i) + "'") + assert_equal(hd_info["hdseedid"], masterkeyid) assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) @@ -89,6 +92,7 @@ hd_add_2 = self.nodes[1].getnewaddress() hd_info_2 = self.nodes[1].getaddressinfo(hd_add_2) assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(i) + "'") + assert_equal(hd_info_2["hdseedid"], masterkeyid) assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) connect_nodes_bi(self.nodes[0], self.nodes[1]) diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -19,8 +19,10 @@ addr_before_encrypting_data = nodes[ 0].getaddressinfo(addr_before_encrypting) wallet_info_old = nodes[0].getwalletinfo() + assert_equal(wallet_info_old['hdseedid'], + wallet_info_old['hdmasterkeyid']) assert( - addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) + addr_before_encrypting_data['hdseedid'] == wallet_info_old['hdseedid']) # Encrypt wallet and wait to terminate nodes[0].node_encrypt_wallet('test') @@ -30,6 +32,7 @@ addr = nodes[0].getnewaddress() addr_data = nodes[0].getaddressinfo(addr) wallet_info = nodes[0].getwalletinfo() + assert_equal(wallet_info['hdseedid'], wallet_info['hdmasterkeyid']) assert( addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid']) assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])