aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/test/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/test/fuzz')
-rw-r--r--src/wallet/test/fuzz/coinselection.cpp4
-rw-r--r--src/wallet/test/fuzz/scriptpubkeyman.cpp16
-rw-r--r--src/wallet/test/fuzz/wallet_bdb_parser.cpp135
3 files changed, 153 insertions, 2 deletions
diff --git a/src/wallet/test/fuzz/coinselection.cpp b/src/wallet/test/fuzz/coinselection.cpp
index 331590df7f..644a8dd7ad 100644
--- a/src/wallet/test/fuzz/coinselection.cpp
+++ b/src/wallet/test/fuzz/coinselection.cpp
@@ -270,7 +270,7 @@ FUZZ_TARGET(coinselection)
if (result_srd) {
assert(result_srd->GetSelectedValue() >= target);
assert(result_srd->GetChange(CHANGE_LOWER, coin_params.m_change_fee) > 0); // Demonstrate that SRD creates change of at least CHANGE_LOWER
- result_srd->ComputeAndSetWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee);
+ result_srd->RecalculateWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee);
(void)result_srd->GetShuffledInputVector();
(void)result_srd->GetInputSet();
}
@@ -279,7 +279,7 @@ FUZZ_TARGET(coinselection)
auto result_knapsack = KnapsackSolver(group_all, target, change_target, fast_random_context, MAX_STANDARD_TX_WEIGHT);
if (result_knapsack) {
assert(result_knapsack->GetSelectedValue() >= target);
- result_knapsack->ComputeAndSetWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee);
+ result_knapsack->RecalculateWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee);
(void)result_knapsack->GetShuffledInputVector();
(void)result_knapsack->GetInputSet();
}
diff --git a/src/wallet/test/fuzz/scriptpubkeyman.cpp b/src/wallet/test/fuzz/scriptpubkeyman.cpp
index 228e9629ed..835470aeae 100644
--- a/src/wallet/test/fuzz/scriptpubkeyman.cpp
+++ b/src/wallet/test/fuzz/scriptpubkeyman.cpp
@@ -137,6 +137,15 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
PKHash{ConsumeUInt160(fuzzed_data_provider)}};
std::string str_sig;
(void)spk_manager->SignMessage(msg, pk_hash, str_sig);
+ (void)spk_manager->GetMetadata(dest);
+ }
+ }
+ },
+ [&] {
+ auto spks{spk_manager->GetScriptPubKeys()};
+ for (const CScript& spk : spks) {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ spk_manager->MarkUnusedAddresses(spk);
}
}
},
@@ -148,6 +157,10 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
}
spk_manager->AddDescriptorKey(key, key.GetPubKey());
spk_manager->TopUp();
+ LOCK(spk_manager->cs_desc_man);
+ auto particular_key{spk_manager->GetKey(key.GetPubKey().GetID())};
+ assert(*particular_key == key);
+ assert(spk_manager->HasPrivKey(key.GetPubKey().GetID()));
},
[&] {
std::string descriptor;
@@ -194,6 +207,9 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm)
}
);
}
+
+ (void)spk_manager->GetEndRange();
+ (void)spk_manager->GetKeyPoolSize();
}
} // namespace
diff --git a/src/wallet/test/fuzz/wallet_bdb_parser.cpp b/src/wallet/test/fuzz/wallet_bdb_parser.cpp
new file mode 100644
index 0000000000..5216e09769
--- /dev/null
+++ b/src/wallet/test/fuzz/wallet_bdb_parser.cpp
@@ -0,0 +1,135 @@
+// Copyright (c) 2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <config/bitcoin-config.h> // IWYU pragma: keep
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <test/util/setup_common.h>
+#include <util/fs.h>
+#include <util/time.h>
+#include <util/translation.h>
+#include <wallet/bdb.h>
+#include <wallet/db.h>
+#include <wallet/dump.h>
+#include <wallet/migrate.h>
+
+#include <fstream>
+#include <iostream>
+
+using wallet::DatabaseOptions;
+using wallet::DatabaseStatus;
+
+namespace {
+TestingSetup* g_setup;
+} // namespace
+
+void initialize_wallet_bdb_parser()
+{
+ static auto testing_setup = MakeNoLogFileContext<TestingSetup>();
+ g_setup = testing_setup.get();
+}
+
+FUZZ_TARGET(wallet_bdb_parser, .init = initialize_wallet_bdb_parser)
+{
+ const auto wallet_path = g_setup->m_args.GetDataDirNet() / "fuzzed_wallet.dat";
+
+ {
+ AutoFile outfile{fsbridge::fopen(wallet_path, "wb")};
+ outfile << Span{buffer};
+ }
+
+ const DatabaseOptions options{};
+ DatabaseStatus status;
+ bilingual_str error;
+
+ fs::path bdb_ro_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb_ro.dump"};
+ if (fs::exists(bdb_ro_dumpfile)) { // Writing into an existing dump file will throw an exception
+ remove(bdb_ro_dumpfile);
+ }
+ g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_ro_dumpfile));
+
+#ifdef USE_BDB
+ bool bdb_ro_err = false;
+ bool bdb_ro_strict_err = false;
+#endif
+ auto db{MakeBerkeleyRODatabase(wallet_path, options, status, error)};
+ if (db) {
+ assert(DumpWallet(g_setup->m_args, *db, error));
+ } else {
+#ifdef USE_BDB
+ bdb_ro_err = true;
+#endif
+ if (error.original.starts_with("AutoFile::ignore: end of file") ||
+ error.original.starts_with("AutoFile::read: end of file") ||
+ error.original == "Not a BDB file" ||
+ error.original == "Unexpected page type, should be 9 (BTree Metadata)" ||
+ error.original == "Unexpected database flags, should only be 0x20 (subdatabases)" ||
+ error.original == "Unexpected outer database root page type" ||
+ error.original == "Unexpected number of entries in outer database root page" ||
+ error.original == "Subdatabase page number has unexpected length" ||
+ error.original == "Unknown record type in records page" ||
+ error.original == "Unknown record type in internal page" ||
+ error.original == "Unexpected page size" ||
+ error.original == "Unexpected page type" ||
+ error.original == "Page number mismatch" ||
+ error.original == "Bad btree level" ||
+ error.original == "Bad page size" ||
+ error.original == "Meta page number mismatch" ||
+ error.original == "Data record position not in page" ||
+ error.original == "Internal record position not in page" ||
+ error.original == "LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support" ||
+ error.original == "Records page has odd number of records" ||
+ error.original == "Bad overflow record page type") {
+ // Do nothing
+ } else if (error.original == "Subdatabase last page is greater than database last page" ||
+ error.original == "Page number is greater than database last page" ||
+ error.original == "Last page number could not fit in file" ||
+ error.original == "Subdatabase has an unexpected name" ||
+ error.original == "Unsupported BDB data file version number" ||
+ error.original == "BDB builtin encryption is not supported") {
+#ifdef USE_BDB
+ bdb_ro_strict_err = true;
+#endif
+ } else {
+ throw std::runtime_error(error.original);
+ }
+ }
+
+#ifdef USE_BDB
+ // Try opening with BDB
+ fs::path bdb_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb.dump"};
+ if (fs::exists(bdb_dumpfile)) { // Writing into an existing dump file will throw an exception
+ remove(bdb_dumpfile);
+ }
+ g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_dumpfile));
+
+ try {
+ auto db{MakeBerkeleyDatabase(wallet_path, options, status, error)};
+ if (bdb_ro_err && !db) {
+ return;
+ }
+ assert(db);
+ if (bdb_ro_strict_err) {
+ // BerkeleyRO will be stricter than BDB. Ignore when those specific errors are hit.
+ return;
+ }
+ assert(!bdb_ro_err);
+ assert(DumpWallet(g_setup->m_args, *db, error));
+ } catch (const std::runtime_error& e) {
+ if (bdb_ro_err) return;
+ throw e;
+ }
+
+ // Make sure the dumpfiles match
+ if (fs::exists(bdb_ro_dumpfile) && fs::exists(bdb_dumpfile)) {
+ std::ifstream bdb_ro_dump(bdb_ro_dumpfile, std::ios_base::binary | std::ios_base::in);
+ std::ifstream bdb_dump(bdb_dumpfile, std::ios_base::binary | std::ios_base::in);
+ assert(std::equal(
+ std::istreambuf_iterator<char>(bdb_ro_dump.rdbuf()),
+ std::istreambuf_iterator<char>(),
+ std::istreambuf_iterator<char>(bdb_dump.rdbuf())));
+ }
+#endif
+}