mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-14 11:26:09 -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);
|
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;
|
const std::vector<CScript> GetScriptPubKeys() const;
|
||||||
|
|
||||||
bool GetDescriptorString(std::string& out, bool priv) const;
|
bool GetDescriptorString(std::string& out, bool priv) const;
|
||||||
|
|
||||||
|
void UpgradeDescriptorCache();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
|
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
|
||||||
|
|
|
@ -374,6 +374,19 @@ void CWallet::UpgradeKeyMetadata()
|
||||||
SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
|
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)
|
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
|
||||||
{
|
{
|
||||||
CCrypter crypter;
|
CCrypter crypter;
|
||||||
|
@ -390,6 +403,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_key
|
||||||
if (Unlock(_vMasterKey, accept_no_keys)) {
|
if (Unlock(_vMasterKey, accept_no_keys)) {
|
||||||
// Now that we've unlocked, upgrade the key metadata
|
// Now that we've unlocked, upgrade the key metadata
|
||||||
UpgradeKeyMetadata();
|
UpgradeKeyMetadata();
|
||||||
|
// Now that we've unlocked, upgrade the descriptor cache
|
||||||
|
UpgradeDescriptorCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ static constexpr uint64_t KNOWN_WALLET_FLAGS =
|
||||||
WALLET_FLAG_AVOID_REUSE
|
WALLET_FLAG_AVOID_REUSE
|
||||||
| WALLET_FLAG_BLANK_WALLET
|
| WALLET_FLAG_BLANK_WALLET
|
||||||
| WALLET_FLAG_KEY_ORIGIN_METADATA
|
| WALLET_FLAG_KEY_ORIGIN_METADATA
|
||||||
|
| WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
|
||||||
| WALLET_FLAG_DISABLE_PRIVATE_KEYS
|
| WALLET_FLAG_DISABLE_PRIVATE_KEYS
|
||||||
| WALLET_FLAG_DESCRIPTORS
|
| WALLET_FLAG_DESCRIPTORS
|
||||||
| WALLET_FLAG_EXTERNAL_SIGNER;
|
| WALLET_FLAG_EXTERNAL_SIGNER;
|
||||||
|
@ -128,6 +129,7 @@ static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{
|
||||||
{"avoid_reuse", WALLET_FLAG_AVOID_REUSE},
|
{"avoid_reuse", WALLET_FLAG_AVOID_REUSE},
|
||||||
{"blank", WALLET_FLAG_BLANK_WALLET},
|
{"blank", WALLET_FLAG_BLANK_WALLET},
|
||||||
{"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA},
|
{"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},
|
{"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS},
|
||||||
{"descriptor_wallet", WALLET_FLAG_DESCRIPTORS},
|
{"descriptor_wallet", WALLET_FLAG_DESCRIPTORS},
|
||||||
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
|
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
|
||||||
|
@ -476,6 +478,9 @@ public:
|
||||||
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
|
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
|
||||||
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
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; }
|
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
|
//! 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;
|
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
|
// Set the inactive chain
|
||||||
if (wss.m_hd_chains.size() > 0) {
|
if (wss.m_hd_chains.size() > 0) {
|
||||||
LegacyScriptPubKeyMan* legacy_spkm = pwallet->GetLegacyScriptPubKeyMan();
|
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
|
// Indicates that the metadata has already been upgraded to contain key origins
|
||||||
WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1),
|
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)
|
// will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys)
|
||||||
WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32),
|
WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32),
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue