mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
wallet: Upgrade existing descriptor caches
Add functions to upgrade existing descriptor caches to support the use of last hardened xpub caching.
This commit is contained in:
parent
432ba9e543
commit
74fede3b8b
6 changed files with 62 additions and 0 deletions
|
@ -2278,3 +2278,32 @@ bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out, bool priv)
|
|||
|
||||
return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, priv);
|
||||
}
|
||||
|
||||
void DescriptorScriptPubKeyMan::UpgradeDescriptorCache()
|
||||
{
|
||||
LOCK(cs_desc_man);
|
||||
if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if we have the last hardened xpub cache
|
||||
if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Expand the descriptor
|
||||
FlatSigningProvider provider;
|
||||
provider.keys = GetKeys();
|
||||
FlatSigningProvider out_keys;
|
||||
std::vector<CScript> scripts_temp;
|
||||
DescriptorCache temp_cache;
|
||||
if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
|
||||
throw std::runtime_error("Unable to expand descriptor");
|
||||
}
|
||||
|
||||
// Cache the last hardened xpubs
|
||||
DescriptorCache diff = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
|
||||
if (!WalletBatch(m_storage.GetDatabase()).WriteDescriptorCacheItems(GetID(), diff)) {
|
||||
throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -631,6 +631,8 @@ public:
|
|||
const std::vector<CScript> GetScriptPubKeys() const;
|
||||
|
||||
bool GetDescriptorString(std::string& out, bool priv) const;
|
||||
|
||||
void UpgradeDescriptorCache();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
|
||||
|
|
|
@ -374,6 +374,19 @@ void CWallet::UpgradeKeyMetadata()
|
|||
SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
|
||||
}
|
||||
|
||||
void CWallet::UpgradeDescriptorCache()
|
||||
{
|
||||
if (!IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) || IsLocked() || IsWalletFlagSet(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ScriptPubKeyMan* spkm : GetAllScriptPubKeyMans()) {
|
||||
DescriptorScriptPubKeyMan* desc_spkm = dynamic_cast<DescriptorScriptPubKeyMan*>(spkm);
|
||||
desc_spkm->UpgradeDescriptorCache();
|
||||
}
|
||||
SetWalletFlag(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED);
|
||||
}
|
||||
|
||||
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
|
||||
{
|
||||
CCrypter crypter;
|
||||
|
@ -390,6 +403,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_key
|
|||
if (Unlock(_vMasterKey, accept_no_keys)) {
|
||||
// Now that we've unlocked, upgrade the key metadata
|
||||
UpgradeKeyMetadata();
|
||||
// Now that we've unlocked, upgrade the descriptor cache
|
||||
UpgradeDescriptorCache();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ static constexpr uint64_t KNOWN_WALLET_FLAGS =
|
|||
WALLET_FLAG_AVOID_REUSE
|
||||
| WALLET_FLAG_BLANK_WALLET
|
||||
| WALLET_FLAG_KEY_ORIGIN_METADATA
|
||||
| WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
|
||||
| WALLET_FLAG_DISABLE_PRIVATE_KEYS
|
||||
| WALLET_FLAG_DESCRIPTORS
|
||||
| WALLET_FLAG_EXTERNAL_SIGNER;
|
||||
|
@ -128,6 +129,7 @@ static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{
|
|||
{"avoid_reuse", WALLET_FLAG_AVOID_REUSE},
|
||||
{"blank", WALLET_FLAG_BLANK_WALLET},
|
||||
{"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA},
|
||||
{"last_hardened_xpub_cached", WALLET_FLAG_LAST_HARDENED_XPUB_CACHED},
|
||||
{"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS},
|
||||
{"descriptor_wallet", WALLET_FLAG_DESCRIPTORS},
|
||||
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
|
||||
|
@ -476,6 +478,9 @@ public:
|
|||
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
|
||||
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
//! Upgrade DescriptorCaches
|
||||
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; return true; }
|
||||
|
||||
//! Adds a destination data tuple to the store, without saving it to disk
|
||||
|
|
|
@ -884,6 +884,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
|||
result = DBErrors::CORRUPT;
|
||||
}
|
||||
|
||||
// Upgrade all of the descriptor caches to cache the last hardened xpub
|
||||
// This operation is not atomic, but if it fails, only new entries are added so it is backwards compatible
|
||||
try {
|
||||
pwallet->UpgradeDescriptorCache();
|
||||
} catch (...) {
|
||||
result = DBErrors::CORRUPT;
|
||||
}
|
||||
|
||||
// Set the inactive chain
|
||||
if (wss.m_hd_chains.size() > 0) {
|
||||
LegacyScriptPubKeyMan* legacy_spkm = pwallet->GetLegacyScriptPubKeyMan();
|
||||
|
|
|
@ -43,6 +43,9 @@ enum WalletFlags : uint64_t {
|
|||
// Indicates that the metadata has already been upgraded to contain key origins
|
||||
WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1),
|
||||
|
||||
// Indicates that the descriptor cache has been upgraded to cache last hardened xpubs
|
||||
WALLET_FLAG_LAST_HARDENED_XPUB_CACHED = (1ULL << 2),
|
||||
|
||||
// will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys)
|
||||
WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32),
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue