Skip to content

Commit 2363e9f

Browse files
committed
Load the descriptor cache from the wallet file
1 parent 46c46ae commit 2363e9f

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

src/wallet/scriptpubkeyman.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,3 +1633,23 @@ void DescriptorScriptPubKeyMan::SetType(OutputType type, bool internal)
16331633
this->m_address_type = type;
16341634
this->m_internal = internal;
16351635
}
1636+
1637+
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
1638+
{
1639+
LOCK(cs_desc_man);
1640+
m_wallet_descriptor.cache = cache;
1641+
for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
1642+
FlatSigningProvider out_keys;
1643+
std::vector<CScript> scripts_temp;
1644+
if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
1645+
throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
1646+
}
1647+
// Add all of the scriptPubKeys to the scriptPubKey set
1648+
for (const CScript& script : scripts_temp) {
1649+
if (m_map_script_pub_keys.count(script) != 0) {
1650+
throw std::runtime_error(strprintf("Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
1651+
}
1652+
m_map_script_pub_keys[script] = i;
1653+
}
1654+
}
1655+
}

src/wallet/scriptpubkeyman.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
543543
uint256 GetID() const override;
544544

545545
void SetType(OutputType type, bool internal) override;
546+
547+
void SetCache(const DescriptorCache& cache);
546548
};
547549

548550
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H

src/wallet/walletdb.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const std::string SETTINGS{"settings"};
4444
const std::string TX{"tx"};
4545
const std::string VERSION{"version"};
4646
const std::string WALLETDESCRIPTOR{"walletdescriptor"};
47+
const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"};
4748
const std::string WATCHMETA{"watchmeta"};
4849
const std::string WATCHS{"watchs"};
4950
} // namespace DBKeys
@@ -200,6 +201,7 @@ class CWalletScanState {
200201
std::vector<uint256> vWalletUpgrade;
201202
std::map<OutputType, uint256> m_active_external_spks;
202203
std::map<OutputType, uint256> m_active_internal_spks;
204+
std::map<uint256, DescriptorCache> m_descriptor_caches;
203205

204206
CWalletScanState() {
205207
}
@@ -433,7 +435,38 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
433435
ssKey >> id;
434436
WalletDescriptor desc;
435437
ssValue >> desc;
438+
if (wss.m_descriptor_caches.count(id) == 0) {
439+
wss.m_descriptor_caches[id] = DescriptorCache();
440+
}
436441
pwallet->LoadDescriptorScriptPubKeyMan(id, desc);
442+
} else if (strType == DBKeys::WALLETDESCRIPTORCACHE) {
443+
bool parent = true;
444+
uint256 desc_id;
445+
uint32_t key_exp_index;
446+
uint32_t der_index;
447+
ssKey >> desc_id;
448+
ssKey >> key_exp_index;
449+
450+
// if the der_index exists, it's a derived xpub
451+
try
452+
{
453+
ssKey >> der_index;
454+
parent = false;
455+
}
456+
catch (...) {}
457+
458+
std::vector<unsigned char> ser_xpub(BIP32_EXTKEY_SIZE);
459+
ssValue >> ser_xpub;
460+
CExtPubKey xpub;
461+
xpub.Decode(ser_xpub.data());
462+
if (wss.m_descriptor_caches.count(desc_id)) {
463+
wss.m_descriptor_caches[desc_id] = DescriptorCache();
464+
}
465+
if (parent) {
466+
wss.m_descriptor_caches[desc_id].CacheParentExtPubKey(key_exp_index, xpub);
467+
} else {
468+
wss.m_descriptor_caches[desc_id].CacheDerivedExtPubKey(key_exp_index, der_index, xpub);
469+
}
437470
} else if (strType != DBKeys::BESTBLOCK && strType != DBKeys::BESTBLOCK_NOMERKLE &&
438471
strType != DBKeys::MINVERSION && strType != DBKeys::ACENTRY &&
439472
strType != DBKeys::VERSION && strType != DBKeys::SETTINGS) {
@@ -535,6 +568,13 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
535568
pwallet->SetActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /* internal */ true, /* memonly */ true);
536569
}
537570

571+
// Set the descriptor caches
572+
for (auto desc_cache_pair : wss.m_descriptor_caches) {
573+
auto spk_man = pwallet->GetScriptPubKeyMan(desc_cache_pair.first);
574+
assert(spk_man);
575+
((DescriptorScriptPubKeyMan*)spk_man)->SetCache(desc_cache_pair.second);
576+
}
577+
538578
if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
539579
result = DBErrors::NONCRITICAL_ERROR;
540580

src/wallet/walletdb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ extern const std::string SETTINGS;
7777
extern const std::string TX;
7878
extern const std::string VERSION;
7979
extern const std::string WALLETDESCRIPTOR;
80+
extern const std::string WALLETDESCRIPTORCKEY;
81+
extern const std::string WALLETDESCRIPTORKEY;
8082
extern const std::string WATCHMETA;
8183
extern const std::string WATCHS;
8284
} // namespace DBKeys

0 commit comments

Comments
 (0)