fix: Pass KeyOriginInfo instead of CKeyMetadata to DeriveChildExtKey (#4918)

Resolves "hdchain -> wallet/walletdb -> ... -> hdchain" circular dependencies
This commit is contained in:
UdjinM6 2022-07-18 16:56:33 +03:00 committed by GitHub
parent 30d6584cb6
commit 0d67aa1915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 26 deletions

View File

@ -8,9 +8,6 @@
#include <tinyformat.h>
#include <util/system.h>
#include <util/strencodings.h>
#ifdef ENABLE_WALLET
#include <wallet/walletdb.h>
#endif
bool CHDChain::SetNull()
{
@ -159,7 +156,7 @@ uint256 CHDChain::GetSeedHash()
return Hash(vchSeed.begin(), vchSeed.end());
}
void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet, CKeyMetadata& metadata)
void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet, KeyOriginInfo& key_origin)
{
LOCK(cs);
// Use BIP44 keypath scheme i.e. m / purpose' / coin_type' / account' / change / address_index
@ -188,17 +185,15 @@ void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_
#ifdef ENABLE_WALLET
// We should never ever update an already existing key_origin here
assert(!metadata.has_key_origin);
assert(metadata.key_origin.path.empty());
metadata.key_origin.path.push_back(44 | 0x80000000);
metadata.key_origin.path.push_back(Params().ExtCoinType() | 0x80000000);
metadata.key_origin.path.push_back(nAccountIndex | 0x80000000);
metadata.key_origin.path.push_back(fInternal ? 1 : 0);
metadata.key_origin.path.push_back(nChildIndex);
assert(key_origin.path.empty());
key_origin.path.push_back(44 | 0x80000000);
key_origin.path.push_back(Params().ExtCoinType() | 0x80000000);
key_origin.path.push_back(nAccountIndex | 0x80000000);
key_origin.path.push_back(fInternal ? 1 : 0);
key_origin.path.push_back(nChildIndex);
CKeyID master_id = masterKey.key.GetPubKey().GetID();
std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
metadata.has_key_origin = true;
std::copy(master_id.begin(), master_id.begin() + 4, key_origin.fingerprint);
#endif
}

View File

@ -4,10 +4,9 @@
#define BITCOIN_HDCHAIN_H
#include <key.h>
#include <script/keyorigin.h>
#include <sync.h>
class CKeyMetadata;
/* hd account data model */
class CHDAccount
{
@ -110,7 +109,7 @@ public:
uint256 GetID() const { LOCK(cs); return id; }
uint256 GetSeedHash();
void DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet, CKeyMetadata& metadata);
void DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet, KeyOriginInfo& key_origin);
void AddAccount();
bool GetAccount(uint32_t nAccountIndex, CHDAccount& hdAccountRet);

View File

@ -417,17 +417,18 @@ void CWallet::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey
// derive child key at next index, skip keys already known to the wallet
CExtKey childKey;
CKeyMetadata metadataTmp;
KeyOriginInfo key_origin_tmp;
uint32_t nChildIndex = fInternal ? acc.nInternalChainCounter : acc.nExternalChainCounter;
do {
// NOTE: DeriveChildExtKey updates metadata, use temporary structure to make sure
// we start with the original (non-updated) data each time.
metadataTmp = metadata;
hdChainTmp.DeriveChildExtKey(nAccountIndex, fInternal, nChildIndex, childKey, metadataTmp);
// NOTE: DeriveChildExtKey updates key_origin, make sure to clear it.
key_origin_tmp.clear();
hdChainTmp.DeriveChildExtKey(nAccountIndex, fInternal, nChildIndex, childKey, key_origin_tmp);
// increment childkey index
nChildIndex++;
} while (HaveKey(childKey.key.GetPubKey().GetID()));
metadata = metadataTmp;
metadata.key_origin = key_origin_tmp;
assert(!metadata.has_key_origin);
metadata.has_key_origin = true;
secretRet = childKey.key;
CPubKey pubkey = secretRet.GetPubKey();
@ -496,8 +497,8 @@ bool CWallet::GetKey(const CKeyID &address, CKey& keyOut) const
throw std::runtime_error(std::string(__func__) + ": Wrong HD chain!");
CExtKey extkey;
CKeyMetadata metadataTmp;
hdChainCurrent.DeriveChildExtKey(hdPubKey.nAccountIndex, hdPubKey.nChangeIndex != 0, hdPubKey.extPubKey.nChild, extkey, metadataTmp);
KeyOriginInfo key_origin_tmp;
hdChainCurrent.DeriveChildExtKey(hdPubKey.nAccountIndex, hdPubKey.nChangeIndex != 0, hdPubKey.extPubKey.nChild, extkey, key_origin_tmp);
keyOut = extkey.key;
return true;

View File

@ -40,8 +40,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"governance/governance -> masternode/sync -> governance/governance"
"governance/governance -> net_processing -> governance/governance"
"governance/object -> governance/validators -> governance/object"
"hdchain -> wallet/walletdb -> hdchain"
"hdchain -> wallet/walletdb -> script/sign -> script/signingprovider -> hdchain"
"llmq/quorums -> llmq/utils -> llmq/quorums"
"llmq/blockprocessor -> net_processing -> llmq/blockprocessor"
"llmq/chainlocks -> llmq/instantsend -> llmq/chainlocks"