0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-06 14:19:59 -05:00

wallet: simplify EraseRecords by using 'ErasePrefix'

This commit is contained in:
furszy 2024-02-06 10:25:48 -03:00
parent 33757814ce
commit 77331aa2a1
No known key found for this signature in database
GPG key ID: 5DD23CCC686AA623

View file

@ -1230,9 +1230,8 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
return result; return result;
} }
bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function<bool(WalletBatch&)>& func) static bool RunWithinTxn(WalletBatch& batch, std::string_view process_desc, const std::function<bool(WalletBatch&)>& func)
{ {
WalletBatch batch(database);
if (!batch.TxnBegin()) { if (!batch.TxnBegin()) {
LogPrint(BCLog::WALLETDB, "Error: cannot create db txn for %s\n", process_desc); LogPrint(BCLog::WALLETDB, "Error: cannot create db txn for %s\n", process_desc);
return false; return false;
@ -1254,6 +1253,12 @@ bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const
return true; return true;
} }
bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function<bool(WalletBatch&)>& func)
{
WalletBatch batch(database);
return RunWithinTxn(batch, process_desc, func);
}
void MaybeCompactWalletDB(WalletContext& context) void MaybeCompactWalletDB(WalletContext& context)
{ {
static std::atomic<bool> fOneThread(false); static std::atomic<bool> fOneThread(false);
@ -1316,47 +1321,11 @@ bool WalletBatch::WriteWalletFlags(const uint64_t flags)
bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types) bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
{ {
// Begin db txn return RunWithinTxn(*this, "erase records", [&types](WalletBatch& self) {
if (!m_batch->TxnBegin()) return false; return std::all_of(types.begin(), types.end(), [&self](const std::string& type) {
return self.m_batch->ErasePrefix(DataStream() << type);
// Get cursor });
std::unique_ptr<DatabaseCursor> 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();
} }
bool WalletBatch::TxnBegin() bool WalletBatch::TxnBegin()