diff options
Diffstat (limited to 'src/test/fuzz')
-rw-r--r-- | src/test/fuzz/asmap.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/connman.cpp | 1 | ||||
-rw-r--r-- | src/test/fuzz/golomb_rice.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/integer.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/parse_iso8601.cpp | 1 | ||||
-rw-r--r-- | src/test/fuzz/rpc.cpp | 21 | ||||
-rw-r--r-- | src/test/fuzz/script_assets_test_minimizer.cpp | 4 | ||||
-rw-r--r-- | src/test/fuzz/script_sign.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/tx_pool.cpp | 21 | ||||
-rw-r--r-- | src/test/fuzz/utxo_snapshot.cpp | 2 |
10 files changed, 45 insertions, 24 deletions
diff --git a/src/test/fuzz/asmap.cpp b/src/test/fuzz/asmap.cpp index d402f8632c..c5e9c56049 100644 --- a/src/test/fuzz/asmap.cpp +++ b/src/test/fuzz/asmap.cpp @@ -49,7 +49,7 @@ FUZZ_TARGET(asmap) CNetAddr net_addr; if (ipv6) { assert(addr_size == ADDR_IPV6_SIZE); - net_addr.SetLegacyIPv6(Span<const uint8_t>(addr_data, addr_size)); + net_addr.SetLegacyIPv6({addr_data, addr_size}); } else { assert(addr_size == ADDR_IPV4_SIZE); in_addr ipv4; diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index b8f4ad8d94..f87b6f1503 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <addrman.h> #include <chainparams.h> #include <chainparamsbase.h> #include <net.h> diff --git a/src/test/fuzz/golomb_rice.cpp b/src/test/fuzz/golomb_rice.cpp index c99bf940c7..746347ac95 100644 --- a/src/test/fuzz/golomb_rice.cpp +++ b/src/test/fuzz/golomb_rice.cpp @@ -82,8 +82,8 @@ FUZZ_TARGET(golomb_rice) std::vector<uint64_t> decoded_deltas; { - VectorReader stream{SER_NETWORK, 0, golomb_rice_data, 0}; - BitStreamReader<VectorReader> bitreader(stream); + SpanReader stream{SER_NETWORK, 0, golomb_rice_data}; + BitStreamReader<SpanReader> bitreader{stream}; const uint32_t n = static_cast<uint32_t>(ReadCompactSize(stream)); for (uint32_t i = 0; i < n; ++i) { decoded_deltas.push_back(GolombRiceDecode(bitreader, BASIC_FILTER_P)); @@ -94,14 +94,14 @@ FUZZ_TARGET(golomb_rice) { const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider, 1024); - VectorReader stream{SER_NETWORK, 0, random_bytes, 0}; + SpanReader stream{SER_NETWORK, 0, random_bytes}; uint32_t n; try { n = static_cast<uint32_t>(ReadCompactSize(stream)); } catch (const std::ios_base::failure&) { return; } - BitStreamReader<VectorReader> bitreader(stream); + BitStreamReader<SpanReader> bitreader{stream}; for (uint32_t i = 0; i < std::min<uint32_t>(n, 1024); ++i) { try { (void)GolombRiceDecode(bitreader, BASIC_FILTER_P); diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index b6c40809e3..ce424c443e 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -29,12 +29,10 @@ #include <util/strencodings.h> #include <util/string.h> #include <util/system.h> -#include <util/time.h> #include <version.h> #include <cassert> #include <chrono> -#include <ctime> #include <limits> #include <set> #include <vector> @@ -81,8 +79,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer) (void)ComputeMerkleRoot(v256); (void)CountBits(u64); (void)DecompressAmount(u64); - (void)FormatISO8601Date(i64); - (void)FormatISO8601DateTime(i64); { if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) { assert(parsed.value() == i64); diff --git a/src/test/fuzz/parse_iso8601.cpp b/src/test/fuzz/parse_iso8601.cpp index a56f2aa48d..3c56fa49ee 100644 --- a/src/test/fuzz/parse_iso8601.cpp +++ b/src/test/fuzz/parse_iso8601.cpp @@ -19,6 +19,7 @@ FUZZ_TARGET(parse_iso8601) const std::string random_string = fuzzed_data_provider.ConsumeRemainingBytesAsString(); const std::string iso8601_datetime = FormatISO8601DateTime(random_time); + (void)FormatISO8601Date(random_time); const int64_t parsed_time_1 = ParseISO8601DateTime(iso8601_datetime); if (random_time >= 0) { assert(parsed_time_1 >= 0); diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp index 251687104e..b6ecf1c492 100644 --- a/src/test/fuzz/rpc.cpp +++ b/src/test/fuzz/rpc.cpp @@ -41,13 +41,17 @@ struct RPCFuzzTestingSetup : public TestingSetup { { } - UniValue CallRPC(const std::string& rpc_method, const std::vector<std::string>& arguments) + void CallRPC(const std::string& rpc_method, const std::vector<std::string>& arguments) { JSONRPCRequest request; request.context = &m_node; request.strMethod = rpc_method; - request.params = RPCConvertValues(rpc_method, arguments); - return tableRPC.execute(request); + try { + request.params = RPCConvertValues(rpc_method, arguments); + } catch (const std::runtime_error&) { + return; + } + tableRPC.execute(request); } std::vector<std::string> GetRPCCommands() const @@ -110,6 +114,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{ "getblockfilter", "getblockhash", "getblockheader", + "getblockfrompeer", // when no peers are connected, no p2p message is sent "getblockstats", "getblocktemplate", "getchaintips", @@ -353,7 +358,13 @@ FUZZ_TARGET_INIT(rpc, initialize_rpc) } try { rpc_testing_setup->CallRPC(rpc_command, arguments); - } catch (const UniValue&) { - } catch (const std::runtime_error&) { + } catch (const UniValue& json_rpc_error) { + const std::string error_msg{find_value(json_rpc_error, "message").get_str()}; + // Once c++20 is allowed, starts_with can be used. + // if (error_msg.starts_with("Internal bug detected")) { + if (0 == error_msg.rfind("Internal bug detected", 0)) { + // Only allow the intentional internal bug + assert(error_msg.find("trigger_internal_bug") != std::string::npos); + } } } diff --git a/src/test/fuzz/script_assets_test_minimizer.cpp b/src/test/fuzz/script_assets_test_minimizer.cpp index 4669f783aa..00a3bed12f 100644 --- a/src/test/fuzz/script_assets_test_minimizer.cpp +++ b/src/test/fuzz/script_assets_test_minimizer.cpp @@ -54,7 +54,7 @@ CMutableTransaction TxFromHex(const std::string& str) { CMutableTransaction tx; try { - VectorReader(SER_DISK, SERIALIZE_TRANSACTION_NO_WITNESS, CheckedParseHex(str), 0) >> tx; + SpanReader{SER_DISK, SERIALIZE_TRANSACTION_NO_WITNESS, CheckedParseHex(str)} >> tx; } catch (const std::ios_base::failure&) { throw std::runtime_error("Tx deserialization failure"); } @@ -68,7 +68,7 @@ std::vector<CTxOut> TxOutsFromJSON(const UniValue& univalue) for (size_t i = 0; i < univalue.size(); ++i) { CTxOut txout; try { - VectorReader(SER_DISK, 0, CheckedParseHex(univalue[i].get_str()), 0) >> txout; + SpanReader{SER_DISK, 0, CheckedParseHex(univalue[i].get_str())} >> txout; } catch (const std::ios_base::failure&) { throw std::runtime_error("Prevout invalid format"); } diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp index 79380bd9c9..1a42179724 100644 --- a/src/test/fuzz/script_sign.cpp +++ b/src/test/fuzz/script_sign.cpp @@ -5,6 +5,7 @@ #include <chainparams.h> #include <chainparamsbase.h> #include <key.h> +#include <psbt.h> #include <pubkey.h> #include <script/keyorigin.h> #include <script/sign.h> @@ -43,7 +44,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign) } catch (const std::ios_base::failure&) { } CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; - SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>())); } { @@ -61,7 +62,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign) } CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; try { - SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>())); } catch (const std::ios_base::failure&) { } std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths; diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 702660f63e..fe1b9c7c0c 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -29,6 +29,15 @@ struct MockedTxPool : public CTxMemPool { } }; +class DummyChainState final : public CChainState +{ +public: + void SetMempool(CTxMemPool* mempool) + { + m_mempool = mempool; + } +}; + void initialize_tx_pool() { static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); @@ -86,7 +95,7 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CCh BlockAssembler::Options options; options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT); options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)}; - auto assembler = BlockAssembler{chainstate, *static_cast<CTxMemPool*>(&tx_pool), ::Params(), options}; + auto assembler = BlockAssembler{chainstate, *static_cast<CTxMemPool*>(&tx_pool), chainstate.m_params, options}; auto block_template = assembler.CreateNewBlock(CScript{} << OP_TRUE); Assert(block_template->block.vtx.size() >= 1); } @@ -114,7 +123,7 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const auto& node = g_setup->m_node; - auto& chainstate = node.chainman->ActiveChainstate(); + auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())}; MockTime(fuzzed_data_provider, chainstate); SetMempoolConstraints(*node.args, fuzzed_data_provider); @@ -134,6 +143,8 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_); + chainstate.SetMempool(&tx_pool); + // Helper to query an amount const CCoinsViewMemPool amount_view{WITH_LOCK(::cs_main, return &chainstate.CoinsTip()), tx_pool}; const auto GetAmount = [&](const COutPoint& outpoint) { @@ -224,13 +235,13 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) // Make sure ProcessNewPackage on one transaction works and always fully validates the transaction. // The result is not guaranteed to be the same as what is returned by ATMP. const auto result_package = WITH_LOCK(::cs_main, - return ProcessNewPackage(node.chainman->ActiveChainstate(), tx_pool, {tx}, true)); + return ProcessNewPackage(chainstate, tx_pool, {tx}, true)); auto it = result_package.m_tx_results.find(tx->GetWitnessHash()); Assert(it != result_package.m_tx_results.end()); Assert(it->second.m_result_type == MempoolAcceptResult::ResultType::VALID || it->second.m_result_type == MempoolAcceptResult::ResultType::INVALID); - const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx_pool, tx, bypass_limits)); + const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false)); const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; SyncWithValidationInterfaceQueue(); UnregisterSharedValidationInterface(txr); @@ -330,7 +341,7 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool) const auto tx = MakeTransactionRef(mut_tx); const bool bypass_limits = fuzzed_data_provider.ConsumeBool(); ::fRequireStandard = fuzzed_data_provider.ConsumeBool(); - const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(node.chainman->ActiveChainstate(), tx_pool, tx, bypass_limits)); + const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false)); const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; if (accepted) { txids.push_back(tx->GetHash()); diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp index 02039cba81..1b9f0c8a02 100644 --- a/src/test/fuzz/utxo_snapshot.cpp +++ b/src/test/fuzz/utxo_snapshot.cpp @@ -38,7 +38,7 @@ FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain) { 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}; + outfile << Span{file_data}; } const auto ActivateFuzzedSnapshot{[&] { |