Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/bench/coin_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <wallet/coinselection.h>
#include <wallet/spend.h>
#include <wallet/wallet.h>
#include <wallet/test/util.h>

#include <set>

Expand All @@ -16,7 +17,7 @@ using wallet::CHANGE_LOWER;
using wallet::CoinEligibilityFilter;
using wallet::CoinSelectionParams;
using wallet::COutput;
using wallet::CreateDummyWalletDatabase;
using wallet::CreateMockableWalletDatabase;
using wallet::CWallet;
using wallet::CWalletTx;
using wallet::OutputGroup;
Expand All @@ -43,7 +44,7 @@ static void CoinSelection(benchmark::Bench& bench)
{
NodeContext node;
auto chain = interfaces::MakeChain(node);
CWallet wallet(chain.get(), /*coinjoin_loader=*/nullptr, "", gArgs, CreateDummyWalletDatabase());
CWallet wallet(chain.get(), /*coinjoin_loader=*/nullptr, "", gArgs, CreateMockableWalletDatabase());
std::vector<std::unique_ptr<CWalletTx>> wtxs;
LOCK(wallet.cs_wallet);

Expand Down
4 changes: 2 additions & 2 deletions src/bench/wallet_balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <optional>

using wallet::CreateMockWalletDatabase;
using wallet::CreateMockableWalletDatabase;
using wallet::CWallet;
using wallet::DBErrors;
using wallet::WALLET_FLAG_DESCRIPTORS;
Expand All @@ -24,7 +24,7 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
const auto& ADDRESS_WATCHONLY = ADDRESS_B58T_UNSPENDABLE;

CWallet wallet{test_setup->m_node.chain.get(), test_setup->m_node.coinjoin_loader.get(), "", gArgs, CreateMockWalletDatabase()};
CWallet wallet{test_setup->m_node.chain.get(), test_setup->m_node.coinjoin_loader.get(), "", gArgs, CreateMockableWalletDatabase()};
{
LOCK(wallet.cs_wallet);
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down
50 changes: 13 additions & 37 deletions src/bench/wallet_loading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@
#include <optional>

using wallet::CWallet;
using wallet::DatabaseFormat;
using wallet::DatabaseOptions;
using wallet::CreateMockableWalletDatabase;
using wallet::TxStateInactive;
using wallet::WALLET_FLAG_DESCRIPTORS;
using wallet::WalletContext;
using wallet::WalletDatabase;

static std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options)
static std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags)
{
bilingual_str error;
std::vector<bilingual_str> warnings;
auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings);
auto wallet = CWallet::Create(context, "", std::move(database), create_flags, error, warnings);
NotifyWalletLoaded(context, wallet);
if (context.chain) {
wallet->postInitProcess();
Expand All @@ -52,66 +51,43 @@ static void AddTx(CWallet& wallet)
wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInactive{});
}

static std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database, DatabaseOptions& options)
static std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database)
{
auto new_database = CreateMockWalletDatabase(options);

// Get a cursor to the original database
auto batch = database.MakeBatch();
batch->StartCursor();

// Get a batch for the new database
auto new_batch = new_database->MakeBatch();

// Read all records from the original database and write them to the new one
while (true) {
CDataStream key(SER_DISK, CLIENT_VERSION);
CDataStream value(SER_DISK, CLIENT_VERSION);
bool complete;
batch->ReadAtCursor(key, value, complete);
if (complete) break;
new_batch->Write(key, value);
}

return new_database;
return std::make_unique<MockableDatabase>(dynamic_cast<MockableDatabase&>(database).m_records);
}

static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet)
{
const auto test_setup = MakeNoLogFileContext<TestingSetup>();
test_setup->m_args.ForceSetArg("-unsafesqlitesync", "1");

WalletContext context;
context.args = &test_setup->m_args;
context.chain = test_setup->m_node.chain.get();

// Setup the wallet
// Loading the wallet will also create it
DatabaseOptions options;
if (legacy_wallet) {
options.require_format = DatabaseFormat::BERKELEY;
} else {
options.create_flags = WALLET_FLAG_DESCRIPTORS;
options.require_format = DatabaseFormat::SQLITE;
uint64_t create_flags = 0;
if (!legacy_wallet) {
create_flags = WALLET_FLAG_DESCRIPTORS;
}
auto database = CreateMockWalletDatabase(options);
auto wallet = BenchLoadWallet(std::move(database), context, options);
auto database = CreateMockableWalletDatabase();
auto wallet = BenchLoadWallet(std::move(database), context, create_flags);

// Generate a bunch of transactions and addresses to put into the wallet
for (int i = 0; i < 1000; ++i) {
AddTx(*wallet);
}

database = DuplicateMockDatabase(wallet->GetDatabase(), options);
database = DuplicateMockDatabase(wallet->GetDatabase());

// reload the wallet for the actual benchmark
BenchUnloadWallet(std::move(wallet));

bench.epochs(5).run([&] {
wallet = BenchLoadWallet(std::move(database), context, options);
wallet = BenchLoadWallet(std::move(database), context, create_flags);

// Cleanup
database = DuplicateMockDatabase(wallet->GetDatabase(), options);
database = DuplicateMockDatabase(wallet->GetDatabase());
BenchUnloadWallet(std::move(wallet));
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/qt/test/addressbooktests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <key.h>
#include <key_io.h>
#include <wallet/wallet.h>
#include <wallet/test/util.h>
#include <walletinitinterface.h>

#include <chrono>
Expand All @@ -29,7 +30,7 @@
#include <QTimer>

using wallet::AddWallet;
using wallet::CreateMockWalletDatabase;
using wallet::CreateMockableWalletDatabase;
using wallet::CWallet;
using wallet::RemoveWallet;
using wallet::WALLET_FLAG_DESCRIPTORS;
Expand Down Expand Up @@ -72,7 +73,7 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
{
TestChain100Setup test;
node.setContext(&test.m_node);
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), node.context()->coinjoin_loader.get(), "", gArgs, CreateMockWalletDatabase());
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), node.context()->coinjoin_loader.get(), "", gArgs, CreateMockableWalletDatabase());
wallet->LoadWallet();
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
{
Expand Down
5 changes: 3 additions & 2 deletions src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <key_io.h>
#include <test/util/setup_common.h>
#include <validation.h>
#include <wallet/test/util.h>
#include <wallet/wallet.h>
#include <qt/overviewpage.h>
#include <qt/receivecoinsdialog.h>
Expand All @@ -43,7 +44,7 @@

using wallet::AddWallet;
using wallet::CWallet;
using wallet::CreateMockWalletDatabase;
using wallet::CreateMockableWalletDatabase;
using wallet::RemoveWallet;
using wallet::WALLET_FLAG_DESCRIPTORS;
using wallet::WalletContext;
Expand Down Expand Up @@ -121,7 +122,7 @@ void TestGUI(interfaces::Node& node)
}
node.setContext(&test.m_node);
WalletContext& context = *node.walletLoader().context();
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), node.context()->coinjoin_loader.get(), "", gArgs, CreateMockWalletDatabase());
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), node.context()->coinjoin_loader.get(), "", gArgs, CreateMockableWalletDatabase());
AddWallet(context, wallet);
wallet->LoadWallet();
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down
9 changes: 9 additions & 0 deletions src/test/util/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ std::string getnewaddress(CWallet& w)
return EncodeDestination(*Assert(w.GetNewDestination("")));
}

std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(std::map<SerializeData, SerializeData> records)
{
return std::make_unique<MockableDatabase>(records);
}

MockableDatabase& GetMockableDatabase(CWallet& wallet)
{
return dynamic_cast<MockableDatabase&>(wallet.GetDatabase());
}
// void importaddress(CWallet& wallet, const std::string& address)
// {
// auto spk_man = wallet.GetLegacyScriptPubKeyMan();
Expand Down
41 changes: 0 additions & 41 deletions src/wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,47 +158,6 @@ class WalletDatabase
virtual bool SupportsAutoBackup() { return false; }
};

/** RAII class that provides access to a DummyDatabase. Never fails. */
class DummyBatch : public DatabaseBatch
{
private:
bool ReadKey(CDataStream&& key, CDataStream& value) override { return true; }
bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) override { return true; }
bool EraseKey(CDataStream&& key) override { return true; }
bool HasKey(CDataStream&& key) override { return true; }

public:
void Flush() override {}
void Close() override {}

bool StartCursor() override { return true; }
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override { return true; }
void CloseCursor() override {}
bool TxnBegin() override { return true; }
bool TxnCommit() override { return true; }
bool TxnAbort() override { return true; }
};

/** A dummy WalletDatabase that does nothing and never fails. Only used by unit tests.
**/
class DummyDatabase : public WalletDatabase
{
public:
void Open() override {};
void AddRef() override {}
void RemoveRef() override {}
bool Rewrite(const char* pszSkip=nullptr) override { return true; }
bool Backup(const std::string& strDest) const override { return true; }
void Close() override {}
void Flush() override {}
bool PeriodicFlush() override { return true; }
void IncrementUpdateCounter() override { ++nUpdateCounter; }
void ReloadDbEnv() override {}
std::string Filename() override { return "dummy"; }
std::string Format() override { return "dummy"; }
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<DummyBatch>(); }
};

enum class DatabaseFormat {
BERKELEY,
SQLITE,
Expand Down
44 changes: 43 additions & 1 deletion src/wallet/salvage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,48 @@ static bool KeyFilter(const std::string& type)
return WalletBatch::IsKeyType(type) || type == DBKeys::HDCHAIN;
}

/** RAII class that provides access to a DummyDatabase. Never fails. */
class DummyBatch : public DatabaseBatch
{
private:
bool ReadKey(CDataStream&& key, CDataStream& value) override { return true; }
bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) override { return true; }
bool EraseKey(CDataStream&& key) override { return true; }
bool HasKey(CDataStream&& key) override { return true; }

public:
void Flush() override {}
void Close() override {}

bool StartCursor() override { return true; }
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override { return true; }
void CloseCursor() override {}
bool TxnBegin() override { return true; }
bool TxnCommit() override { return true; }
bool TxnAbort() override { return true; }
};

/** A dummy WalletDatabase that does nothing and never fails. Only used by unit tests.
**/
class DummyDatabase : public WalletDatabase
{
public:
void Open() override {};
void AddRef() override {}
void RemoveRef() override {}
bool Rewrite(const char* pszSkip=nullptr) override { return true; }
bool Backup(const std::string& strDest) const override { return true; }
void Close() override {}
void Flush() override {}
bool PeriodicFlush() override { return true; }
void IncrementUpdateCounter() override { ++nUpdateCounter; }
void ReloadDbEnv() override {}
std::string Filename() override { return "dummy"; }
std::string Format() override { return "dummy"; }
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<DummyBatch>(); }
};


bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
DatabaseOptions options;
Expand Down Expand Up @@ -135,7 +177,7 @@ bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bil
}

DbTxn* ptxn = env->TxnBegin();
CWallet dummyWallet(/*chain=*/nullptr, /*coinjoin_loader=*/nullptr, "", gArgs, CreateDummyWalletDatabase());
CWallet dummyWallet(/*chain=*/nullptr, /*coinjoin_loader=*/nullptr, "", gArgs, std::make_unique<DummyDatabase>());
dummyWallet.SetupLegacyScriptPubKeyMan();
for (KeyValPair& row : salvagedData)
{
Expand Down
15 changes: 8 additions & 7 deletions src/wallet/test/coinselector_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <wallet/coincontrol.h>
#include <wallet/coinselection.h>
#include <wallet/spend.h>
#include <wallet/test/util.h>
#include <wallet/test/wallet_test_fixture.h>
#include <wallet/wallet.h>

Expand Down Expand Up @@ -297,7 +298,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
coin_selection_params_bnb.m_subtract_fee_outputs = true;

{
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand All @@ -319,7 +320,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
}

{
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand All @@ -338,7 +339,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
BOOST_CHECK(result10);
}
{
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down Expand Up @@ -400,7 +401,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
FastRandomContext rand{};
const auto temp1{[&rand](std::vector<OutputGroup>& g, const CAmount& v, CAmount c) { return KnapsackSolver(g, v, c, rand); }};
const auto KnapsackSolver{temp1};
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down Expand Up @@ -710,7 +711,7 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
{
FastRandomContext rand{};
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand All @@ -732,7 +733,7 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
// Tests that with the ideal conditions, the coin selector will always be able to find a solution that can pay the target value
BOOST_AUTO_TEST_CASE(SelectCoins_test)
{
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down Expand Up @@ -918,7 +919,7 @@ BOOST_AUTO_TEST_CASE(effective_value_test)
/* --------------------------- Dash-specific tests start here --------------------------- */
BOOST_AUTO_TEST_CASE(minimum_inputs_test)
{
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockWalletDatabase());
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), /*coinjoin_loader=*/nullptr, "", m_args, CreateMockableWalletDatabase());
wallet->LoadWallet();
LOCK(wallet->cs_wallet);
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
Expand Down
Loading
Loading