From d9f01c3c9f7ebf60f878e1e2093334b77d7986ed Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 16 Jan 2024 07:25:25 +0000 Subject: [PATCH 01/15] build: fix indentation for test, fuzz and bench option print --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index ed96c7e0dbb7..62819f46fda6 100644 --- a/configure.ac +++ b/configure.ac @@ -1960,12 +1960,12 @@ if test x$bitcoin_enable_qt != xno; then fi echo " with zmq = $use_zmq" if test x$enable_fuzz == xno; then - echo " with test = $use_tests" + echo " with test = $use_tests" else - echo " with test = not building test_dash because fuzzing is enabled" - echo " with fuzz = $enable_fuzz" + echo " with test = not building test_dash because fuzzing is enabled" + echo " with fuzz = $enable_fuzz" fi -echo " with bench = $use_bench" +echo " with bench = $use_bench" echo " with upnp = $use_upnp" echo " with natpmp = $use_natpmp" echo " use asm = $use_asm" From 1ecd587183392273b3a1e0ae7fa08d60981ec49d Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 6 Nov 2020 15:03:51 +0100 Subject: [PATCH 02/15] merge bitcoin#20332: Mock IBD in net_processing fuzzers --- src/Makefile.test_util.include | 2 ++ src/test/fuzz/process_message.cpp | 5 +++++ src/test/fuzz/process_messages.cpp | 6 ++++++ src/test/util/validation.cpp | 22 ++++++++++++++++++++++ src/test/util/validation.h | 17 +++++++++++++++++ src/validation.h | 3 +-- 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/test/util/validation.cpp create mode 100644 src/test/util/validation.h diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index f55a040bbde0..1e9553e74529 100644 --- a/src/Makefile.test_util.include +++ b/src/Makefile.test_util.include @@ -17,6 +17,7 @@ TEST_UTIL_H = \ test/util/str.h \ test/util/transaction_utils.h \ test/util/wallet.h \ + test/util/validation.h \ test/util/xoroshiro128plusplus.h libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) @@ -30,6 +31,7 @@ libtest_util_a_SOURCES = \ test/util/setup_common.cpp \ test/util/str.cpp \ test/util/transaction_utils.cpp \ + test/util/validation.cpp \ test/util/wallet.cpp \ $(TEST_UTIL_H) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 6fe278449bc2..bf57798b2723 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -74,10 +75,14 @@ void fuzz_target(FuzzBufferType buffer, const std::string& LIMIT_TO_MESSAGE_TYPE { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); + TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + chainstate.ResetIbd(); const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) { return; } + const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()}; + if (jump_out_of_ibd) chainstate.JumpOutOfIbd(); CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release(); const bool successfully_connected{fuzzed_data_provider.ConsumeBool()}; diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index dc035b52d61f..c50388efcf19 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,10 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); + TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + chainstate.ResetIbd(); std::vector peers; + bool jump_out_of_ibd{false}; const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); for (int i = 0; i < num_peers_to_add; ++i) { @@ -51,6 +55,8 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) } while (fuzzed_data_provider.ConsumeBool()) { + if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool(); + if (jump_out_of_ibd && chainstate.IsInitialBlockDownload()) chainstate.JumpOutOfIbd(); const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; CSerializedNetMsg net_msg; diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp new file mode 100644 index 000000000000..1aed492c3c03 --- /dev/null +++ b/src/test/util/validation.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2020 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 + +#include +#include +#include + +void TestChainState::ResetIbd() +{ + m_cached_finished_ibd = false; + assert(IsInitialBlockDownload()); +} + +void TestChainState::JumpOutOfIbd() +{ + Assert(IsInitialBlockDownload()); + m_cached_finished_ibd = true; + Assert(!IsInitialBlockDownload()); +} diff --git a/src/test/util/validation.h b/src/test/util/validation.h new file mode 100644 index 000000000000..b13aa0be60d5 --- /dev/null +++ b/src/test/util/validation.h @@ -0,0 +1,17 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TEST_UTIL_VALIDATION_H +#define BITCOIN_TEST_UTIL_VALIDATION_H + +#include + +struct TestChainState : public CChainState { + /** Reset the ibd cache to its initial state */ + void ResetIbd(); + /** Toggle IsInitialBlockDownload from true to false */ + void JumpOutOfIbd(); +}; + +#endif // BITCOIN_TEST_UTIL_VALIDATION_H diff --git a/src/validation.h b/src/validation.h index 0f1b61e17002..35bb2bd8e283 100644 --- a/src/validation.h +++ b/src/validation.h @@ -625,8 +625,7 @@ enum class CoinsCacheSizeState */ class CChainState { -private: - +protected: /** * Every received block is assigned a unique and increasing identifier, so we * know which one to give priority in case of a fork. From d4d6b329349831ac74e93c77a5ce21168a390c3d Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 10 Jan 2021 16:41:52 +0100 Subject: [PATCH 03/15] merge bitcoin#20908: Use mocktime in process_message* fuzz targets --- src/test/fuzz/process_message.cpp | 8 ++++++-- src/test/fuzz/process_messages.cpp | 9 +++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index bf57798b2723..0034447bdea3 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -74,15 +74,16 @@ void initialize_process_message() void fuzz_target(FuzzBufferType buffer, const std::string& LIMIT_TO_MESSAGE_TYPE) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + SetMockTime(1610000000); // any time to successfully reset ibd chainstate.ResetIbd(); + const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) { return; } - const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()}; - if (jump_out_of_ibd) chainstate.JumpOutOfIbd(); CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release(); const bool successfully_connected{fuzzed_data_provider.ConsumeBool()}; @@ -91,6 +92,9 @@ void fuzz_target(FuzzBufferType buffer, const std::string& LIMIT_TO_MESSAGE_TYPE g_setup->m_node.peerman->InitializeNode(&p2p_node); FillNode(fuzzed_data_provider, p2p_node, /* init_version */ successfully_connected); + const auto mock_time = ConsumeTime(fuzzed_data_provider); + SetMockTime(mock_time); + // fuzzed_data_provider is fully consumed after this call, don't use it CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes(), SER_NETWORK, PROTOCOL_VERSION}; try { diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index c50388efcf19..ae5a348e72d3 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -36,10 +36,10 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + SetMockTime(1610000000); // any time to successfully reset ibd chainstate.ResetIbd(); - std::vector peers; - bool jump_out_of_ibd{false}; + std::vector peers; const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); for (int i = 0; i < num_peers_to_add; ++i) { peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release()); @@ -55,10 +55,11 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) } while (fuzzed_data_provider.ConsumeBool()) { - if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool(); - if (jump_out_of_ibd && chainstate.IsInitialBlockDownload()) chainstate.JumpOutOfIbd(); const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; + const auto mock_time = ConsumeTime(fuzzed_data_provider); + SetMockTime(mock_time); + CSerializedNetMsg net_msg; net_msg.command = random_message_type; net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider); From e12bc1f71b44a61da0b5cee0ca5baf0d6d0f41bd Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 4 Feb 2024 11:59:46 +0000 Subject: [PATCH 04/15] fuzz: add missing Dash-specific network messages --- src/test/fuzz/process_message.cpp | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 0034447bdea3..05cf51a4bee6 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -118,7 +118,16 @@ FUZZ_TARGET_MSG(blocktxn); FUZZ_TARGET_MSG(cfcheckpt); FUZZ_TARGET_MSG(cfheaders); FUZZ_TARGET_MSG(cfilter); +FUZZ_TARGET_MSG(clsig); FUZZ_TARGET_MSG(cmpctblock); +FUZZ_TARGET_MSG(dsa); +FUZZ_TARGET_MSG(dsc); +FUZZ_TARGET_MSG(dsf); +FUZZ_TARGET_MSG(dsi); +FUZZ_TARGET_MSG(dsq); +FUZZ_TARGET_MSG(dss); +FUZZ_TARGET_MSG(dssu); +FUZZ_TARGET_MSG(dstx); FUZZ_TARGET_MSG(feefilter); FUZZ_TARGET_MSG(filteradd); FUZZ_TARGET_MSG(filterclear); @@ -131,16 +140,47 @@ FUZZ_TARGET_MSG(getcfheaders); FUZZ_TARGET_MSG(getcfilters); FUZZ_TARGET_MSG(getdata); FUZZ_TARGET_MSG(getheaders); +FUZZ_TARGET_MSG(getheaders2); +FUZZ_TARGET_MSG(getmnlistd); +FUZZ_TARGET_MSG(getqrinfo); +FUZZ_TARGET_MSG(getsporks); +FUZZ_TARGET_MSG(govobj); +FUZZ_TARGET_MSG(govobjvote); +FUZZ_TARGET_MSG(govsync); FUZZ_TARGET_MSG(headers); +FUZZ_TARGET_MSG(headers2); FUZZ_TARGET_MSG(inv); +FUZZ_TARGET_MSG(isdlock); FUZZ_TARGET_MSG(mempool); FUZZ_TARGET_MSG(merkleblock); +FUZZ_TARGET_MSG(mnauth); +FUZZ_TARGET_MSG(mnlistdiff); FUZZ_TARGET_MSG(notfound); FUZZ_TARGET_MSG(ping); FUZZ_TARGET_MSG(pong); +FUZZ_TARGET_MSG(qbsigs); +FUZZ_TARGET_MSG(qcomplaint); +FUZZ_TARGET_MSG(qcontrib); +FUZZ_TARGET_MSG(qdata); +FUZZ_TARGET_MSG(qfcommit); +FUZZ_TARGET_MSG(qgetdata); +FUZZ_TARGET_MSG(qgetsigs); +FUZZ_TARGET_MSG(qjustify); +FUZZ_TARGET_MSG(qpcommit); +FUZZ_TARGET_MSG(qrinfo); +FUZZ_TARGET_MSG(qsendrecsigs); +FUZZ_TARGET_MSG(qsigrec); +FUZZ_TARGET_MSG(qsigsesann); +FUZZ_TARGET_MSG(qsigshare); +FUZZ_TARGET_MSG(qsigsinv); +FUZZ_TARGET_MSG(qwatch); FUZZ_TARGET_MSG(sendaddrv2); FUZZ_TARGET_MSG(sendcmpct); +FUZZ_TARGET_MSG(senddsq); FUZZ_TARGET_MSG(sendheaders); +FUZZ_TARGET_MSG(sendheaders2); +FUZZ_TARGET_MSG(spork); +FUZZ_TARGET_MSG(ssc); FUZZ_TARGET_MSG(tx); FUZZ_TARGET_MSG(verack); FUZZ_TARGET_MSG(version); From e866162ba91c7088a3a752f9a75d5c226c6c89aa Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 4 Feb 2024 12:00:04 +0000 Subject: [PATCH 05/15] fuzz: drop nonexistent messages from `FUZZ_TARGET_MSG` in process_message Dash doesn't have feefilters or SegWit. --- src/test/fuzz/process_message.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 05cf51a4bee6..496e85d44ef3 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -128,7 +128,6 @@ FUZZ_TARGET_MSG(dsq); FUZZ_TARGET_MSG(dss); FUZZ_TARGET_MSG(dssu); FUZZ_TARGET_MSG(dstx); -FUZZ_TARGET_MSG(feefilter); FUZZ_TARGET_MSG(filteradd); FUZZ_TARGET_MSG(filterclear); FUZZ_TARGET_MSG(filterload); @@ -184,4 +183,3 @@ FUZZ_TARGET_MSG(ssc); FUZZ_TARGET_MSG(tx); FUZZ_TARGET_MSG(verack); FUZZ_TARGET_MSG(version); -FUZZ_TARGET_MSG(wtxidrelay); From 6ff3a46b3d83914ae1d2812549c244f102a4835e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:31:05 +0200 Subject: [PATCH 06/15] merge bitcoin#21336: Make .gitignore ignore src/test/fuzz/fuzz.exe --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 54855b71f771..e5b3265f888a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,7 @@ src/dash-gui src/dash-node src/dash-tx src/dash-wallet -src/test/fuzz/* -!src/test/fuzz/*.* +src/test/fuzz/fuzz src/test/test_dash src/qt/test/test_dash-qt src/qt/res/css/colors/* From 16f13cafe3b0fc7545b40930ef06ad33c9b547fc Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 15 Mar 2021 15:20:03 +0000 Subject: [PATCH 07/15] merge bitcoin#21443: Implement fuzzed_dns_lookup_function as lambda --- src/test/fuzz/netbase_dns_lookup.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/test/fuzz/netbase_dns_lookup.cpp b/src/test/fuzz/netbase_dns_lookup.cpp index 2c984e15ff27..cf2fa337443c 100644 --- a/src/test/fuzz/netbase_dns_lookup.cpp +++ b/src/test/fuzz/netbase_dns_lookup.cpp @@ -12,27 +12,22 @@ #include #include -namespace { -FuzzedDataProvider* fuzzed_data_provider_ptr = nullptr; - -std::vector fuzzed_dns_lookup_function(const std::string& name, bool allow_lookup) -{ - std::vector resolved_addresses; - while (fuzzed_data_provider_ptr->ConsumeBool()) { - resolved_addresses.push_back(ConsumeNetAddr(*fuzzed_data_provider_ptr)); - } - return resolved_addresses; -} -} // namespace - FUZZ_TARGET(netbase_dns_lookup) { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; - fuzzed_data_provider_ptr = &fuzzed_data_provider; const std::string name = fuzzed_data_provider.ConsumeRandomLengthString(512); const unsigned int max_results = fuzzed_data_provider.ConsumeIntegral(); const bool allow_lookup = fuzzed_data_provider.ConsumeBool(); const uint16_t default_port = fuzzed_data_provider.ConsumeIntegral(); + + auto fuzzed_dns_lookup_function = [&](const std::string&, bool) { + std::vector resolved_addresses; + while (fuzzed_data_provider.ConsumeBool()) { + resolved_addresses.push_back(ConsumeNetAddr(fuzzed_data_provider)); + } + return resolved_addresses; + }; + { std::vector resolved_addresses; if (LookupHost(name, resolved_addresses, max_results, allow_lookup, fuzzed_dns_lookup_function)) { @@ -73,5 +68,4 @@ FUZZ_TARGET(netbase_dns_lookup) assert(resolved_subnet.IsValid()); } } - fuzzed_data_provider_ptr = nullptr; } From b46521b8a6a22f73cb5f17f95a0f9cb55d770f6f Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:58:39 +0000 Subject: [PATCH 08/15] merge bitcoin#21142: Add tx_pool fuzz targets --- src/Makefile.test.include | 1 + src/test/fuzz/tx_pool.cpp | 281 ++++++++++++++++++++++++++++++++++++++ src/test/fuzz/util.cpp | 48 +++++++ src/test/fuzz/util.h | 20 ++- src/txmempool.h | 2 +- 5 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 src/test/fuzz/tx_pool.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 93353dc8ff05..fc1e52d6df74 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -327,6 +327,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/transaction.cpp \ test/fuzz/tx_in.cpp \ test/fuzz/tx_out.cpp \ + test/fuzz/tx_pool.cpp \ test/fuzz/validation_load_mempool.cpp \ test/fuzz/versionbits.cpp endif # ENABLE_FUZZ_BINARY diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp new file mode 100644 index 000000000000..02a3cd3305a6 --- /dev/null +++ b/src/test/fuzz/tx_pool.cpp @@ -0,0 +1,281 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +const TestingSetup* g_setup; +std::vector g_outpoints_coinbase_init; + +struct MockedTxPool : public CTxMemPool { + void RollingFeeUpdate() + { + lastRollingFeeUpdate = GetTime(); + blockSinceLastRollingFeeBump = true; + } +}; + +void initialize_tx_pool() +{ + static const auto testing_setup = MakeNoLogFileContext(); + g_setup = testing_setup.get(); + + for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) { + CTxIn in = MineBlock(g_setup->m_node, CScript() << OP_TRUE); + // Remember the txids to avoid expensive disk acess later on + g_outpoints_coinbase_init.push_back(in.prevout); + } + SyncWithValidationInterfaceQueue(); +} + +struct TransactionsDelta final : public CValidationInterface { + std::set& m_removed; + std::set& m_added; + + explicit TransactionsDelta(std::set& r, std::set& a) + : m_removed{r}, m_added{a} {} + + void TransactionAddedToMempool(const CTransactionRef& tx, int64_t /* nAcceptTime */) override + { + Assert(m_added.insert(tx).second); + } + + void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) override + { + Assert(m_removed.insert(tx).second); + } +}; + +void SetMempoolConstraints(ArgsManager& args, FuzzedDataProvider& fuzzed_data_provider) +{ + args.ForceSetArg("-limitancestorcount", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 50))); + args.ForceSetArg("-limitancestorsize", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 202))); + args.ForceSetArg("-limitdescendantcount", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 50))); + args.ForceSetArg("-limitdescendantsize", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 202))); + args.ForceSetArg("-maxmempool", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 200))); + args.ForceSetArg("-mempoolexpiry", + ToString(fuzzed_data_provider.ConsumeIntegralInRange(0, 999))); +} + +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(); + + SetMockTime(ConsumeTime(fuzzed_data_provider)); + SetMempoolConstraints(*node.args, fuzzed_data_provider); + + // All RBF-spendable outpoints + std::set outpoints_rbf; + // All outpoints counting toward the total supply (subset of outpoints_rbf) + std::set outpoints_supply; + for (const auto& outpoint : g_outpoints_coinbase_init) { + Assert(outpoints_supply.insert(outpoint).second); + if (outpoints_supply.size() >= COINBASE_MATURITY) break; + } + outpoints_rbf = outpoints_supply; + + // The sum of the values of all spendable outpoints + constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN}; + + CTxMemPool tx_pool_{/* estimator */ nullptr, /* check_ratio */ 1}; + MockedTxPool& tx_pool = *(MockedTxPool*)&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) { + Coin c; + amount_view.GetCoin(outpoint, c); + Assert(!c.IsSpent()); + return c.out.nValue; + }; + + while (fuzzed_data_provider.ConsumeBool()) { + { + // Total supply is all outpoints + CAmount supply_now{0}; + for (const auto& op : outpoints_supply) { + supply_now += GetAmount(op); + } + Assert(supply_now == SUPPLY_TOTAL); + } + Assert(!outpoints_supply.empty()); + + // Create transaction to add to the mempool + const CTransactionRef tx = [&] { + CMutableTransaction tx_mut; + tx_mut.nVersion = CTransaction::CURRENT_VERSION; + tx_mut.nLockTime = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral(); + const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange(1, outpoints_rbf.size()); + const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange(1, outpoints_rbf.size() * 2); + + CAmount amount_in{0}; + for (int i = 0; i < num_in; ++i) { + // Pop random outpoint + auto pop = outpoints_rbf.begin(); + std::advance(pop, fuzzed_data_provider.ConsumeIntegralInRange(0, outpoints_rbf.size() - 1)); + const auto outpoint = *pop; + outpoints_rbf.erase(pop); + amount_in += GetAmount(outpoint); + + // Create input + const auto sequence = ConsumeSequence(fuzzed_data_provider); + const auto script_sig = CScript{}; + CTxIn in; + in.prevout = outpoint; + in.nSequence = sequence; + in.scriptSig = script_sig; + + tx_mut.vin.push_back(in); + } + const auto amount_fee = fuzzed_data_provider.ConsumeIntegralInRange(-1000, amount_in); + const auto amount_out = (amount_in - amount_fee) / num_out; + for (int i = 0; i < num_out; ++i) { + tx_mut.vout.emplace_back(amount_out, CScript() << OP_RETURN); + } + const auto tx = MakeTransactionRef(tx_mut); + // Restore previously removed outpoints + for (const auto& in : tx->vin) { + Assert(outpoints_rbf.insert(in.prevout).second); + } + return tx; + }(); + + if (fuzzed_data_provider.ConsumeBool()) { + SetMockTime(ConsumeTime(fuzzed_data_provider)); + } + if (fuzzed_data_provider.ConsumeBool()) { + SetMempoolConstraints(*node.args, fuzzed_data_provider); + } + if (fuzzed_data_provider.ConsumeBool()) { + tx_pool.RollingFeeUpdate(); + } + if (fuzzed_data_provider.ConsumeBool()) { + const auto& txid = fuzzed_data_provider.ConsumeBool() ? + tx->GetHash() : + PickValue(fuzzed_data_provider, outpoints_rbf).hash; + const auto delta = fuzzed_data_provider.ConsumeIntegralInRange(-50 * COIN, +50 * COIN); + tx_pool.PrioritiseTransaction(txid, delta); + } + + // Remember all removed and added transactions + std::set removed; + std::set added; + auto txr = std::make_shared(removed, added); + RegisterSharedValidationInterface(txr); + const bool bypass_limits = fuzzed_data_provider.ConsumeBool(); + ::fRequireStandard = fuzzed_data_provider.ConsumeBool(); + const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx_pool, tx, bypass_limits)); + const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; + SyncWithValidationInterfaceQueue(); + UnregisterSharedValidationInterface(txr); + + Assert(accepted != added.empty()); + Assert(accepted == res.m_state.IsValid()); + Assert(accepted != res.m_state.IsInvalid()); + if (accepted) { + Assert(added.size() == 1); // For now, no package acceptance + Assert(tx == *added.begin()); + } else { + // Do not consider rejected transaction removed + removed.erase(tx); + } + + // Helper to insert spent and created outpoints of a tx into collections + using Sets = std::vector>>; + const auto insert_tx = [](Sets created_by_tx, Sets consumed_by_tx, const auto& tx) { + for (size_t i{0}; i < tx.vout.size(); ++i) { + for (auto& set : created_by_tx) { + Assert(set.get().emplace(tx.GetHash(), i).second); + } + } + for (const auto& in : tx.vin) { + for (auto& set : consumed_by_tx) { + Assert(set.get().insert(in.prevout).second); + } + } + }; + // Add created outpoints, remove spent outpoints + { + // Outpoints that no longer exist at all + std::set consumed_erased; + // Outpoints that no longer count toward the total supply + std::set consumed_supply; + for (const auto& removed_tx : removed) { + insert_tx(/* created_by_tx */ {consumed_erased}, /* consumed_by_tx */ {outpoints_supply}, /* tx */ *removed_tx); + } + for (const auto& added_tx : added) { + insert_tx(/* created_by_tx */ {outpoints_supply, outpoints_rbf}, /* consumed_by_tx */ {consumed_supply}, /* tx */ *added_tx); + } + for (const auto& p : consumed_erased) { + Assert(outpoints_supply.erase(p) == 1); + Assert(outpoints_rbf.erase(p) == 1); + } + for (const auto& p : consumed_supply) { + Assert(outpoints_supply.erase(p) == 1); + } + } + } + WITH_LOCK(::cs_main, tx_pool.check(chainstate)); + const auto info_all = tx_pool.infoAll(); + if (!info_all.empty()) { + const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx; + WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK)); + std::vector all_txids; + tx_pool.queryHashes(all_txids); + assert(all_txids.size() < info_all.size()); + WITH_LOCK(::cs_main, tx_pool.check(chainstate)); + } + SyncWithValidationInterfaceQueue(); +} + +FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const auto& node = g_setup->m_node; + + std::vector txids; + for (const auto& outpoint : g_outpoints_coinbase_init) { + txids.push_back(outpoint.hash); + if (txids.size() >= COINBASE_MATURITY) break; + } + for (int i{0}; i <= 3; ++i) { + // Add some immature and non-existent outpoints + txids.push_back(g_outpoints_coinbase_init.at(i).hash); + txids.push_back(ConsumeUInt256(fuzzed_data_provider)); + } + + CTxMemPool tx_pool{/* estimator */ nullptr, /* check_ratio */ 1}; + + while (fuzzed_data_provider.ConsumeBool()) { + const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids); + + 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 bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; + if (accepted) { + txids.push_back(tx->GetHash()); + } + + SyncWithValidationInterfaceQueue(); + } +} +} // namespace diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index e3dfcd933b54..9c1ae3d01b3a 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -4,6 +4,7 @@ #include +#include #include #include @@ -215,3 +216,50 @@ void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_v node.m_tx_relay->fRelayTxes = filter_txs; } } + +CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional>& prevout_txids, const int max_num_in, const int max_num_out) noexcept +{ + CMutableTransaction tx_mut; + tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ? + CTransaction::CURRENT_VERSION : + fuzzed_data_provider.ConsumeIntegral(); + tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral(); + const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange(0, max_num_in); + const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange(0, max_num_out); + for (int i = 0; i < num_in; ++i) { + const auto& txid_prev = prevout_txids ? + PickValue(fuzzed_data_provider, *prevout_txids) : + ConsumeUInt256(fuzzed_data_provider); + const auto index_out = fuzzed_data_provider.ConsumeIntegralInRange(0, max_num_out); + const auto sequence = ConsumeSequence(fuzzed_data_provider); + const auto script_sig = ConsumeScript(fuzzed_data_provider); + CTxIn in; + in.prevout = COutPoint{txid_prev, index_out}; + in.nSequence = sequence; + in.scriptSig = script_sig; + + tx_mut.vin.push_back(in); + } + for (int i = 0; i < num_out; ++i) { + const auto amount = fuzzed_data_provider.ConsumeIntegralInRange(-10, 50 * COIN + 10); + const auto script_pk = ConsumeScript(fuzzed_data_provider, /* max_length */ 128); + tx_mut.vout.emplace_back(amount, script_pk); + } + return tx_mut; +} + +CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length) noexcept +{ + const std::vector b = ConsumeRandomLengthByteVector(fuzzed_data_provider); + return {b.begin(), b.end()}; +} + +uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + return fuzzed_data_provider.ConsumeBool() ? + fuzzed_data_provider.PickValueInArray({ + CTxIn::SEQUENCE_FINAL, + CTxIn::SEQUENCE_FINAL - 1 + }) : + fuzzed_data_provider.ConsumeIntegral(); +} diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 6cab0751a11b..8393b84dd7f2 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -51,6 +51,16 @@ void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables) return ((i++ == call_index ? callables() : void()), ...); } +template +const auto& PickValue(FuzzedDataProvider& fuzzed_data_provider, const Collection& col) +{ + const auto sz = col.size(); + assert(sz >= 1); + auto it = col.begin(); + std::advance(it, fuzzed_data_provider.ConsumeIntegralInRange(0, sz - 1)); + return *it; +} + [[ nodiscard ]] inline std::vector ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept { const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length); @@ -128,11 +138,11 @@ template return fuzzed_data_provider.ConsumeIntegralInRange(time_min, time_max); } -[[ nodiscard ]] inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept -{ - const std::vector b = ConsumeRandomLengthByteVector(fuzzed_data_provider); - return {b.begin(), b.end()}; -} +[[ nodiscard ]] CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional>& prevout_txids, const int max_num_in = 10, const int max_num_out = 10) noexcept; + +[[ nodiscard ]] CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept; + +[[ nodiscard ]] uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept; [[ nodiscard ]] inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept { diff --git a/src/txmempool.h b/src/txmempool.h index cbf5fb8e12d5..4b7d09bad6e3 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -442,7 +442,7 @@ enum class MemPoolRemovalReason { */ class CTxMemPool { -private: +protected: const int m_check_ratio; //!< Value n means that 1 times in n we check. std::atomic nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation CBlockPolicyEstimator* minerPolicyEstimator; From 5bb3ac365e878a67a457a84279768e13bfa1853e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 23 Mar 2021 11:04:18 +0100 Subject: [PATCH 09/15] merge bitcoin#21512: Fix tx_pool target to properly fuzz immature outpoints --- src/test/fuzz/process_message.cpp | 4 ++-- src/test/fuzz/process_messages.cpp | 4 ++-- src/test/fuzz/tx_pool.cpp | 21 +++++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 496e85d44ef3..915b949fe400 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -75,8 +75,8 @@ void fuzz_target(FuzzBufferType buffer, const std::string& LIMIT_TO_MESSAGE_TYPE { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); - TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + ConnmanTestMsg& connman = *static_cast(g_setup->m_node.connman.get()); + TestChainState& chainstate = *static_cast(&g_setup->m_node.chainman->ActiveChainstate()); SetMockTime(1610000000); // any time to successfully reset ibd chainstate.ResetIbd(); diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index ae5a348e72d3..deb94743dde6 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -34,8 +34,8 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get(); - TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate(); + ConnmanTestMsg& connman = *static_cast(g_setup->m_node.connman.get()); + TestChainState& chainstate = *static_cast(&g_setup->m_node.chainman->ActiveChainstate()); SetMockTime(1610000000); // any time to successfully reset ibd chainstate.ResetIbd(); diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 02a3cd3305a6..c52da0a75629 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -15,7 +15,8 @@ namespace { const TestingSetup* g_setup; -std::vector g_outpoints_coinbase_init; +std::vector g_outpoints_coinbase_init_mature; +std::vector g_outpoints_coinbase_init_immature; struct MockedTxPool : public CTxMemPool { void RollingFeeUpdate() @@ -33,7 +34,10 @@ void initialize_tx_pool() for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) { CTxIn in = MineBlock(g_setup->m_node, CScript() << OP_TRUE); // Remember the txids to avoid expensive disk acess later on - g_outpoints_coinbase_init.push_back(in.prevout); + auto& outpoints = i < COINBASE_MATURITY ? + g_outpoints_coinbase_init_mature : + g_outpoints_coinbase_init_immature; + outpoints.push_back(in.prevout); } SyncWithValidationInterfaceQueue(); } @@ -85,9 +89,8 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) std::set outpoints_rbf; // All outpoints counting toward the total supply (subset of outpoints_rbf) std::set outpoints_supply; - for (const auto& outpoint : g_outpoints_coinbase_init) { + for (const auto& outpoint : g_outpoints_coinbase_init_mature) { Assert(outpoints_supply.insert(outpoint).second); - if (outpoints_supply.size() >= COINBASE_MATURITY) break; } outpoints_rbf = outpoints_supply; @@ -95,14 +98,13 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN}; CTxMemPool tx_pool_{/* estimator */ nullptr, /* check_ratio */ 1}; - MockedTxPool& tx_pool = *(MockedTxPool*)&tx_pool_; + MockedTxPool& tx_pool = *static_cast(&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) { Coin c; - amount_view.GetCoin(outpoint, c); - Assert(!c.IsSpent()); + Assert(amount_view.GetCoin(outpoint, c)); return c.out.nValue; }; @@ -251,13 +253,12 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool) const auto& node = g_setup->m_node; std::vector txids; - for (const auto& outpoint : g_outpoints_coinbase_init) { + for (const auto& outpoint : g_outpoints_coinbase_init_mature) { txids.push_back(outpoint.hash); - if (txids.size() >= COINBASE_MATURITY) break; } for (int i{0}; i <= 3; ++i) { // Add some immature and non-existent outpoints - txids.push_back(g_outpoints_coinbase_init.at(i).hash); + txids.push_back(g_outpoints_coinbase_init_immature.at(i).hash); txids.push_back(ConsumeUInt256(fuzzed_data_provider)); } From 33336b93d36537e729f03fa48acf5034da0686b8 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:19:27 +0000 Subject: [PATCH 10/15] merge bitcoin#20833: enable packages through testmempoolaccept includes: - c9e1a26d1f17c8b98632b7796ffa8f8788b5a83c --- src/test/fuzz/tx_pool.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index c52da0a75629..3a083667562d 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -183,6 +183,16 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) RegisterSharedValidationInterface(txr); const bool bypass_limits = fuzzed_data_provider.ConsumeBool(); ::fRequireStandard = fuzzed_data_provider.ConsumeBool(); + + // 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)); + auto it = result_package.m_tx_results.find(tx->GetHash()); + 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 bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; SyncWithValidationInterfaceQueue(); From 51128482a2731204a7c2bebbf83a4624c8aa49c1 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 24 Mar 2021 07:01:35 +0100 Subject: [PATCH 11/15] merge bitcoin#21522: Use PickValue where possible --- src/test/fuzz/pow.cpp | 8 ++++---- src/test/fuzz/process_messages.cpp | 2 +- src/test/fuzz/util.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/fuzz/pow.cpp b/src/test/fuzz/pow.cpp index fd0ca0644a30..04f51d3fb647 100644 --- a/src/test/fuzz/pow.cpp +++ b/src/test/fuzz/pow.cpp @@ -35,7 +35,7 @@ FUZZ_TARGET_INIT(pow, initialize_pow) } CBlockIndex current_block{*block_header}; { - CBlockIndex* previous_block = !blocks.empty() ? &blocks[fuzzed_data_provider.ConsumeIntegralInRange(0, blocks.size() - 1)] : nullptr; + CBlockIndex* previous_block = blocks.empty() ? nullptr : &PickValue(fuzzed_data_provider, blocks); const int current_height = (previous_block != nullptr && previous_block->nHeight != std::numeric_limits::max()) ? previous_block->nHeight + 1 : 0; if (fuzzed_data_provider.ConsumeBool()) { current_block.pprev = previous_block; @@ -64,9 +64,9 @@ FUZZ_TARGET_INIT(pow, initialize_pow) } } { - const CBlockIndex* to = &blocks[fuzzed_data_provider.ConsumeIntegralInRange(0, blocks.size() - 1)]; - const CBlockIndex* from = &blocks[fuzzed_data_provider.ConsumeIntegralInRange(0, blocks.size() - 1)]; - const CBlockIndex* tip = &blocks[fuzzed_data_provider.ConsumeIntegralInRange(0, blocks.size() - 1)]; + const CBlockIndex* to = &PickValue(fuzzed_data_provider, blocks); + const CBlockIndex* from = &PickValue(fuzzed_data_provider, blocks); + const CBlockIndex* tip = &PickValue(fuzzed_data_provider, blocks); try { (void)GetBlockProofEquivalentTime(*to, *from, *tip, consensus_params); } catch (const uint_error&) { diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index deb94743dde6..b61df25ed717 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -64,7 +64,7 @@ FUZZ_TARGET_INIT(process_messages, initialize_process_messages) net_msg.command = random_message_type; net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider); - CNode& random_node = *peers.at(fuzzed_data_provider.ConsumeIntegralInRange(0, peers.size() - 1)); + CNode& random_node = *PickValue(fuzzed_data_provider, peers); (void)connman.ReceiveMsgFrom(random_node, net_msg); random_node.fPauseSend = false; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 8393b84dd7f2..db0359aa8d3e 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -52,7 +52,7 @@ void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables) } template -const auto& PickValue(FuzzedDataProvider& fuzzed_data_provider, const Collection& col) +auto& PickValue(FuzzedDataProvider& fuzzed_data_provider, Collection& col) { const auto sz = col.size(); assert(sz >= 1); From 689b5134aeba4018632b55c48eed519150c60712 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:05:02 +0000 Subject: [PATCH 12/15] merge bitcoin#21553: Misc refactor --- src/Makefile.test_util.include | 2 ++ src/test/fuzz/coins_view.cpp | 7 ++----- src/test/fuzz/script_flags.cpp | 10 +--------- src/test/fuzz/signature_checker.cpp | 14 +++++++------- src/test/fuzz/util.cpp | 2 +- src/test/util/script.cpp | 12 ++++++++++++ src/test/util/script.h | 11 +++++++++++ 7 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 src/test/util/script.cpp create mode 100644 src/test/util/script.h diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index 1e9553e74529..1a805a1dd1f5 100644 --- a/src/Makefile.test_util.include +++ b/src/Makefile.test_util.include @@ -13,6 +13,7 @@ TEST_UTIL_H = \ test/util/logging.h \ test/util/mining.h \ test/util/net.h \ + test/util/script.h \ test/util/setup_common.h \ test/util/str.h \ test/util/transaction_utils.h \ @@ -28,6 +29,7 @@ libtest_util_a_SOURCES = \ test/util/logging.cpp \ test/util/mining.cpp \ test/util/net.cpp \ + test/util/script.cpp \ test/util/setup_common.cpp \ test/util/str.cpp \ test/util/transaction_utils.cpp \ diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index da96d2fae060..ab69fd93d98a 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -229,11 +229,8 @@ 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; } - try { - (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange(0, std::numeric_limits::max()), tx_fee_out); - assert(MoneyRange(tx_fee_out)); - } catch (const std::runtime_error&) { - } + (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange(0, std::numeric_limits::max()), tx_fee_out); + assert(MoneyRange(tx_fee_out)); }, [&] { const CTransaction transaction{random_mutable_transaction}; diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp index bfabf3af732c..c38dbfb4d83a 100644 --- a/src/test/fuzz/script_flags.cpp +++ b/src/test/fuzz/script_flags.cpp @@ -5,13 +5,11 @@ #include #include