mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Implement loading of keys for DescriptorScriptPubKeyMan
This commit is contained in:
parent
2363e9fcaa
commit
953feb3d27
@ -1653,3 +1653,21 @@ void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)
|
||||
{
|
||||
LOCK(cs_desc_man);
|
||||
m_map_keys[key_id] = key;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DescriptorScriptPubKeyMan::AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key)
|
||||
{
|
||||
LOCK(cs_desc_man);
|
||||
if (!m_map_keys.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
|
||||
return true;
|
||||
}
|
||||
|
@ -488,11 +488,21 @@ private:
|
||||
WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);
|
||||
|
||||
using ScriptPubKeyMap = std::map<CScript, int32_t>; // Map of scripts to descriptor range index
|
||||
using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
|
||||
using KeyMap = std::map<CKeyID, CKey>;
|
||||
|
||||
ScriptPubKeyMap m_map_script_pub_keys GUARDED_BY(cs_desc_man);
|
||||
|
||||
OutputType m_address_type;
|
||||
bool m_internal;
|
||||
|
||||
KeyMap m_map_keys GUARDED_BY(cs_desc_man);
|
||||
CryptedKeyMap m_map_crypted_keys GUARDED_BY(cs_desc_man);
|
||||
|
||||
bool SetCrypted();
|
||||
|
||||
//! keeps track of whether Unlock has run a thorough check before
|
||||
bool m_decryption_thoroughly_checked = false;
|
||||
public:
|
||||
DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor)
|
||||
: ScriptPubKeyMan(storage),
|
||||
@ -545,6 +555,9 @@ public:
|
||||
void SetType(OutputType type, bool internal) override;
|
||||
|
||||
void SetCache(const DescriptorCache& cache);
|
||||
|
||||
bool AddKey(const CKeyID& key_id, const CKey& key);
|
||||
bool AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
|
||||
|
@ -45,6 +45,8 @@ const std::string TX{"tx"};
|
||||
const std::string VERSION{"version"};
|
||||
const std::string WALLETDESCRIPTOR{"walletdescriptor"};
|
||||
const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"};
|
||||
const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"};
|
||||
const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"};
|
||||
const std::string WATCHMETA{"watchmeta"};
|
||||
const std::string WATCHS{"watchs"};
|
||||
} // namespace DBKeys
|
||||
@ -202,6 +204,8 @@ public:
|
||||
std::map<OutputType, uint256> m_active_external_spks;
|
||||
std::map<OutputType, uint256> m_active_internal_spks;
|
||||
std::map<uint256, DescriptorCache> m_descriptor_caches;
|
||||
std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys;
|
||||
std::map<std::pair<uint256, CKeyID>, std::pair<CPubKey, std::vector<unsigned char>>> m_descriptor_crypt_keys;
|
||||
|
||||
CWalletScanState() {
|
||||
}
|
||||
@ -467,6 +471,58 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||
} else {
|
||||
wss.m_descriptor_caches[desc_id].CacheDerivedExtPubKey(key_exp_index, der_index, xpub);
|
||||
}
|
||||
} else if (strType == DBKeys::WALLETDESCRIPTORKEY) {
|
||||
uint256 desc_id;
|
||||
CPubKey pubkey;
|
||||
ssKey >> desc_id;
|
||||
ssKey >> pubkey;
|
||||
if (!pubkey.IsValid())
|
||||
{
|
||||
strErr = "Error reading wallet database: CPubKey corrupt";
|
||||
return false;
|
||||
}
|
||||
CKey key;
|
||||
CPrivKey pkey;
|
||||
uint256 hash;
|
||||
|
||||
wss.nKeys++;
|
||||
ssValue >> pkey;
|
||||
ssValue >> hash;
|
||||
|
||||
// hash pubkey/privkey to accelerate wallet load
|
||||
std::vector<unsigned char> to_hash;
|
||||
to_hash.reserve(pubkey.size() + pkey.size());
|
||||
to_hash.insert(to_hash.end(), pubkey.begin(), pubkey.end());
|
||||
to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
|
||||
|
||||
if (Hash(to_hash.begin(), to_hash.end()) != hash)
|
||||
{
|
||||
strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!key.Load(pkey, pubkey, true))
|
||||
{
|
||||
strErr = "Error reading wallet database: CPrivKey corrupt";
|
||||
return false;
|
||||
}
|
||||
wss.m_descriptor_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), key));
|
||||
} else if (strType == DBKeys::WALLETDESCRIPTORCKEY) {
|
||||
uint256 desc_id;
|
||||
CPubKey pubkey;
|
||||
ssKey >> desc_id;
|
||||
ssKey >> pubkey;
|
||||
if (!pubkey.IsValid())
|
||||
{
|
||||
strErr = "Error reading wallet database: CPubKey corrupt";
|
||||
return false;
|
||||
}
|
||||
std::vector<unsigned char> privkey;
|
||||
ssValue >> privkey;
|
||||
wss.nCKeys++;
|
||||
|
||||
wss.m_descriptor_crypt_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), std::make_pair(pubkey, privkey)));
|
||||
wss.fIsEncrypted = true;
|
||||
} else if (strType != DBKeys::BESTBLOCK && strType != DBKeys::BESTBLOCK_NOMERKLE &&
|
||||
strType != DBKeys::MINVERSION && strType != DBKeys::ACENTRY &&
|
||||
strType != DBKeys::VERSION && strType != DBKeys::SETTINGS) {
|
||||
@ -575,6 +631,16 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
||||
((DescriptorScriptPubKeyMan*)spk_man)->SetCache(desc_cache_pair.second);
|
||||
}
|
||||
|
||||
// Set the descriptor keys
|
||||
for (auto desc_key_pair : wss.m_descriptor_keys) {
|
||||
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first);
|
||||
((DescriptorScriptPubKeyMan*)spk_man)->AddKey(desc_key_pair.first.second, desc_key_pair.second);
|
||||
}
|
||||
for (auto desc_key_pair : wss.m_descriptor_crypt_keys) {
|
||||
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first);
|
||||
((DescriptorScriptPubKeyMan*)spk_man)->AddCryptedKey(desc_key_pair.first.second, desc_key_pair.second.first, desc_key_pair.second.second);
|
||||
}
|
||||
|
||||
if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
|
||||
result = DBErrors::NONCRITICAL_ERROR;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user