wallet: Cache SigningProviders

In order to avoid constantly re-deriving the same keys in
DescriptorScriptPubKeyMan, cache the SigningProviders generated inside
of GetSigningProvider.
This commit is contained in:
Andrew Chow committed 2022-08-03 15:33:13 -04:00
1 parent 8a105ecd1a
commit 1f798fe85b
2 files changed
+16 -3

No files matched your search

+14 -3
View File
@@ -2075,10 +2075,21 @@ std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvid
std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(int32_t index, bool include_private) const
{
AssertLockHeld(cs_desc_man);
// Get the scripts, keys, and key origins for this script
std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
std::vector<CScript> scripts_temp;
if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) return nullptr;
// Fetch SigningProvider from cache to avoid re-deriving
auto it = m_map_signing_providers.find(index);
if (it != m_map_signing_providers.end()) {
*out_keys = Merge(*out_keys, it->second);
} else {
// Get the scripts, keys, and key origins for this script
std::vector<CScript> scripts_temp;
if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) return nullptr;
// Cache SigningProvider so we don't need to re-derive if we need this SigningProvider again
m_map_signing_providers[index] = *out_keys;
}
if (HavePrivateKeys() && include_private) {
FlatSigningProvider master_provider;
+2
View File
@@ -547,6 +547,8 @@ private:
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
// Cached FlatSigningProviders to avoid regenerating them each time they are needed.
mutable std::map<int32_t, FlatSigningProvider> m_map_signing_providers;
// Fetch the SigningProvider for the given script and optionally include private keys
std::unique_ptr<FlatSigningProvider> GetSigningProvider(const CScript& script, bool include_private = false) const;
// Fetch the SigningProvider for the given pubkey and always include private keys. This should only be called by signing code.