aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/test
diff options
context:
space:
mode:
authorfurszy <matiasfurszyfer@protonmail.com>2024-02-06 16:28:23 -0300
committerfurszy <matiasfurszyfer@protonmail.com>2024-02-12 16:05:15 -0300
commit33757814ceb04102141d3fd5ef2f87abf0422310 (patch)
tree40f8af126fcb333f3d2c62e725f3b101155addf3 /src/wallet/test
parentcf4d72a75e9603e947b3d47e1f3ac7c7f37bb401 (diff)
downloadbitcoin-33757814ceb04102141d3fd5ef2f87abf0422310.tar.xz
wallet: bdb batch 'ErasePrefix', do not create txn internally
Transactions are intended to be started on upper layers rather than internally by the bdb batch object. This enables us to consolidate different write operations within a procedure in the same db txn, improving consistency due to the atomic property of the transaction, as well as its performance due to the reduction of disk write operations. Important Note: This approach also ensures that the BerkeleyBatch::ErasePrefix function behaves exactly as the SQLiteBatch::ErasePrefix function, which does not create a db txn internally. Furthermore, since the `BerkeleyBatch::ErasePrefix' implementation erases records one by one (by traversing the db), this change ensures that the function is always called within an active txn context. Without this measure, there's a potential risk to consistency; certain records may be removed while others could persist due to an internal failure during the procedure.
Diffstat (limited to 'src/wallet/test')
-rw-r--r--src/wallet/test/db_tests.cpp33
-rw-r--r--src/wallet/test/wallet_tests.cpp8
2 files changed, 38 insertions, 3 deletions
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index adbbb94318..c933366354 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -228,6 +228,39 @@ BOOST_AUTO_TEST_CASE(db_availability_after_write_error)
}
}
+// Verify 'ErasePrefix' functionality using db keys similar to the ones used by the wallet.
+// Keys are in the form of std::pair<TYPE, ENTRY_ID>
+BOOST_AUTO_TEST_CASE(erase_prefix)
+{
+ const std::string key = "key";
+ const std::string key2 = "key2";
+ const std::string value = "value";
+ const std::string value2 = "value_2";
+ auto make_key = [](std::string type, std::string id) { return std::make_pair(type, id); };
+
+ for (const auto& database : TestDatabases(m_path_root)) {
+ std::unique_ptr<DatabaseBatch> batch = database->MakeBatch();
+
+ // Write two entries with the same key type prefix, a third one with a different prefix
+ // and a fourth one with the type-id values inverted
+ BOOST_CHECK(batch->Write(make_key(key, value), value));
+ BOOST_CHECK(batch->Write(make_key(key, value2), value2));
+ BOOST_CHECK(batch->Write(make_key(key2, value), value));
+ BOOST_CHECK(batch->Write(make_key(value, key), value));
+
+ // Erase the ones with the same prefix and verify result
+ BOOST_CHECK(batch->TxnBegin());
+ BOOST_CHECK(batch->ErasePrefix(DataStream() << key));
+ BOOST_CHECK(batch->TxnCommit());
+
+ BOOST_CHECK(!batch->Exists(make_key(key, value)));
+ BOOST_CHECK(!batch->Exists(make_key(key, value2)));
+ // Also verify that entries with a different prefix were not erased
+ BOOST_CHECK(batch->Exists(make_key(key2, value)));
+ BOOST_CHECK(batch->Exists(make_key(value, key)));
+ }
+}
+
#ifdef USE_SQLITE
// Test-only statement execution error
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 7396a43c50..27a81b3669 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -445,9 +445,11 @@ BOOST_FIXTURE_TEST_CASE(LoadReceiveRequests, TestingSetup)
auto requests = wallet->GetAddressReceiveRequests();
auto erequests = {"val_rr11", "val_rr20"};
BOOST_CHECK_EQUAL_COLLECTIONS(requests.begin(), requests.end(), std::begin(erequests), std::end(erequests));
- WalletBatch batch{wallet->GetDatabase()};
- BOOST_CHECK(batch.WriteAddressPreviouslySpent(PKHash(), false));
- BOOST_CHECK(batch.EraseAddressData(ScriptHash()));
+ RunWithinTxn(wallet->GetDatabase(), /*process_desc*/"test", [](WalletBatch& batch){
+ BOOST_CHECK(batch.WriteAddressPreviouslySpent(PKHash(), false));
+ BOOST_CHECK(batch.EraseAddressData(ScriptHash()));
+ return true;
+ });
});
TestLoadWallet(name, format, [](std::shared_ptr<CWallet> wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet) {
BOOST_CHECK(!wallet->IsAddressPreviouslySpent(PKHash()));