wallet: batch MigrateToDescriptor() db transactions

Grouping all db writes into a single atomic write operation.
Speeding up the flow and preventing inconsistent states.
This commit is contained in:
furszy
2023-09-30 08:57:18 -03:00
parent 66c9936455
commit f2541d09e1
2 changed files with 20 additions and 6 deletions

View File

@@ -1807,6 +1807,12 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
keyid_it++;
}
WalletBatch batch(m_storage.GetDatabase());
if (!batch.TxnBegin()) {
LogPrintf("Error generating descriptors for migration, cannot initialize db transaction\n");
return std::nullopt;
}
// keyids is now all non-HD keys. Each key will have its own combo descriptor
for (const CKeyID& keyid : keyids) {
CKey key;
@@ -1837,8 +1843,8 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
desc_spk_man->TopUp();
WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.GetPubKey()));
desc_spk_man->TopUpWithDB(batch);
auto desc_spks = desc_spk_man->GetScriptPubKeys();
// Remove the scriptPubKeys from our current set
@@ -1883,8 +1889,8 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
desc_spk_man->AddDescriptorKey(master_key.key, master_key.key.GetPubKey());
desc_spk_man->TopUp();
WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey()));
desc_spk_man->TopUpWithDB(batch);
auto desc_spks = desc_spk_man->GetScriptPubKeys();
// Remove the scriptPubKeys from our current set
@@ -1950,9 +1956,9 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
if (!GetKey(keyid, key)) {
continue;
}
desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.GetPubKey()));
}
desc_spk_man->TopUp();
desc_spk_man->TopUpWithDB(batch);
auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
@@ -2019,6 +2025,13 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
// Make sure that we have accounted for all scriptPubKeys
assert(spks.size() == 0);
// Finalize transaction
if (!batch.TxnCommit()) {
LogPrintf("Error generating descriptors for migration, cannot commit db transaction\n");
return std::nullopt;
}
return out;
}