aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/walletdb.cpp
diff options
context:
space:
mode:
authorfurszy <matiasfurszyfer@protonmail.com>2022-12-05 18:04:56 -0300
committerfurszy <matiasfurszyfer@protonmail.com>2023-05-15 12:23:15 -0300
commit12daf6fcdcbf5c7f03038338d843df3877714b24 (patch)
tree39311f5f6bf52be19d095d1e24c7ba3bb1be0bef /src/wallet/walletdb.cpp
parent043fcb0b053eee6021cc75e3d3f41097f52698c0 (diff)
downloadbitcoin-12daf6fcdcbf5c7f03038338d843df3877714b24.tar.xz
walletdb: scope bdb::EraseRecords under a single db txn
so we erase all the records atomically or abort the entire procedure. and, at the same time, we can share the same db txn context for the db cursor and the erase functionality. extra note from the Db.cursor doc: "If transaction protection is enabled, cursors must be opened and closed within the context of a transaction" thus why added a `CloseCursor` call before calling to `TxnAbort/TxnCommit`.
Diffstat (limited to 'src/wallet/walletdb.cpp')
-rw-r--r--src/wallet/walletdb.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 072357022e..9a6c5afba6 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1136,6 +1136,9 @@ bool WalletBatch::WriteWalletFlags(const uint64_t flags)
bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
{
+ // Begin db txn
+ if (!m_batch->TxnBegin()) return false;
+
// Get cursor
std::unique_ptr<DatabaseCursor> cursor = m_batch->GetNewCursor();
if (!cursor)
@@ -1144,8 +1147,7 @@ bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
}
// Iterate the DB and look for any records that have the type prefixes
- while (true)
- {
+ while (true) {
// Read next record
DataStream key{};
DataStream value{};
@@ -1153,6 +1155,8 @@ bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
if (status == DatabaseCursor::Status::DONE) {
break;
} else if (status == DatabaseCursor::Status::FAIL) {
+ cursor.reset(nullptr);
+ m_batch->TxnAbort(); // abort db txn
return false;
}
@@ -1163,10 +1167,16 @@ bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
key >> type;
if (types.count(type) > 0) {
- m_batch->Erase(key_data);
+ if (!m_batch->Erase(key_data)) {
+ cursor.reset(nullptr);
+ m_batch->TxnAbort();
+ return false; // erase failed
+ }
}
}
- return true;
+ // Finish db txn
+ cursor.reset(nullptr);
+ return m_batch->TxnCommit();
}
bool WalletBatch::TxnBegin()