diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -3,3 +3,6 @@ This release includes the following features and fixes: + +- The `getwalletinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.21. +- The `getaddressinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.21. diff --git a/src/key.h b/src/key.h --- a/src/key.h +++ b/src/key.h @@ -170,7 +170,7 @@ void Decode(const uint8_t code[BIP32_EXTKEY_SIZE]); bool Derive(CExtKey &out, unsigned int nChild) const; CExtPubKey Neuter() const; - void SetMaster(const uint8_t *seed, unsigned int nSeedLen); + void SetSeed(const uint8_t *seed, unsigned int nSeedLen); template void Serialize(Stream &s) const { unsigned int len = BIP32_EXTKEY_SIZE; ::WriteCompactSize(s, len); diff --git a/src/key.cpp b/src/key.cpp --- a/src/key.cpp +++ b/src/key.cpp @@ -339,7 +339,7 @@ return key.Derive(out.key, out.chaincode, _nChild, chaincode); } -void CExtKey::SetMaster(const uint8_t *seed, unsigned int nSeedLen) { +void CExtKey::SetSeed(const uint8_t *seed, unsigned int nSeedLen) { static const uint8_t hashkey[] = {'B', 'i', 't', 'c', 'o', 'i', 'n', ' ', 's', 'e', 'e', 'd'}; std::vector> vout(64); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -98,7 +98,7 @@ std::vector seed = ParseHex(test.strHexMaster); CExtKey key; CExtPubKey pubkey; - key.SetMaster(seed.data(), seed.size()); + key.SetSeed(seed.data(), seed.size()); pubkey = key.Neuter(); for (const TestDerivation &derive : test.vDerive) { uint8_t data[74]; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -892,12 +892,12 @@ file << "\n"; // add the base58check encoded extended master if the wallet uses HD - CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; - if (!masterKeyID.IsNull()) { + CKeyID seed_id = pwallet->GetHDChain().seed_id; + if (!seed_id.IsNull()) { CKey key; - if (pwallet->GetKey(masterKeyID, key)) { + if (pwallet->GetKey(seed_id, key)) { CExtKey masterKey; - masterKey.SetMaster(key.begin(), key.size()); + masterKey.SetSeed(key.begin(), key.size()); file << "# extended private masterkey: " << EncodeExtKey(masterKey) << "\n\n"; @@ -916,8 +916,8 @@ if (GetWalletAddressesForKey(config, pwallet, keyid, strAddr, strLabel)) { file << strprintf("label=%s", strLabel); - } else if (keyid == masterKeyID) { - file << "hdmaster=1"; + } else if (keyid == seed_id) { + file << "hdseed=1"; } else if (mapKeyPool.count(keyid)) { file << "reserve=1"; } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") { 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,8 @@ "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" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") + @@ -3305,8 +3304,8 @@ obj.pushKV("txcount", (int)pwallet->mapWallet.size()); obj.pushKV("keypoololdest", pwallet->GetOldestKeyPoolTime()); obj.pushKV("keypoolsize", (int64_t)kpExternalSize); - CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID; - if (!masterKeyID.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) { + CKeyID seed_id = pwallet->GetHDChain().seed_id; + if (!seed_id.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) { obj.pushKV("keypoolsize_hd_internal", int64_t(pwallet->GetKeyPoolSize() - kpExternalSize)); } @@ -3314,8 +3313,8 @@ obj.pushKV("unlocked_until", pwallet->nRelockTime); } obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK())); - if (!masterKeyID.IsNull()) { - obj.pushKV("hdmasterkeyid", masterKeyID.GetHex()); + if (!seed_id.IsNull()) { + obj.pushKV("hdseedid", seed_id.GetHex()); } return obj; } @@ -4288,7 +4287,7 @@ "about the address embedded in P2SH or P2WSH, if relevant and " "known. It includes all getaddressinfo output fields for the " "embedded address, excluding metadata (\"timestamp\", " - "\"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet " + "\"hdkeypath\", \"hdseedid\") and relation to the wallet " "(\"ismine\", \"iswatchonly\", \"account\").\n" " \"iscompressed\" : true|false, (boolean) If the address is " "compressed\n" @@ -4299,7 +4298,7 @@ "GMT)\n" " \"hdkeypath\" : \"keypath\" (string, optional) The HD " "keypath if the key is HD and available\n" - " \"hdmasterkeyid\" : \"\" (string, optional) The " + " \"hdseedid\" : \"\" (string, optional) The " "Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + @@ -4353,7 +4352,7 @@ ret.pushKV("timestamp", meta->nCreateTime); if (!meta->hdKeypath.empty()) { ret.pushKV("hdkeypath", meta->hdKeypath); - ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex()); + ret.pushKV("hdseedid", meta->hd_seed_id.GetHex()); } } return ret; @@ -4394,7 +4393,7 @@ "used.\n" " The seed value can be retrieved " "using the dumpwallet command. It is the private key marked " - "hdmaster=1\n" + "hdseed=1\n" "\nExamples:\n" + HelpExampleCli("sethdseed", "") + HelpExampleCli("sethdseed", "false") + @@ -4427,7 +4426,7 @@ CPubKey master_pub_key; if (request.params[1].isNull()) { - master_pub_key = pwallet->GenerateNewHDMasterKey(); + master_pub_key = pwallet->GenerateNewSeed(); } else { CKey key = DecodeSecret(request.params[1].get_str()); if (!key.IsValid()) { @@ -4441,12 +4440,12 @@ "as a loose private key)"); } - master_pub_key = pwallet->DeriveNewMasterHDKey(key); + master_pub_key = pwallet->DeriveNewSeed(key); } - pwallet->SetHDMasterKey(master_pub_key); + pwallet->SetHDSeed(master_pub_key); if (flush_key_pool) { - pwallet->NewKeyPool(); + pwallet->NewKeyPool(); } return NullUniValue; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1279,10 +1279,10 @@ bool IsHDEnabled() const; /* Generates a new HD master key (will not be activated) */ - CPubKey GenerateNewHDMasterKey(); + CPubKey GenerateNewSeed(); /* Derives a new HD master key (will not be activated) */ - CPubKey DeriveNewMasterHDKey(const CKey &key); + CPubKey DeriveNewSeed(const CKey &key); /** * Set the current HD master key (will reset the chain child index counters) @@ -1290,7 +1290,7 @@ * caller must ensure the current wallet version is correct before calling * this function). */ - bool SetHDMasterKey(const CPubKey &key); + bool SetHDSeed(const CPubKey &key); /** * Blocks until the wallet state is up-to-date to /at least/ the current diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -206,12 +206,12 @@ CExtKey childKey; // try to get the master key - if (!GetKey(hdChain.masterKeyID, key)) { + if (!GetKey(hdChain.seed_id, key)) { throw std::runtime_error(std::string(__func__) + ": Master key not found"); } - masterKey.SetMaster(key.begin(), key.size()); + masterKey.SetSeed(key.begin(), key.size()); // derive m/0' // use hardened derivation (child keys >= 0x80000000 are hardened after @@ -246,7 +246,7 @@ } } while (HaveKey(childKey.key.GetPubKey().GetID())); secret = childKey.key; - metadata.hdMasterKeyID = hdChain.masterKeyID; + metadata.hd_seed_id = hdChain.seed_id; // update the chain model in the database if (!batch.WriteHDChain(hdChain)) { throw std::runtime_error(std::string(__func__) + @@ -785,7 +785,7 @@ // If we are using HD, replace the HD master key (seed) with a new one. if (IsHDEnabled()) { - if (!SetHDMasterKey(GenerateNewHDMasterKey())) { + if (!SetHDSeed(GenerateNewSeed())) { return false; } } @@ -1547,13 +1547,13 @@ return nChange; } -CPubKey CWallet::GenerateNewHDMasterKey() { +CPubKey CWallet::GenerateNewSeed() { CKey key; key.MakeNewKey(true); - return DeriveNewMasterHDKey(key); + return DeriveNewSeed(key); } -CPubKey CWallet::DeriveNewMasterHDKey(const CKey &key) { +CPubKey CWallet::DeriveNewSeed(const CKey &key) { int64_t nCreationTime = GetTime(); CKeyMetadata metadata(nCreationTime); @@ -1563,7 +1563,7 @@ // Set the hd keypath to "m" -> Master, refers the masterkeyid to itself. metadata.hdKeypath = "m"; - metadata.hdMasterKeyID = pubkey.GetID(); + metadata.hd_seed_id = pubkey.GetID(); LOCK(cs_wallet); @@ -1579,7 +1579,7 @@ return pubkey; } -bool CWallet::SetHDMasterKey(const CPubKey &pubkey) { +bool CWallet::SetHDSeed(const CPubKey &seed) { LOCK(cs_wallet); // Store the keyid (hash160) together with the child index counter in the @@ -1588,7 +1588,7 @@ newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE; - newHdChain.masterKeyID = pubkey.GetID(); + newHdChain.seed_id = seed.GetID(); SetHDChain(newHdChain, false); return true; @@ -1606,7 +1606,7 @@ } bool CWallet::IsHDEnabled() const { - return !hdChain.masterKeyID.IsNull(); + return !hdChain.seed_id.IsNull(); } int64_t CWalletTx::GetTxTime() const { @@ -4454,8 +4454,8 @@ walletInstance->SetMinVersion(FEATURE_HD); // generate a new master key - CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); - if (!walletInstance->SetHDMasterKey(masterPubKey)) { + CPubKey masterPubKey = walletInstance->GenerateNewSeed(); + if (!walletInstance->SetHDSeed(masterPubKey)) { throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } @@ -4492,8 +4492,8 @@ walletInstance->SetMinVersion(FEATURE_LATEST); // Generate a new master key. - CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); - if (!walletInstance->SetHDMasterKey(masterPubKey)) { + CPubKey masterPubKey = walletInstance->GenerateNewSeed(); + if (!walletInstance->SetHDSeed(masterPubKey)) { throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -64,7 +64,7 @@ uint32_t nExternalChainCounter; uint32_t nInternalChainCounter; //!< master key hash160 - CKeyID masterKeyID; + CKeyID seed_id; static const int VERSION_HD_BASE = 1; static const int VERSION_HD_CHAIN_SPLIT = 2; @@ -77,7 +77,7 @@ inline void SerializationOp(Stream &s, Operation ser_action) { READWRITE(this->nVersion); READWRITE(nExternalChainCounter); - READWRITE(masterKeyID); + READWRITE(seed_id); if (this->nVersion >= VERSION_HD_CHAIN_SPLIT) { READWRITE(nInternalChainCounter); } @@ -87,7 +87,7 @@ nVersion = CHDChain::CURRENT_VERSION; nExternalChainCounter = 0; nInternalChainCounter = 0; - masterKeyID.SetNull(); + seed_id.SetNull(); } }; @@ -102,7 +102,7 @@ // optional HD/bip32 keypath. std::string hdKeypath; // Id of the HD masterkey used to derive this key. - CKeyID hdMasterKeyID; + CKeyID hd_seed_id; CKeyMetadata() { SetNull(); } explicit CKeyMetadata(int64_t nCreateTime_) { @@ -118,7 +118,7 @@ READWRITE(nCreateTime); if (this->nVersion >= VERSION_WITH_HDDATA) { READWRITE(hdKeypath); - READWRITE(hdMasterKeyID); + READWRITE(hd_seed_id); } } @@ -126,7 +126,7 @@ nVersion = CKeyMetadata::CURRENT_VERSION; nCreateTime = 0; hdKeypath.clear(); - hdMasterKeyID.SetNull(); + hd_seed_id.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 @@ -35,7 +35,7 @@ if keytype == "inactivehdmaster=1": # ensure the old master is still available assert(hd_master_addr_old == addr) - elif keytype == "hdmaster=1": + elif keytype == "hdseed=1": # ensure we have generated a new hd master key assert(hd_master_addr_old != addr) hd_master_addr_ret = addr 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,7 @@ 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(len(masterkeyid), 40) # create an internal key @@ -57,7 +57,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["hdmasterkeyid"], masterkeyid) + assert_equal(hd_info["hdseedid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) self.nodes[0].sendtoaddress(non_hd_add, 1) @@ -89,7 +89,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["hdmasterkeyid"], masterkeyid) + assert_equal(hd_info_2["hdseedid"], masterkeyid) assert_equal(hd_add, hd_add_2) connect_nodes_bi(self.nodes[0], self.nodes[1]) self.sync_all() @@ -138,9 +138,9 @@ assert_equal(keypath[0:7], "m/0'/1'") # Generate a new HD seed on node 1 and make sure it is set - orig_masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] + orig_masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] self.nodes[1].sethdseed() - new_masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] + new_masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] assert orig_masterkeyid != new_masterkeyid addr = self.nodes[1].getnewaddress() # Make sure the new address is the first from the keypool @@ -152,11 +152,11 @@ new_seed = self.nodes[0].dumpprivkey(self.nodes[0].getnewaddress()) orig_masterkeyid = new_masterkeyid self.nodes[1].sethdseed(False, new_seed) - new_masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] + new_masterkeyid = self.nodes[1].getwalletinfo()['hdseedid'] assert orig_masterkeyid != new_masterkeyid addr = self.nodes[1].getnewaddress() assert_equal(orig_masterkeyid, self.nodes[1].getaddressinfo( - addr)['hdmasterkeyid']) + addr)['hdseedid']) # Make sure the new address continues previous keypool assert_equal(self.nodes[1].getaddressinfo( addr)['hdkeypath'], 'm/0\'/0\'/1\'') @@ -165,7 +165,7 @@ self.nodes[1].keypoolrefill(1) next_addr = self.nodes[1].getnewaddress() assert_equal(new_masterkeyid, self.nodes[1].getaddressinfo( - next_addr)['hdmasterkeyid']) + next_addr)['hdseedid']) # Make sure the new address is not from previous keypool assert_equal(self.nodes[1].getaddressinfo( next_addr)['hdkeypath'], 'm/0\'/0\'/0\'') 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,8 @@ addr_before_encrypting_data = nodes[ 0].getaddressinfo(addr_before_encrypting) wallet_info_old = nodes[0].getwalletinfo() - assert(addr_before_encrypting_data[ - 'hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) + assert(addr_before_encrypting_data['hdseedid'] == + wallet_info_old['hdseedid']) # Encrypt wallet and wait to terminate nodes[0].node_encrypt_wallet('test') @@ -30,9 +30,9 @@ addr = nodes[0].getnewaddress() addr_data = nodes[0].getaddressinfo(addr) wallet_info = nodes[0].getwalletinfo() - assert(addr_before_encrypting_data[ - 'hdmasterkeyid'] != wallet_info['hdmasterkeyid']) - assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid']) + assert( + addr_before_encrypting_data['hdseedid'] != wallet_info['hdseedid']) + assert(addr_data['hdseedid'] == wallet_info['hdseedid']) assert_raises_rpc_error( -12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)