diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/addrman_tests.cpp | 13 | ||||
-rw-r--r-- | src/test/amount_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/dbwrapper_tests.cpp | 18 | ||||
-rw-r--r-- | src/test/denialofservice_tests.cpp | 4 | ||||
-rw-r--r-- | src/test/flatfile_tests.cpp | 8 | ||||
-rw-r--r-- | src/test/fs_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/addrman.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/banman.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/coins_view.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/connman.cpp | 13 | ||||
-rw-r--r-- | src/test/fuzz/fee_rate.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/fuzz.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/i2p.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/net.cpp | 22 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 14 | ||||
-rw-r--r-- | src/test/fuzz/tx_pool.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/utxo_snapshot.cpp | 87 | ||||
-rw-r--r-- | src/test/i2p_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/settings_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/util/mining.cpp | 33 | ||||
-rw-r--r-- | src/test/util/mining.h | 5 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 2 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 20 | ||||
-rw-r--r-- | src/test/validation_tests.cpp | 8 |
24 files changed, 205 insertions, 80 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index d438537606..49b40924e0 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -12,6 +12,7 @@ #include <boost/test/unit_test.hpp> +#include <optional> #include <string> class CAddrManTest : public CAddrMan @@ -392,7 +393,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Test: Sanity check, GetAddr should never return anything if addrman // is empty. BOOST_CHECK_EQUAL(addrman.size(), 0U); - std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */0); + std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt); BOOST_CHECK_EQUAL(vAddr1.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); @@ -415,15 +416,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.Add(addr4, source2)); BOOST_CHECK(addrman.Add(addr5, source1)); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); // Net processing asks for 23% of addresses. 23% of 5 is 1 rounded down. - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U); // Test: Ensure GetAddr works with new and tried addresses. addrman.Good(CAddress(addr1, NODE_NONE)); addrman.Good(CAddress(addr2, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U); // Test: Ensure GetAddr still returns 23% when addrman has many addrs. for (unsigned int i = 1; i < (8 * 256); i++) { @@ -438,7 +439,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) if (i % 8 == 0) addrman.Good(addr); } - std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23); + std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt); size_t percent23 = (addrman.size() * 23) / 100; BOOST_CHECK_EQUAL(vAddr.size(), percent23); diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index 1a39498899..65ba2bab15 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); // Maximum size in bytes, should not crash - CFeeRate(MAX_MONEY, std::numeric_limits<size_t>::max() >> 1).GetFeePerK(); + CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).GetFeePerK(); } BOOST_AUTO_TEST_CASE(BinaryOperatorTest) diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index b5f3bb2fa4..e2e7644dfa 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_obfuscate_true" : "dbwrapper_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_obfuscate_true" : "dbwrapper_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'k'; uint256 in = InsecureRand256(); @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_basic_data) { // Perform tests both obfuscated and non-obfuscated. for (bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_1_obfuscate_true" : "dbwrapper_1_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_1_obfuscate_true" : "dbwrapper_1_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), false, true, obfuscate); uint256 res; @@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_batch_obfuscate_true" : "dbwrapper_batch_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_batch_obfuscate_true" : "dbwrapper_batch_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'i'; @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_iterator_obfuscate_true" : "dbwrapper_iterator_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_iterator_obfuscate_true" : "dbwrapper_iterator_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); // The two keys are intentionally chosen for ordering @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) { // We're going to share this fs::path between two wrappers - fs::path ph = m_args.GetDataDirPath() / "existing_data_no_obfuscate"; + fs::path ph = m_args.GetDataDirBase() / "existing_data_no_obfuscate"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) BOOST_AUTO_TEST_CASE(existing_data_reindex) { // We're going to share this fs::path between two wrappers - fs::path ph = m_args.GetDataDirPath() / "existing_data_reindex"; + fs::path ph = m_args.GetDataDirBase() / "existing_data_reindex"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_AUTO_TEST_CASE(iterator_ordering) { - fs::path ph = m_args.GetDataDirPath() / "iterator_ordering"; + fs::path ph = m_args.GetDataDirBase() / "iterator_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<256; ++x) { uint8_t key = x; @@ -358,7 +358,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) { char buf[10]; - fs::path ph = m_args.GetDataDirPath() / "iterator_string_ordering"; + fs::path ph = m_args.GetDataDirBase() / "iterator_string_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { @@ -404,7 +404,7 @@ BOOST_AUTO_TEST_CASE(unicodepath) // On Windows this test will fail if the directory is created using // the ANSI CreateDirectoryA call and the code page isn't UTF8. // It will succeed if created with CreateDirectoryW. - fs::path ph = m_args.GetDataDirPath() / "test_runner_₿_🏃_20191128_104644"; + fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644"; CDBWrapper dbw(ph, (1 << 20)); fs::path lockPath = ph / "LOCK"; diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index ddf0e0ca90..a56ce51acb 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) BOOST_AUTO_TEST_CASE(peer_discouragement) { const CChainParams& chainparams = Params(); - auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) BOOST_AUTO_TEST_CASE(DoS_bantime) { const CChainParams& chainparams = Params(); - auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); diff --git a/src/test/flatfile_tests.cpp b/src/test/flatfile_tests.cpp index 9194ed8130..f4bc320f3c 100644 --- a/src/test/flatfile_tests.cpp +++ b/src/test/flatfile_tests.cpp @@ -14,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(flatfile_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(flatfile_filename) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFilePos pos(456, 789); @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(flatfile_filename) BOOST_AUTO_TEST_CASE(flatfile_open) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 16 * 1024); std::string line1("A purely peer-to-peer version of electronic cash would allow online " @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(flatfile_open) BOOST_AUTO_TEST_CASE(flatfile_allocate) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(flatfile_allocate) BOOST_AUTO_TEST_CASE(flatfile_flush) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp index 452bc06bbb..526a3c27be 100644 --- a/src/test/fs_tests.cpp +++ b/src/test/fs_tests.cpp @@ -13,7 +13,7 @@ BOOST_FIXTURE_TEST_SUITE(fs_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(fsbridge_fstream) { - fs::path tmpfolder = m_args.GetDataDirPath(); + fs::path tmpfolder = m_args.GetDataDirBase(); // tmpfile1 should be the same as tmpfile2 fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃"; fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃"; diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 0baf30aef6..98ae32a8d0 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -60,7 +60,10 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) (void)addr_man.Select(fuzzed_data_provider.ConsumeBool()); }, [&] { - (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); + (void)addr_man.GetAddr( + /* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), + /* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), + /* network */ std::nullopt); }, [&] { const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider); diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp index 8bf484722c..4a04eed463 100644 --- a/src/test/fuzz/banman.cpp +++ b/src/test/fuzz/banman.cpp @@ -34,7 +34,7 @@ FUZZ_TARGET_INIT(banman, initialize_banman) { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; SetMockTime(ConsumeTime(fuzzed_data_provider)); - const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat"; + const fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist.dat"; fs::remove(banlist_file); { BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)}; diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index 21dc80cc8d..878b5a27da 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -6,6 +6,7 @@ #include <chainparams.h> #include <chainparamsbase.h> #include <coins.h> +#include <consensus/tx_check.h> #include <consensus/tx_verify.h> #include <consensus/validation.h> #include <key.h> @@ -230,6 +231,11 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view) // consensus/tx_verify.cpp:171: bool Consensus::CheckTxInputs(const CTransaction &, TxValidationState &, const CCoinsViewCache &, int, CAmount &): Assertion `!coin.IsSpent()' failed. return; } + TxValidationState dummy; + if (!CheckTransaction(transaction, dummy)) { + // It is not allowed to call CheckTxInputs if CheckTransaction failed + return; + } (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out); assert(MoneyRange(tx_fee_out)); }, diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index e07f25dedf..bbec5943af 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -65,16 +65,19 @@ FUZZ_TARGET_INIT(connman, initialize_connman) connman.ForEachNode([](auto) {}); }, [&] { - connman.ForEachNodeThen([](auto) {}, []() {}); - }, - [&] { (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); }); }, [&] { - (void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>()); + (void)connman.GetAddresses( + /* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* network */ std::nullopt); }, [&] { - (void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>()); + (void)connman.GetAddresses( + /* requestor */ random_node, + /* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>()); }, [&] { (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); diff --git a/src/test/fuzz/fee_rate.cpp b/src/test/fuzz/fee_rate.cpp index 2955213635..dff0e58000 100644 --- a/src/test/fuzz/fee_rate.cpp +++ b/src/test/fuzz/fee_rate.cpp @@ -20,8 +20,8 @@ FUZZ_TARGET(fee_rate) const CFeeRate fee_rate{satoshis_per_k}; (void)fee_rate.GetFeePerK(); - const size_t bytes = fuzzed_data_provider.ConsumeIntegral<size_t>(); - if (!MultiplicationOverflow(static_cast<int64_t>(bytes), satoshis_per_k) && bytes <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) { + const auto bytes = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + if (!MultiplicationOverflow(int64_t{bytes}, satoshis_per_k)) { (void)fee_rate.GetFee(bytes); } (void)fee_rate.ToString(); diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp index 0d8d960d56..631c861bb6 100644 --- a/src/test/fuzz/fuzz.cpp +++ b/src/test/fuzz/fuzz.cpp @@ -4,10 +4,15 @@ #include <test/fuzz/fuzz.h> +#include <netaddress.h> +#include <netbase.h> #include <test/util/setup_common.h> #include <util/check.h> +#include <util/sock.h> #include <cstdint> +#include <exception> +#include <memory> #include <unistd.h> #include <vector> @@ -29,6 +34,9 @@ static TypeTestOneInput* g_test_one_input{nullptr}; void initialize() { + // Terminate immediately if a fuzzing harness ever tries to create a TCP socket. + CreateSock = [](const CService&) -> std::unique_ptr<Sock> { std::terminate(); }; + bool should_abort{false}; if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) { for (const auto& t : FuzzTargets()) { diff --git a/src/test/fuzz/i2p.cpp b/src/test/fuzz/i2p.cpp index e0d62fb493..fb6d23aca5 100644 --- a/src/test/fuzz/i2p.cpp +++ b/src/test/fuzz/i2p.cpp @@ -30,7 +30,7 @@ FUZZ_TARGET_INIT(i2p, initialize_i2p) const CService sam_proxy; CThreadInterrupt interrupt; - i2p::sam::Session sess{GetDataDir() / "fuzzed_i2p_private_key", sam_proxy, &interrupt}; + i2p::sam::Session sess{gArgs.GetDataDirNet() / "fuzzed_i2p_private_key", sam_proxy, &interrupt}; i2p::Connection conn; diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp index 272f6415a9..20d8581312 100644 --- a/src/test/fuzz/net.cpp +++ b/src/test/fuzz/net.cpp @@ -58,27 +58,6 @@ FUZZ_TARGET_INIT(net, initialize_net) } }, [&] { - if (node.m_addr_known == nullptr) { - return; - } - const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider); - if (!addr_opt) { - return; - } - node.AddAddressKnown(*addr_opt); - }, - [&] { - if (node.m_addr_known == nullptr) { - return; - } - const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider); - if (!addr_opt) { - return; - } - FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)}; - node.PushAddress(*addr_opt, fast_random_context); - }, - [&] { const std::optional<CInv> inv_opt = ConsumeDeserializable<CInv>(fuzzed_data_provider); if (!inv_opt) { return; @@ -110,7 +89,6 @@ FUZZ_TARGET_INIT(net, initialize_net) const int ref_count = node.GetRefCount(); assert(ref_count >= 0); (void)node.GetCommonVersion(); - (void)node.RelayAddrsWithConn(); const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS); (void)node.HasPermission(net_permission_flags); diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 17e4405a13..ff34cc87b2 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -61,8 +61,11 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) return; } - TxValidationState state_with_dupe_check; - (void)CheckTransaction(tx, state_with_dupe_check); + { + TxValidationState state_with_dupe_check; + const bool res{CheckTransaction(tx, state_with_dupe_check)}; + Assert(res == state_with_dupe_check.IsValid()); + } const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE}; std::string reason; @@ -100,9 +103,6 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) (void)IsWitnessStandard(tx, coins_view_cache); UniValue u(UniValue::VOBJ); - TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ true, u); - TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ false, u); - static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); - TxToUniv(tx, u256_max, /* include_addresses */ true, u); - TxToUniv(tx, u256_max, /* include_addresses */ false, u); + TxToUniv(tx, /* hashBlock */ uint256::ZERO, /* include_addresses */ true, u); + TxToUniv(tx, /* hashBlock */ uint256::ONE, /* include_addresses */ false, u); } diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 068e207118..ad11f2c5f2 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -21,8 +21,9 @@ std::vector<COutPoint> g_outpoints_coinbase_init_mature; std::vector<COutPoint> g_outpoints_coinbase_init_immature; struct MockedTxPool : public CTxMemPool { - void RollingFeeUpdate() + void RollingFeeUpdate() EXCLUSIVE_LOCKS_REQUIRED(!cs) { + LOCK(cs); lastRollingFeeUpdate = GetTime(); blockSinceLastRollingFeeBump = true; } diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp new file mode 100644 index 0000000000..6f2bc081c6 --- /dev/null +++ b/src/test/fuzz/utxo_snapshot.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2021 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 <chainparams.h> +#include <consensus/validation.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/mining.h> +#include <test/util/setup_common.h> +#include <validation.h> +#include <validationinterface.h> + +namespace { + +const std::vector<std::shared_ptr<CBlock>>* g_chain; + +void initialize_chain() +{ + const auto params{CreateChainParams(ArgsManager{}, CBaseChainParams::REGTEST)}; + static const auto chain{CreateBlockChain(2 * COINBASE_MATURITY, *params)}; + g_chain = &chain; +} + +FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + std::unique_ptr<const TestingSetup> setup{MakeNoLogFileContext<const TestingSetup>()}; + const auto& node = setup->m_node; + auto& chainman{*node.chainman}; + + const auto snapshot_path = gArgs.GetDataDirNet() / "fuzzed_snapshot.dat"; + + Assert(!chainman.SnapshotBlockhash()); + + { + CAutoFile outfile{fsbridge::fopen(snapshot_path, "wb"), SER_DISK, CLIENT_VERSION}; + const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)}; + outfile << Span<const uint8_t>{file_data}; + } + + const auto ActivateFuzzedSnapshot{[&] { + CAutoFile infile{fsbridge::fopen(snapshot_path, "rb"), SER_DISK, CLIENT_VERSION}; + SnapshotMetadata metadata; + try { + infile >> metadata; + } catch (const std::ios_base::failure&) { + return false; + } + return chainman.ActivateSnapshot(infile, metadata, /* in_memory */ true); + }}; + + if (fuzzed_data_provider.ConsumeBool()) { + for (const auto& block : *g_chain) { + BlockValidationState dummy; + bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy, ::Params())}; + Assert(processed); + const auto* index{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block->GetHash()))}; + Assert(index); + } + } + + if (ActivateFuzzedSnapshot()) { + LOCK(::cs_main); + Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash->IsNull()); + Assert(*chainman.ActiveChainstate().m_from_snapshot_blockhash == + *chainman.SnapshotBlockhash()); + const auto& coinscache{chainman.ActiveChainstate().CoinsTip()}; + int64_t chain_tx{}; + for (const auto& block : *g_chain) { + Assert(coinscache.HaveCoin(COutPoint{block->vtx.at(0)->GetHash(), 0})); + const auto* index{chainman.m_blockman.LookupBlockIndex(block->GetHash())}; + const auto num_tx{Assert(index)->nTx}; + Assert(num_tx == 1); + chain_tx += num_tx; + } + Assert(g_chain->size() == coinscache.GetCacheSize()); + Assert(chain_tx == chainman.ActiveTip()->nChainTx); + } else { + Assert(!chainman.SnapshotBlockhash()); + Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash); + } + // Snapshot should refuse to load a second time regardless of validity + Assert(!ActivateFuzzedSnapshot()); +} +} // namespace diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp index 334f71106c..bd9ba4b8f7 100644 --- a/src/test/i2p_tests.cpp +++ b/src/test/i2p_tests.cpp @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(unlimited_recv) }; CThreadInterrupt interrupt; - i2p::sam::Session session(GetDataDir() / "test_i2p_private_key", CService{}, &interrupt); + i2p::sam::Session session(gArgs.GetDataDirNet() / "test_i2p_private_key", CService{}, &interrupt); { ASSERT_DEBUG_LOG("Creating SAM session"); diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index f5ae9f86d1..340ce33d91 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -45,7 +45,7 @@ BOOST_FIXTURE_TEST_SUITE(settings_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(ReadWrite) { - fs::path path = m_args.GetDataDirPath() / "settings.json"; + fs::path path = m_args.GetDataDirBase() / "settings.json"; WriteText(path, R"({ "string": "string", diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp index 3fc3329da2..1204873828 100644 --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -11,8 +11,10 @@ #include <node/context.h> #include <pow.h> #include <script/standard.h> +#include <test/util/script.h> #include <util/check.h> #include <validation.h> +#include <versionbits.h> CTxIn generatetoaddress(const NodeContext& node, const std::string& address) { @@ -23,6 +25,37 @@ CTxIn generatetoaddress(const NodeContext& node, const std::string& address) return MineBlock(node, coinbase_script); } +std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params) +{ + std::vector<std::shared_ptr<CBlock>> ret{total_height}; + auto time{params.GenesisBlock().nTime}; + for (size_t height{0}; height < total_height; ++height) { + CBlock& block{*(ret.at(height) = std::make_shared<CBlock>())}; + + CMutableTransaction coinbase_tx; + coinbase_tx.vin.resize(1); + coinbase_tx.vin[0].prevout.SetNull(); + coinbase_tx.vout.resize(1); + coinbase_tx.vout[0].scriptPubKey = P2WSH_OP_TRUE; + coinbase_tx.vout[0].nValue = GetBlockSubsidy(height + 1, params.GetConsensus()); + coinbase_tx.vin[0].scriptSig = CScript() << (height + 1) << OP_0; + block.vtx = {MakeTransactionRef(std::move(coinbase_tx))}; + + block.nVersion = VERSIONBITS_LAST_OLD_BLOCK_VERSION; + block.hashPrevBlock = (height >= 1 ? *ret.at(height - 1) : params.GenesisBlock()).GetHash(); + block.hashMerkleRoot = BlockMerkleRoot(block); + block.nTime = ++time; + block.nBits = params.GenesisBlock().nBits; + block.nNonce = 0; + + while (!CheckProofOfWork(block.GetHash(), block.nBits, params.GetConsensus())) { + ++block.nNonce; + assert(block.nNonce); + } + } + return ret; +} + CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) { auto block = PrepareBlock(node, coinbase_scriptPubKey); diff --git a/src/test/util/mining.h b/src/test/util/mining.h index 5f250fffe8..1fc1864b91 100644 --- a/src/test/util/mining.h +++ b/src/test/util/mining.h @@ -7,12 +7,17 @@ #include <memory> #include <string> +#include <vector> class CBlock; +class CChainParams; class CScript; class CTxIn; struct NodeContext; +/** Create a blockchain, starting from genesis */ +std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params); + /** Returns the generated coin */ CTxIn MineBlock(const NodeContext&, const CScript& coinbase_scriptPubKey); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index f92e4c4b99..7bf7f9e0ba 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -195,7 +195,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const } m_node.addrman = std::make_unique<CAddrMan>(); - m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests. m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 534d28e5de..aa95bc37e5 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -53,23 +53,23 @@ BOOST_AUTO_TEST_CASE(util_datadir) ArgsManager args; args.ForceSetArg("-datadir", m_path_root.string()); - const fs::path dd_norm = args.GetDataDirPath(); + const fs::path dd_norm = args.GetDataDirBase(); args.ForceSetArg("-datadir", dd_norm.string() + "/"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/."); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/./"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/.//"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); } BOOST_AUTO_TEST_CASE(util_check) @@ -1159,10 +1159,10 @@ BOOST_AUTO_TEST_CASE(util_ReadWriteSettings) // Test error logging, and remove previously written setting. { ASSERT_DEBUG_LOG("Failed renaming settings file"); - fs::remove(args1.GetDataDirPath() / "settings.json"); - fs::create_directory(args1.GetDataDirPath() / "settings.json"); + fs::remove(args1.GetDataDirBase() / "settings.json"); + fs::create_directory(args1.GetDataDirBase() / "settings.json"); args2.WriteSettingsFile(); - fs::remove(args1.GetDataDirPath() / "settings.json"); + fs::remove(args1.GetDataDirBase() / "settings.json"); } } @@ -1810,7 +1810,7 @@ static constexpr char ExitCommand = 'X'; BOOST_AUTO_TEST_CASE(test_LockDirectory) { - fs::path dirname = m_args.GetDataDirPath() / "lock_dir"; + fs::path dirname = m_args.GetDataDirBase() / "lock_dir"; const std::string lockname = ".lock"; #ifndef WIN32 // Revert SIGCHLD to default, otherwise boost.test will catch and fail on @@ -1899,7 +1899,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) BOOST_AUTO_TEST_CASE(test_DirIsWritable) { // Should be able to write to the data dir. - fs::path tmpdirname = m_args.GetDataDirPath(); + fs::path tmpdirname = m_args.GetDataDirBase(); BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true); // Should not be able to write to a non-existent dir. diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index 1e5baec01a..a0c2e76f00 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -136,11 +136,11 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo) const auto out110 = *ExpectedAssumeutxo(110, *params); BOOST_CHECK_EQUAL(out110.hash_serialized.ToString(), "1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"); - BOOST_CHECK_EQUAL(out110.nChainTx, (unsigned int)110); + BOOST_CHECK_EQUAL(out110.nChainTx, 110U); - const auto out210 = *ExpectedAssumeutxo(210, *params); - BOOST_CHECK_EQUAL(out210.hash_serialized.ToString(), "9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2"); - BOOST_CHECK_EQUAL(out210.nChainTx, (unsigned int)210); + const auto out210 = *ExpectedAssumeutxo(200, *params); + BOOST_CHECK_EQUAL(out210.hash_serialized.ToString(), "51c8d11d8b5c1de51543c579736e786aa2736206d1e11e627568029ce092cf62"); + BOOST_CHECK_EQUAL(out210.nChainTx, 200U); } BOOST_AUTO_TEST_SUITE_END() |