diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c66b09628eb..45c3e902201 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1230,9 +1230,8 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet) return result; } -bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function& func) +static bool RunWithinTxn(WalletBatch& batch, std::string_view process_desc, const std::function& func) { - WalletBatch batch(database); if (!batch.TxnBegin()) { LogPrint(BCLog::WALLETDB, "Error: cannot create db txn for %s\n", process_desc); return false; @@ -1254,6 +1253,12 @@ bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const return true; } +bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function& func) +{ + WalletBatch batch(database); + return RunWithinTxn(batch, process_desc, func); +} + void MaybeCompactWalletDB(WalletContext& context) { static std::atomic fOneThread(false); @@ -1316,47 +1321,11 @@ bool WalletBatch::WriteWalletFlags(const uint64_t flags) bool WalletBatch::EraseRecords(const std::unordered_set& types) { - // Begin db txn - if (!m_batch->TxnBegin()) return false; - - // Get cursor - std::unique_ptr cursor = m_batch->GetNewCursor(); - if (!cursor) - { - return false; - } - - // Iterate the DB and look for any records that have the type prefixes - while (true) { - // Read next record - DataStream key{}; - DataStream value{}; - DatabaseCursor::Status status = cursor->Next(key, value); - if (status == DatabaseCursor::Status::DONE) { - break; - } else if (status == DatabaseCursor::Status::FAIL) { - cursor.reset(nullptr); - m_batch->TxnAbort(); // abort db txn - return false; - } - - // Make a copy of key to avoid data being deleted by the following read of the type - const SerializeData key_data{key.begin(), key.end()}; - - std::string type; - key >> type; - - if (types.count(type) > 0) { - if (!m_batch->Erase(Span{key_data})) { - cursor.reset(nullptr); - m_batch->TxnAbort(); - return false; // erase failed - } - } - } - // Finish db txn - cursor.reset(nullptr); - return m_batch->TxnCommit(); + return RunWithinTxn(*this, "erase records", [&types](WalletBatch& self) { + return std::all_of(types.begin(), types.end(), [&self](const std::string& type) { + return self.m_batch->ErasePrefix(DataStream() << type); + }); + }); } bool WalletBatch::TxnBegin()