mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-23 15:20:49 +01:00
wallet: Introduce a callback called after TopUp completes
After TopUp completes, the wallet containing each SPKM will want to know what new scriptPubKeys were generated. In order for all TopUp calls (including ones internal the the SPKM), we use a callback function in the WalletStorage interface.
This commit is contained in:
parent
b276825932
commit
99a0cddbc0
4 changed files with 28 additions and 0 deletions
|
@ -1290,6 +1290,9 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
|
||||||
}
|
}
|
||||||
if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
|
if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
|
||||||
NotifyCanGetAddressesChanged();
|
NotifyCanGetAddressesChanged();
|
||||||
|
// Note: Unlike with DescriptorSPKM, LegacySPKM does not need to call
|
||||||
|
// m_storage.TopUpCallback() as we do not know what new scripts the LegacySPKM is
|
||||||
|
// watching for. CWallet's scriptPubKey cache is not used for LegacySPKMs.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2154,6 +2157,7 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
|
||||||
bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int size)
|
bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int size)
|
||||||
{
|
{
|
||||||
LOCK(cs_desc_man);
|
LOCK(cs_desc_man);
|
||||||
|
std::set<CScript> new_spks;
|
||||||
unsigned int target_size;
|
unsigned int target_size;
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
target_size = size;
|
target_size = size;
|
||||||
|
@ -2184,6 +2188,7 @@ bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int siz
|
||||||
if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false;
|
if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false;
|
||||||
}
|
}
|
||||||
// Add all of the scriptPubKeys to the scriptPubKey set
|
// Add all of the scriptPubKeys to the scriptPubKey set
|
||||||
|
new_spks.insert(scripts_temp.begin(), scripts_temp.end());
|
||||||
for (const CScript& script : scripts_temp) {
|
for (const CScript& script : scripts_temp) {
|
||||||
m_map_script_pub_keys[script] = i;
|
m_map_script_pub_keys[script] = i;
|
||||||
}
|
}
|
||||||
|
@ -2209,6 +2214,7 @@ bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int siz
|
||||||
// By this point, the cache size should be the size of the entire range
|
// By this point, the cache size should be the size of the entire range
|
||||||
assert(m_wallet_descriptor.range_end - 1 == m_max_cached_index);
|
assert(m_wallet_descriptor.range_end - 1 == m_max_cached_index);
|
||||||
|
|
||||||
|
m_storage.TopUpCallback(new_spks, this);
|
||||||
NotifyCanGetAddressesChanged();
|
NotifyCanGetAddressesChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2624,6 +2630,7 @@ uint256 DescriptorScriptPubKeyMan::GetID() const
|
||||||
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
|
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
|
||||||
{
|
{
|
||||||
LOCK(cs_desc_man);
|
LOCK(cs_desc_man);
|
||||||
|
std::set<CScript> new_spks;
|
||||||
m_wallet_descriptor.cache = cache;
|
m_wallet_descriptor.cache = cache;
|
||||||
for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
|
for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
|
||||||
FlatSigningProvider out_keys;
|
FlatSigningProvider out_keys;
|
||||||
|
@ -2632,6 +2639,7 @@ void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
|
||||||
throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
|
throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
|
||||||
}
|
}
|
||||||
// Add all of the scriptPubKeys to the scriptPubKey set
|
// Add all of the scriptPubKeys to the scriptPubKey set
|
||||||
|
new_spks.insert(scripts_temp.begin(), scripts_temp.end());
|
||||||
for (const CScript& script : scripts_temp) {
|
for (const CScript& script : scripts_temp) {
|
||||||
if (m_map_script_pub_keys.count(script) != 0) {
|
if (m_map_script_pub_keys.count(script) != 0) {
|
||||||
throw std::runtime_error(strprintf("Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
|
throw std::runtime_error(strprintf("Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
|
||||||
|
@ -2649,6 +2657,8 @@ void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
|
||||||
}
|
}
|
||||||
m_max_cached_index++;
|
m_max_cached_index++;
|
||||||
}
|
}
|
||||||
|
// Make sure the wallet knows about our new spks
|
||||||
|
m_storage.TopUpCallback(new_spks, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)
|
bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct bilingual_str;
|
||||||
|
|
||||||
namespace wallet {
|
namespace wallet {
|
||||||
struct MigrationData;
|
struct MigrationData;
|
||||||
|
class ScriptPubKeyMan;
|
||||||
|
|
||||||
// Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database.
|
// Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database.
|
||||||
// It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as
|
// It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as
|
||||||
|
@ -51,6 +52,8 @@ public:
|
||||||
virtual bool WithEncryptionKey(std::function<bool (const CKeyingMaterial&)> cb) const = 0;
|
virtual bool WithEncryptionKey(std::function<bool (const CKeyingMaterial&)> cb) const = 0;
|
||||||
virtual bool HasEncryptionKeys() const = 0;
|
virtual bool HasEncryptionKeys() const = 0;
|
||||||
virtual bool IsLocked() const = 0;
|
virtual bool IsLocked() const = 0;
|
||||||
|
//! Callback function for after TopUp completes containining any scripts that were added by a SPKMan
|
||||||
|
virtual void TopUpCallback(const std::set<CScript>&, ScriptPubKeyMan*) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Constant representing an unknown spkm creation time
|
//! Constant representing an unknown spkm creation time
|
||||||
|
|
|
@ -4334,4 +4334,14 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWallet::CacheNewScriptPubKeys(const std::set<CScript>& spks, ScriptPubKeyMan* spkm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWallet::TopUpCallback(const std::set<CScript>& spks, ScriptPubKeyMan* spkm)
|
||||||
|
{
|
||||||
|
// Update scriptPubKey cache
|
||||||
|
CacheNewScriptPubKeys(spks, spkm);
|
||||||
|
}
|
||||||
} // namespace wallet
|
} // namespace wallet
|
||||||
|
|
|
@ -1042,6 +1042,11 @@ public:
|
||||||
|
|
||||||
//! Whether the (external) signer performs R-value signature grinding
|
//! Whether the (external) signer performs R-value signature grinding
|
||||||
bool CanGrindR() const;
|
bool CanGrindR() const;
|
||||||
|
|
||||||
|
//! Add scriptPubKeys for this ScriptPubKeyMan into the scriptPubKey cache
|
||||||
|
void CacheNewScriptPubKeys(const std::set<CScript>& spks, ScriptPubKeyMan* spkm);
|
||||||
|
|
||||||
|
void TopUpCallback(const std::set<CScript>& spks, ScriptPubKeyMan* spkm) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue