wallet: migration, batch addressbook records removal

Instead of doing one db transaction per removed record,
we now batch all removals in a single db transaction.

Speeding up the process and preventing the wallet from entering
an inconsistent state when any of the intermediate writes fail.
This commit is contained in:
furszy 2023-09-29 15:42:15 -03:00
parent 342c45f80e
commit 86960cdb7f
No known key found for this signature in database
GPG Key ID: 5DD23CCC686AA623
2 changed files with 11 additions and 2 deletions

View File

@ -2395,8 +2395,13 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
bool CWallet::DelAddressBook(const CTxDestination& address)
{
const std::string& dest = EncodeDestination(address);
WalletBatch batch(GetDatabase());
return DelAddressBookWithDB(batch, address);
}
bool CWallet::DelAddressBookWithDB(WalletBatch& batch, const CTxDestination& address)
{
const std::string& dest = EncodeDestination(address);
{
LOCK(cs_wallet);
// If we want to delete receiving addresses, we should avoid calling EraseAddressData because it will delete the previously_spent value. Could instead just erase the label so it becomes a change address, and keep the data.
@ -4079,14 +4084,17 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
}
// Remove the things to delete in this wallet
WalletBatch local_wallet_batch(GetDatabase());
local_wallet_batch.TxnBegin();
if (dests_to_delete.size() > 0) {
for (const auto& dest : dests_to_delete) {
if (!DelAddressBook(dest)) {
if (!DelAddressBookWithDB(local_wallet_batch, dest)) {
error = _("Error: Unable to remove watchonly address book data");
return false;
}
}
}
local_wallet_batch.TxnCommit();
// Connect the SPKM signals
ConnectScriptPubKeyManNotifiers();

View File

@ -795,6 +795,7 @@ public:
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose);
bool DelAddressBook(const CTxDestination& address);
bool DelAddressBookWithDB(WalletBatch& batch, const CTxDestination& address);
bool IsAddressPreviouslySpent(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressPreviouslySpent(WalletBatch& batch, const CTxDestination& dest, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);