test: Make duplicating MockableDatabases use cursor and batch

Instead of directly copying the stored records map when duplicating a
MockableDatabase, use a Cursor to read the records, and a Batch to write
them into the new database. This prepares for using SQLite as the
database backend for MockableDatabase.
This commit is contained in:
Ava Chow
2025-07-07 14:12:58 -07:00
parent 964eafb71c
commit e7d67c9fd9
2 changed files with 27 additions and 11 deletions

View File

@@ -105,7 +105,23 @@ void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database)
{
return std::make_unique<MockableDatabase>(dynamic_cast<MockableDatabase&>(database).m_records);
std::unique_ptr<DatabaseBatch> batch_orig = database.MakeBatch();
std::unique_ptr<DatabaseCursor> cursor_orig = batch_orig->GetNewCursor();
std::unique_ptr<WalletDatabase> new_db = std::make_unique<MockableDatabase>();
std::unique_ptr<DatabaseBatch> new_db_batch = new_db->MakeBatch();
MockableBatch* batch_new = dynamic_cast<MockableBatch*>(new_db_batch.get());
Assert(batch_new);
while (true) {
DataStream key, value;
DatabaseCursor::Status status = cursor_orig->Next(key, value);
Assert(status != DatabaseCursor::Status::FAIL);
if (status != DatabaseCursor::Status::MORE) break;
batch_new->WriteKey(std::move(key), std::move(value));
}
return new_db;
}
std::string getnewaddress(CWallet& w)
@@ -208,9 +224,9 @@ bool MockableBatch::ErasePrefix(std::span<const std::byte> prefix)
return true;
}
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records)
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase()
{
return std::make_unique<MockableDatabase>(records);
return std::make_unique<MockableDatabase>();
}
MockableDatabase& GetMockableDatabase(CWallet& wallet)

View File

@@ -68,18 +68,18 @@ private:
MockableData& m_records;
bool m_pass;
bool ReadKey(DataStream&& key, DataStream& value) override;
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite=true) override;
bool EraseKey(DataStream&& key) override;
bool HasKey(DataStream&& key) override;
bool ErasePrefix(std::span<const std::byte> prefix) override;
public:
explicit MockableBatch(MockableData& records, bool pass) : m_records(records), m_pass(pass) {}
~MockableBatch() = default;
void Close() override {}
bool ReadKey(DataStream&& key, DataStream& value) override;
bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite=true) override;
bool EraseKey(DataStream&& key) override;
bool HasKey(DataStream&& key) override;
bool ErasePrefix(std::span<const std::byte> prefix) override;
std::unique_ptr<DatabaseCursor> GetNewCursor() override
{
return std::make_unique<MockableCursor>(m_records, m_pass);
@@ -101,7 +101,7 @@ public:
MockableData m_records;
bool m_pass{true};
MockableDatabase(MockableData records = {}) : WalletDatabase(), m_records(records) {}
MockableDatabase() : WalletDatabase() {}
~MockableDatabase() = default;
void Open() override {}
@@ -116,7 +116,7 @@ public:
std::unique_ptr<DatabaseBatch> MakeBatch() override { return std::make_unique<MockableBatch>(m_records, m_pass); }
};
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {});
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase();
MockableDatabase& GetMockableDatabase(CWallet& wallet);
DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, bool success);