diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 7fa85505e0b2..d59f65985291 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -243,7 +243,8 @@ BITCOIN_TESTS += \ wallet/test/ismine_tests.cpp \ wallet/test/rpc_util_tests.cpp \ wallet/test/scriptpubkeyman_tests.cpp \ - wallet/test/walletload_tests.cpp + wallet/test/walletload_tests.cpp \ + wallet/test/group_outputs_tests.cpp FUZZ_SUITE_LD_COMMON +=\ $(SQLITE_LIBS) \ @@ -256,6 +257,7 @@ endif FUZZ_WALLET_SRC = \ wallet/test/fuzz/coincontrol.cpp \ wallet/test/fuzz/coinselection.cpp \ + wallet/test/fuzz/fees.cpp \ wallet/test/fuzz/parse_iso8601.cpp if USE_SQLITE diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 634afe91696d..4999b0cb8def 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -17,7 +18,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; @@ -44,7 +45,7 @@ static void CoinSelection(benchmark::Bench& bench) { NodeContext node; auto chain = interfaces::MakeChain(node); - CWallet wallet(chain.get(), "", CreateDummyWalletDatabase()); + CWallet wallet(chain.get(), "", CreateMockableWalletDatabase()); std::vector> wtxs; LOCK(wallet.cs_wallet); @@ -73,8 +74,9 @@ static void CoinSelection(benchmark::Bench& bench) /*tx_noinputs_size=*/ 0, /*avoid_partial=*/ false, }; + auto group = wallet::GroupOutputs(wallet, available_coins, coin_selection_params, {{filter_standard}})[filter_standard]; bench.run([&] { - auto result = AttemptSelection(wallet, 1003 * COIN, filter_standard, available_coins, coin_selection_params, /*allow_mixed_output_types=*/true); + auto result = AttemptSelection(wallet, 1003 * COIN, group, coin_selection_params, /*allow_mixed_output_types=*/true); assert(result); assert(result->GetSelectedValue() == 1003 * COIN); assert(result->GetInputSet().size() == 2); @@ -89,7 +91,7 @@ static void add_coin(const CAmount& nValue, int nInput, std::vector tx.vout[nInput].nValue = nValue; COutput output(COutPoint(tx.GetHash(), nInput), tx.vout.at(nInput), /*depth=*/ 0, /*input_bytes=*/ -1, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ true, /*fees=*/ 0); set.emplace_back(); - set.back().Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false); + set.back().Insert(std::make_shared(output), /*ancestors=*/ 0, /*descendants=*/ 0); } // Copied from src/wallet/test/coinselector_tests.cpp static CAmount make_hard_case(int utxos, std::vector& utxo_pool) diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index 578dae5137dd..2a97a32a97e7 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -15,13 +15,7 @@ #include -using wallet::CreateMockWalletDatabase; -using wallet::CWallet; -using wallet::DBErrors; -using wallet::WALLET_FLAG_DESCRIPTORS; - -const std::string ADDRESS_B58T_UNSPENDABLE = "yXXXXXXXXXXXXXXXXXXXXXXXXXXXVd2rXU"; - +namespace wallet { static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const bool add_mine, const uint32_t epoch_iters) { const auto test_setup = MakeNoLogFileContext(); @@ -31,12 +25,11 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b // Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process. // The reason is 'generatetoaddress', which creates a chain with deterministic timestamps in the past. SetMockTime(test_setup->m_node.chainman->GetParams().GenesisBlock().nTime); - CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()}; + CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()}; { LOCK(wallet.cs_wallet); wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); wallet.SetupDescriptorScriptPubKeyMans("", ""); - if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false); } auto handler = test_setup->m_node.chain->handleNotifications({&wallet, [](CWallet*) {}}); @@ -66,3 +59,4 @@ BENCHMARK(WalletBalanceDirty, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceClean, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceMine, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceWatch, benchmark::PriorityLevel::HIGH); +} // namespace wallet diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp index 022234c40298..17c249641518 100644 --- a/src/bench/wallet_create_tx.cpp +++ b/src/bench/wallet_create_tx.cpp @@ -15,7 +15,7 @@ #include using wallet::CWallet; -using wallet::CreateMockWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::DBErrors; using wallet::WALLET_FLAG_DESCRIPTORS; @@ -84,7 +84,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type { const auto test_setup = MakeNoLogFileContext(); - CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()}; + CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()}; { LOCK(wallet.cs_wallet); wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); @@ -137,7 +137,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type static void AvailableCoins(benchmark::Bench& bench, const std::vector& output_type) { const auto test_setup = MakeNoLogFileContext(); - CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()}; + CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()}; { LOCK(wallet.cs_wallet); wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index 0b0574eceaa5..5acaae1e0431 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -20,33 +20,7 @@ #include -using wallet::CWallet; -using wallet::DatabaseFormat; -using wallet::DatabaseOptions; -using wallet::TxStateInactive; -using wallet::WALLET_FLAG_DESCRIPTORS; -using wallet::WalletContext; -using wallet::WalletDatabase; - -static std::shared_ptr BenchLoadWallet(std::unique_ptr database, WalletContext& context, DatabaseOptions& options) -{ - bilingual_str error; - std::vector warnings; - auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings); - NotifyWalletLoaded(context, wallet); - if (context.chain) { - wallet->postInitProcess(); - } - return wallet; -} - -static void BenchUnloadWallet(std::shared_ptr&& wallet) -{ - SyncWithValidationInterfaceQueue(); - wallet->m_chain_notifications_handler.reset(); - UnloadWallet(std::move(wallet)); -} - +namespace wallet{ static void AddTx(CWallet& wallet) { CMutableTransaction mtx; @@ -59,7 +33,6 @@ static void AddTx(CWallet& wallet) static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) { const auto test_setup = MakeNoLogFileContext(); - test_setup->m_args.ForceSetArg("-unsafesqlitesync", "1"); WalletContext context; context.args = &test_setup->m_args; @@ -67,32 +40,29 @@ static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) // 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 = TestLoadWallet(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)); + TestUnloadWallet(std::move(wallet)); bench.epochs(5).run([&] { - wallet = BenchLoadWallet(std::move(database), context, options); + wallet = TestLoadWallet(std::move(database), context, create_flags); // Cleanup - database = DuplicateMockDatabase(wallet->GetDatabase(), options); - BenchUnloadWallet(std::move(wallet)); + database = DuplicateMockDatabase(wallet->GetDatabase()); + TestUnloadWallet(std::move(wallet)); }); } @@ -105,3 +75,4 @@ BENCHMARK(WalletLoadingLegacy, benchmark::PriorityLevel::HIGH); static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); } BENCHMARK(WalletLoadingDescriptors, benchmark::PriorityLevel::HIGH); #endif +} // namespace wallet diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index 5143de883569..b038bc842598 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,7 @@ #include using wallet::AddWallet; -using wallet::CreateMockWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::CWallet; using wallet::RemoveWallet; using wallet::WALLET_FLAG_DESCRIPTORS; @@ -72,7 +73,7 @@ void TestAddAddressesToSendBook(interfaces::Node& node) { TestChain100Setup test; node.setContext(&test.m_node); - const std::shared_ptr wallet = std::make_shared(node.context()->chain.get(), "", CreateMockWalletDatabase()); + const std::shared_ptr wallet = std::make_shared(node.context()->chain.get(), "", CreateMockableWalletDatabase()); wallet->LoadWallet(); wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS); { diff --git a/src/qt/test/masternodetestutil.cpp b/src/qt/test/masternodetestutil.cpp index d3f36cd1f50e..739ada691674 100644 --- a/src/qt/test/masternodetestutil.cpp +++ b/src/qt/test/masternodetestutil.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,7 @@ using wallet::AddWallet; using wallet::CWallet; -using wallet::CreateMockWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::RemoveWallet; using wallet::WALLET_FLAG_DESCRIPTORS; using wallet::WalletContext; @@ -74,7 +75,7 @@ struct WalletOptions { std::shared_ptr MakeWallet(interfaces::Node& node, WalletContext& context, const std::string& name, const WalletOptions& options) { - auto wallet{std::make_shared(node.context()->chain.get(), name, CreateMockWalletDatabase())}; + auto wallet{std::make_shared(node.context()->chain.get(), name, CreateMockableWalletDatabase())}; wallet->LoadWallet(); wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS); const CBlockIndex* const tip{options.setup == nullptr diff --git a/src/qt/test/masternodewidgettests.cpp b/src/qt/test/masternodewidgettests.cpp index 9dac30676fc7..e51c598766bb 100644 --- a/src/qt/test/masternodewidgettests.cpp +++ b/src/qt/test/masternodewidgettests.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -67,7 +68,7 @@ #include #include -using wallet::CreateMockWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::CWallet; using wallet::WalletContext; @@ -407,7 +408,7 @@ void MasternodeWidgetTests::operationRunnerThreading() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); auto wallet_interface{interfaces::MakeWallet(context, wallet)}; QVERIFY(wallet_interface != nullptr); @@ -455,7 +456,7 @@ void MasternodeWidgetTests::operationRunnerExceptions() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); auto wallet_interface{interfaces::MakeWallet(context, wallet)}; QVERIFY(wallet_interface != nullptr); @@ -492,7 +493,7 @@ void MasternodeWidgetTests::operationRunnerShutdownDelivery() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); auto wallet_interface{interfaces::MakeWallet(context, wallet)}; QVERIFY(wallet_interface != nullptr); @@ -548,7 +549,7 @@ void MasternodeWidgetTests::feeSourcePickerEligibility() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); wallet->SetWalletFlag(wallet::WALLET_FLAG_DESCRIPTORS); @@ -613,7 +614,7 @@ void MasternodeWidgetTests::registeredCollateralExclusion() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); wallet->SetWalletFlag(wallet::WALLET_FLAG_DESCRIPTORS); @@ -916,7 +917,7 @@ void MasternodeWidgetTests::masternodeListRegistrationAvailability() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); MasternodeTestUtil::GuiModels models{m_node}; QVERIFY2(models.ok, qPrintable(QString::fromStdString(models.error.translated))); @@ -999,7 +1000,7 @@ void MasternodeWidgetTests::sharedMasternodeOwnedFilter() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); wallet->SetWalletFlag(wallet::WALLET_FLAG_DESCRIPTORS); @@ -1036,7 +1037,7 @@ void MasternodeWidgetTests::sharedMasternodeContextMenu() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); wallet->SetWalletFlag(wallet::WALLET_FLAG_DESCRIPTORS); @@ -1220,7 +1221,7 @@ void MasternodeWidgetTests::wizardInteractionLifecycle() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); MasternodeTestUtil::GuiModels models{m_node}; QVERIFY2(models.ok, qPrintable(QString::fromStdString(models.error.translated))); @@ -1303,7 +1304,7 @@ void MasternodeWidgetTests::registrationResultStates() TestChain100Setup test; m_node.setContext(&test.m_node); WalletContext& context{*m_node.walletLoader().context()}; - const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockWalletDatabase())}; + const auto wallet{std::make_shared(m_node.context()->chain.get(), "", CreateMockableWalletDatabase())}; wallet->LoadWallet(); MasternodeTestUtil::GuiModels models{m_node}; QVERIFY2(models.ok, qPrintable(QString::fromStdString(models.error.translated))); diff --git a/src/qt/test/providertransactiontests.cpp b/src/qt/test/providertransactiontests.cpp index 4efdfa2409c9..71668cf10d2d 100644 --- a/src/qt/test/providertransactiontests.cpp +++ b/src/qt/test/providertransactiontests.cpp @@ -22,6 +22,7 @@ #include