0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-03 09:56:38 -05:00

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 2022-03-28 16:47:59 -04:00
parent 8a105ecd1a
commit 1f798fe85b
2 changed files with 16 additions and 3 deletions

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;

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.