From b741b11cad4c9a18713a12b20cdc5d831eca1cad Mon Sep 17 00:00:00 2001 From: lateminer Date: Tue, 2 Jan 2018 14:30:26 +0300 Subject: [PATCH] Add HD keypath to CKeyMetadata, report metadata in validateaddress https://github.com/bitcoin/bitcoin/pull/8323 --- src/rpcmisc.cpp | 8 ++++++++ src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.cpp | 2 ++ src/wallet/wallet.h | 6 +++--- src/wallet/walletdb.h | 12 ++++++++++-- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 779587660..fafc46a1a 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -174,6 +174,8 @@ UniValue validateaddress(const UniValue& params, bool fHelp) " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\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" "}\n" "\nExamples:\n" + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") @@ -208,6 +210,12 @@ UniValue validateaddress(const UniValue& params, bool fHelp) ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + CKeyID keyID; + if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty()) + { + ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath)); + ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex())); + } #endif } return ret; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 24d287b17..bcaad6219 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2310,7 +2310,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" - " \"hdmasterkeyid\": \"\", (string) the Hash160 of the hd master pubkey\n" + " \"hdmasterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2332,7 +2332,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) - obj.push_back(Pair("hdmasterkeyid",masterKeyID.GetHex())); + obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex())); return obj; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 31428ccb8..e6ef7f0e2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -130,6 +130,8 @@ CPubKey CWallet::GenerateNewKey() // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649 externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT); + metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'"; + metadata.hdMasterKeyID = hdChain.masterKeyID; // increment childkey index hdChain.nExternalChainCounter++; } while(HaveKey(childKey.key.GetPubKey().GetID())); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c15ad4076..267c2a620 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -509,7 +509,7 @@ private: void SyncMetaData(std::pair); - /* the hd chain data model (external chain counters) */ + /* the HD chain data model (external chain counters) */ CHDChain hdChain; public: @@ -817,14 +817,14 @@ public: bool SelectCoinsForStaking(CAmount& nTargetValue, std::set >& setCoinsRet, CAmount& nValueRet) const; void AvailableCoinsForStaking(std::vector& vCoins) const; uint64_t GetStakeWeight() const; - /* Set the hd chain model (chain child index counters) */ + /* Set the HD chain model (chain child index counters) */ 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) */ + /* Set the current HD master key (will reset the chain child index counters) */ bool SetHDMasterKey(const CPubKey& key); }; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 697e2ebff..267680a5e 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -40,7 +40,7 @@ enum DBErrors DB_NEED_REWRITE }; -/* simple hd chain data model */ +/* simple HD chain data model */ class CHDChain { public: @@ -72,7 +72,9 @@ public: class CKeyMetadata { public: - static const int CURRENT_VERSION=1; + static const int VERSION_BASIC=1; + static const int VERSION_WITH_HDDATA=10; + static const int CURRENT_VERSION=VERSION_WITH_HDDATA; int nVersion; int64_t nCreateTime; // 0 means unknown std::string hdKeypath; //optional HD/bip32 keypath @@ -95,12 +97,18 @@ public: READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(nCreateTime); + if (this->nVersion >= VERSION_WITH_HDDATA) + { + READWRITE(hdKeypath); + READWRITE(hdMasterKeyID); + } } void SetNull() { nVersion = CKeyMetadata::CURRENT_VERSION; nCreateTime = 0; + hdKeypath.clear(); hdMasterKeyID.SetNull(); } };