diff options
author | merge-script <fanquake@gmail.com> | 2024-05-21 10:05:09 +0100 |
---|---|---|
committer | merge-script <fanquake@gmail.com> | 2024-05-21 10:05:09 +0100 |
commit | 5acdc2b97dcd756a15d28d75bce9a9d3e3953f9f (patch) | |
tree | 8e82974017d9993a77481a3c2896f3a258054c28 /src/wallet/test/db_tests.cpp | |
parent | ecd23656db174adef61d3bd753d02698c3528192 (diff) | |
parent | d51fbab4b32d56765e8faab6ad01245fb259b0ca (diff) | |
download | bitcoin-5acdc2b97dcd756a15d28d75bce9a9d3e3953f9f.tar.xz |
Merge bitcoin/bitcoin#26606: wallet: Implement independent BDB parser
d51fbab4b32d56765e8faab6ad01245fb259b0ca wallet, test: Be able to always swap BDB endianness (Ava Chow)
0b753156ce60c29efb2386954ba7555ad8f642f5 test: Test bdb_ro dump of wallet without reset LSNs (Ava Chow)
c1984f128284589423b7e0cc06c9a3b23a242d95 test: Test dumping dbs with overflow pages (Ava Chow)
fd7b16e391ed320e35255157a28be14c947ef30a test: Test dumps of other endian BDB files (Ava Chow)
6ace3e953f0864bd7818f040c59a1bc70aa47512 bdb: Be able to make byteswapped databases (Ava Chow)
d9878903fb34939dee8e1462f079acc68110253d Error if LSNs are not reset (Ava Chow)
4d7a3ae78e55f25868979f1bd920857a4aecb825 Berkeley RO Database fuzz test (TheCharlatan)
3568dce9e93295674cdf5458c5bdf93ff01fd0a2 tests: Add BerkeleyRO to db prefix tests (Ava Chow)
70cfbfdadf16d3b115309c6938f07ef5b96c7cc1 wallettool: Optionally use BERKELEY_RO as format when dumping BDB wallets (Ava Chow)
dd57713f6ede3d46e97ee7df87c10001b0bf4c3d Add MakeBerkeleyRODatabase (Ava Chow)
6e50bee67d1d58aecd8a0ce8b7c3f5a7979365f5 Implement handling of other endianness in BerkeleyRODatabase (Ava Chow)
cdd61c9cc108df8e13f4e3891ff2c96355b3ee38 wallet: implement independent BDB deserializer in BerkeleyRODatabase (Ava Chow)
ecba23097955dad7208baa687fc405c846aee794 wallet: implement BerkeleyRODatabase::Backup (Ava Chow)
0c8e72847603540bb29b8b8aeb80fa3f2e3a2c9a wallet: implement BerkeleyROBatch (Ava Chow)
756ff9b478484b17c4a6e65c171c2e4fecb21ad4 wallet: add dummy BerkeleyRODatabase and BerkeleyROBatch classes (Ava Chow)
ca18aea5c4975ace4e307be96c74641d203fa389 Add AutoFile::seek and tell (Ava Chow)
Pull request description:
Split from #26596
This PR adds `BerkeleyRODatabase` which is an independent implementation of a BDB file parser. It provides read only access to a BDB file, and can therefore be used as a read only database backend for wallets. This will be used for dumping legacy wallet records and migrating legacy wallets without the need for BDB itself.
Wallettool's `dump` command is changed to use `BerkeleyRODatabase` instead of `BerkeleyDatabase` (and `CWallet` itself) to demonstrate that this parser works and to test it against the existing wallettool functional tests.
ACKs for top commit:
josibake:
reACK https://github.com/bitcoin/bitcoin/commit/d51fbab4b32d56765e8faab6ad01245fb259b0ca
TheCharlatan:
Re-ACK d51fbab4b32d56765e8faab6ad01245fb259b0ca
furszy:
reACK d51fbab4b32d56765e8faab6ad01245fb259b0ca
laanwj:
re-ACK d51fbab4b32d56765e8faab6ad01245fb259b0ca
theStack:
ACK d51fbab4b32d56765e8faab6ad01245fb259b0ca
Tree-SHA512: 1e7b97edf223b2974eed2e9eac1179fc82bb6359e0a66b7d2a0c8b9fa515eae9ea036f1edf7c76cdab2e75ad994962b134b41056ccfbc33b8d54f0859e86657b
Diffstat (limited to 'src/wallet/test/db_tests.cpp')
-rw-r--r-- | src/wallet/test/db_tests.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp index 438dfceb7f..2fac356263 100644 --- a/src/wallet/test/db_tests.cpp +++ b/src/wallet/test/db_tests.cpp @@ -16,6 +16,7 @@ #ifdef USE_SQLITE #include <wallet/sqlite.h> #endif +#include <wallet/migrate.h> #include <wallet/test/util.h> #include <wallet/walletutil.h> // for WALLET_FLAG_DESCRIPTORS @@ -132,6 +133,8 @@ static std::vector<std::unique_ptr<WalletDatabase>> TestDatabases(const fs::path bilingual_str error; #ifdef USE_BDB dbs.emplace_back(MakeBerkeleyDatabase(path_root / "bdb", options, status, error)); + // Needs BDB to make the DB to read + dbs.emplace_back(std::make_unique<BerkeleyRODatabase>(BDBDataFile(path_root / "bdb"), /*open=*/false)); #endif #ifdef USE_SQLITE dbs.emplace_back(MakeSQLiteDatabase(path_root / "sqlite", options, status, error)); @@ -146,11 +149,16 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_range_test) for (const auto& database : TestDatabases(m_path_root)) { std::vector<std::string> prefixes = {"", "FIRST", "SECOND", "P\xfe\xff", "P\xff\x01", "\xff\xff"}; - // Write elements to it std::unique_ptr<DatabaseBatch> handler = Assert(database)->MakeBatch(); - for (unsigned int i = 0; i < 10; i++) { - for (const auto& prefix : prefixes) { - BOOST_CHECK(handler->Write(std::make_pair(prefix, i), i)); + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // For BerkeleyRO, open the file now. This must happen after BDB has written to the file + database->Open(); + } else { + // Write elements to it if not berkeleyro + for (unsigned int i = 0; i < 10; i++) { + for (const auto& prefix : prefixes) { + BOOST_CHECK(handler->Write(std::make_pair(prefix, i), i)); + } } } @@ -178,6 +186,8 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_range_test) // Let's now read it once more, it should return DONE BOOST_CHECK(cursor->Next(key, value) == DatabaseCursor::Status::DONE); } + handler.reset(); + database->Close(); } } @@ -197,13 +207,23 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_byte_test) ffs{StringData("\xff\xffsuffix"), StringData("ffs")}; for (const auto& database : TestDatabases(m_path_root)) { std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); - for (const auto& [k, v] : {e, p, ps, f, fs, ff, ffs}) { - batch->Write(Span{k}, Span{v}); + + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // For BerkeleyRO, open the file now. This must happen after BDB has written to the file + database->Open(); + } else { + // Write elements to it if not berkeleyro + for (const auto& [k, v] : {e, p, ps, f, fs, ff, ffs}) { + batch->Write(Span{k}, Span{v}); + } } + CheckPrefix(*batch, StringBytes(""), {e, p, ps, f, fs, ff, ffs}); CheckPrefix(*batch, StringBytes("prefix"), {p, ps}); CheckPrefix(*batch, StringBytes("\xff"), {f, fs, ff, ffs}); CheckPrefix(*batch, StringBytes("\xff\xff"), {ff, ffs}); + batch.reset(); + database->Close(); } } @@ -213,6 +233,10 @@ BOOST_AUTO_TEST_CASE(db_availability_after_write_error) // To simulate the behavior, record overwrites are disallowed, and the test verifies // that the database remains active after failing to store an existing record. for (const auto& database : TestDatabases(m_path_root)) { + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // Skip this test if BerkeleyRO + continue; + } // Write original record std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); std::string key = "key"; @@ -241,6 +265,10 @@ BOOST_AUTO_TEST_CASE(erase_prefix) auto make_key = [](std::string type, std::string id) { return std::make_pair(type, id); }; for (const auto& database : TestDatabases(m_path_root)) { + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // Skip this test if BerkeleyRO + continue; + } std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); // Write two entries with the same key type prefix, a third one with a different prefix |