Skip to content

Commit

Permalink
wallet: batch descriptor spkm TopUp
Browse files Browse the repository at this point in the history
Instead of performing multiple atomic write
operations per descriptor setup call, batch
them all within a single atomic db txn.
  • Loading branch information
furszy committed Nov 22, 2023
1 parent bb4554c commit 075aa44
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
16 changes: 14 additions & 2 deletions src/wallet/scriptpubkeyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2135,6 +2135,15 @@ std::map<CKeyID, CKey> DescriptorScriptPubKeyMan::GetKeys() const
}

bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
{
WalletBatch batch(m_storage.GetDatabase());
if (!batch.TxnBegin()) return false;
bool res = TopUpWithDB(batch, size);
if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during descriptors keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
return res;
}

bool DescriptorScriptPubKeyMan::TopUpWithDB(WalletBatch& batch, unsigned int size)
{
LOCK(cs_desc_man);
unsigned int target_size;
Expand All @@ -2157,7 +2166,6 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
FlatSigningProvider provider;
provider.keys = GetKeys();

WalletBatch batch(m_storage.GetDatabase());
uint256 id = GetID();
for (int32_t i = m_max_cached_index + 1; i < new_range_end; ++i) {
FlatSigningProvider out_keys;
Expand Down Expand Up @@ -2326,6 +2334,8 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_

// Store the master private key, and descriptor
WalletBatch batch(m_storage.GetDatabase());
if (!batch.TxnBegin()) throw std::runtime_error(std::string(__func__) + ": cannot start db transaction");

if (!AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey())) {
throw std::runtime_error(std::string(__func__) + ": writing descriptor master private key failed");
}
Expand All @@ -2334,9 +2344,11 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
}

// TopUp
TopUp();
TopUpWithDB(batch);

m_storage.UnsetBlankWalletFlag(batch);

if (!batch.TxnCommit()) throw std::runtime_error(std::string(__func__) + ": error committing db transaction");
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion src/wallet/scriptpubkeyman.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,10 @@ class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
std::unique_ptr<FlatSigningProvider> GetSigningProvider(int32_t index, bool include_private = false) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);

protected:
WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);
WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);

//! Same as 'TopUp' but designed for use within a batch transaction context
bool TopUpWithDB(WalletBatch& batch, unsigned int size = 0);

public:
DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size)
Expand Down

0 comments on commit 075aa44

Please sign in to comment.