Skip to content

Commit 99a0cdd

Browse files
committed
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.
1 parent b276825 commit 99a0cdd

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

src/wallet/scriptpubkeyman.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,9 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
12901290
}
12911291
if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
12921292
NotifyCanGetAddressesChanged();
1293+
// Note: Unlike with DescriptorSPKM, LegacySPKM does not need to call
1294+
// m_storage.TopUpCallback() as we do not know what new scripts the LegacySPKM is
1295+
// watching for. CWallet's scriptPubKey cache is not used for LegacySPKMs.
12931296
return true;
12941297
}
12951298

@@ -2154,6 +2157,7 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
21542157
bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int size)
21552158
{
21562159
LOCK(cs_desc_man);
2160+
std::set<CScript> new_spks;
21572161
unsigned int target_size;
21582162
if (size > 0) {
21592163
target_size = size;
@@ -2184,6 +2188,7 @@ bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int siz
21842188
if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false;
21852189
}
21862190
// Add all of the scriptPubKeys to the scriptPubKey set
2191+
new_spks.insert(scripts_temp.begin(), scripts_temp.end());
21872192
for (const CScript& script : scripts_temp) {
21882193
m_map_script_pub_keys[script] = i;
21892194
}
@@ -2209,6 +2214,7 @@ bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int siz
22092214
// By this point, the cache size should be the size of the entire range
22102215
assert(m_wallet_descriptor.range_end - 1 == m_max_cached_index);
22112216

2217+
m_storage.TopUpCallback(new_spks, this);
22122218
NotifyCanGetAddressesChanged();
22132219
return true;
22142220
}
@@ -2624,6 +2630,7 @@ uint256 DescriptorScriptPubKeyMan::GetID() const
26242630
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
26252631
{
26262632
LOCK(cs_desc_man);
2633+
std::set<CScript> new_spks;
26272634
m_wallet_descriptor.cache = cache;
26282635
for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
26292636
FlatSigningProvider out_keys;
@@ -2632,6 +2639,7 @@ void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
26322639
throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
26332640
}
26342641
// Add all of the scriptPubKeys to the scriptPubKey set
2642+
new_spks.insert(scripts_temp.begin(), scripts_temp.end());
26352643
for (const CScript& script : scripts_temp) {
26362644
if (m_map_script_pub_keys.count(script) != 0) {
26372645
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)
26492657
}
26502658
m_max_cached_index++;
26512659
}
2660+
// Make sure the wallet knows about our new spks
2661+
m_storage.TopUpCallback(new_spks, this);
26522662
}
26532663

26542664
bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)

src/wallet/scriptpubkeyman.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct bilingual_str;
3131

3232
namespace wallet {
3333
struct MigrationData;
34+
class ScriptPubKeyMan;
3435

3536
// Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database.
3637
// It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as
@@ -51,6 +52,8 @@ class WalletStorage
5152
virtual bool WithEncryptionKey(std::function<bool (const CKeyingMaterial&)> cb) const = 0;
5253
virtual bool HasEncryptionKeys() const = 0;
5354
virtual bool IsLocked() const = 0;
55+
//! Callback function for after TopUp completes containining any scripts that were added by a SPKMan
56+
virtual void TopUpCallback(const std::set<CScript>&, ScriptPubKeyMan*) = 0;
5457
};
5558

5659
//! Constant representing an unknown spkm creation time

src/wallet/wallet.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4334,4 +4334,14 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
43344334
}
43354335
return res;
43364336
}
4337+
4338+
void CWallet::CacheNewScriptPubKeys(const std::set<CScript>& spks, ScriptPubKeyMan* spkm)
4339+
{
4340+
}
4341+
4342+
void CWallet::TopUpCallback(const std::set<CScript>& spks, ScriptPubKeyMan* spkm)
4343+
{
4344+
// Update scriptPubKey cache
4345+
CacheNewScriptPubKeys(spks, spkm);
4346+
}
43374347
} // namespace wallet

src/wallet/wallet.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,11 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
10421042

10431043
//! Whether the (external) signer performs R-value signature grinding
10441044
bool CanGrindR() const;
1045+
1046+
//! Add scriptPubKeys for this ScriptPubKeyMan into the scriptPubKey cache
1047+
void CacheNewScriptPubKeys(const std::set<CScript>& spks, ScriptPubKeyMan* spkm);
1048+
1049+
void TopUpCallback(const std::set<CScript>& spks, ScriptPubKeyMan* spkm) override;
10451050
};
10461051

10471052
/**

0 commit comments

Comments
 (0)