diff options
Diffstat (limited to 'src/test/fuzz')
-rw-r--r-- | src/test/fuzz/coins_view.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/decode_tx.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/descriptor_parse.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/deserialize.cpp | 57 | ||||
-rw-r--r-- | src/test/fuzz/merkleblock.cpp | 34 | ||||
-rw-r--r-- | src/test/fuzz/process_message.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/process_messages.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/script_flags.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 3 |
9 files changed, 99 insertions, 29 deletions
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index c186bef7ae..ac034809b0 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -229,7 +229,8 @@ void test_one_input(const std::vector<uint8_t>& buffer) break; } case 1: { - (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache); + (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, false); + (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, true); break; } case 2: { diff --git a/src/test/fuzz/decode_tx.cpp b/src/test/fuzz/decode_tx.cpp index 0d89d4228a..a2b18c0365 100644 --- a/src/test/fuzz/decode_tx.cpp +++ b/src/test/fuzz/decode_tx.cpp @@ -19,13 +19,14 @@ void test_one_input(const std::vector<uint8_t>& buffer) const bool result_none = DecodeHexTx(mtx, tx_hex, false, false); const bool result_try_witness = DecodeHexTx(mtx, tx_hex, false, true); const bool result_try_witness_and_maybe_no_witness = DecodeHexTx(mtx, tx_hex, true, true); - const bool result_try_no_witness = DecodeHexTx(mtx, tx_hex, true, false); + CMutableTransaction no_witness_mtx; + const bool result_try_no_witness = DecodeHexTx(no_witness_mtx, tx_hex, true, false); assert(!result_none); if (result_try_witness_and_maybe_no_witness) { assert(result_try_no_witness || result_try_witness); } - // if (result_try_no_witness) { // Uncomment when https://github.com/bitcoin/bitcoin/pull/17775 is merged - if (result_try_witness) { // Remove stop-gap when https://github.com/bitcoin/bitcoin/pull/17775 is merged + if (result_try_no_witness) { + assert(!no_witness_mtx.HasWitness()); assert(result_try_witness_and_maybe_no_witness); } } diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp index 001758ffdb..7b57a2c1e2 100644 --- a/src/test/fuzz/descriptor_parse.cpp +++ b/src/test/fuzz/descriptor_parse.cpp @@ -11,7 +11,8 @@ void initialize() { static const ECCVerifyHandle verify_handle; - SelectParams(CBaseChainParams::REGTEST); + ECC_Start(); + SelectParams(CBaseChainParams::MAIN); } void test_one_input(const std::vector<uint8_t>& buffer) diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index b799d3b43b..8ca5366c8a 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -13,7 +13,9 @@ #include <key.h> #include <merkleblock.h> #include <net.h> +#include <netbase.h> #include <node/utxo_snapshot.h> +#include <optional.h> #include <primitives/block.h> #include <protocol.h> #include <psbt.h> @@ -44,9 +46,9 @@ struct invalid_fuzzing_input_exception : public std::exception { }; template <typename T> -CDataStream Serialize(const T& obj) +CDataStream Serialize(const T& obj, const int version = INIT_PROTO_VERSION) { - CDataStream ds(SER_NETWORK, INIT_PROTO_VERSION); + CDataStream ds(SER_NETWORK, version); ds << obj; return ds; } @@ -60,15 +62,19 @@ T Deserialize(CDataStream ds) } template <typename T> -void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj) +void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj, const Optional<int> protocol_version = nullopt) { CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); - try { - int version; - ds >> version; - ds.SetVersion(version); - } catch (const std::ios_base::failure&) { - throw invalid_fuzzing_input_exception(); + if (protocol_version) { + ds.SetVersion(*protocol_version); + } else { + try { + int version; + ds >> version; + ds.SetVersion(version); + } catch (const std::ios_base::failure&) { + throw invalid_fuzzing_input_exception(); + } } try { ds >> obj; @@ -79,9 +85,9 @@ void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj) } template <typename T> -void AssertEqualAfterSerializeDeserialize(const T& obj) +void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT_PROTO_VERSION) { - assert(Deserialize<T>(Serialize(obj)) == obj); + assert(Deserialize<T>(Serialize(obj, version)) == obj); } } // namespace @@ -124,9 +130,15 @@ void test_one_input(const std::vector<uint8_t>& buffer) CScript script; DeserializeFromFuzzingInput(buffer, script); #elif SUB_NET_DESERIALIZE - CSubNet sub_net; - DeserializeFromFuzzingInput(buffer, sub_net); - AssertEqualAfterSerializeDeserialize(sub_net); + CSubNet sub_net_1; + DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION); + AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION); + CSubNet sub_net_2; + DeserializeFromFuzzingInput(buffer, sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + AssertEqualAfterSerializeDeserialize(sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + CSubNet sub_net_3; + DeserializeFromFuzzingInput(buffer, sub_net_3); + AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT); #elif TX_IN_DESERIALIZE CTxIn tx_in; DeserializeFromFuzzingInput(buffer, tx_in); @@ -183,11 +195,24 @@ void test_one_input(const std::vector<uint8_t>& buffer) #elif NETADDR_DESERIALIZE CNetAddr na; DeserializeFromFuzzingInput(buffer, na); - AssertEqualAfterSerializeDeserialize(na); + if (na.IsAddrV1Compatible()) { + AssertEqualAfterSerializeDeserialize(na); + } + AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT); #elif SERVICE_DESERIALIZE CService s; DeserializeFromFuzzingInput(buffer, s); - AssertEqualAfterSerializeDeserialize(s); + if (s.IsAddrV1Compatible()) { + AssertEqualAfterSerializeDeserialize(s); + } + AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT); + CService s1; + DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION); + AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION); + assert(s1.IsAddrV1Compatible()); + CService s2; + DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); + AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT); #elif MESSAGEHEADER_DESERIALIZE CMessageHeader mh; DeserializeFromFuzzingInput(buffer, mh); diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp index c44e334272..4710e75757 100644 --- a/src/test/fuzz/merkleblock.cpp +++ b/src/test/fuzz/merkleblock.cpp @@ -16,12 +16,36 @@ void test_one_input(const std::vector<uint8_t>& buffer) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - std::optional<CPartialMerkleTree> partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider); - if (!partial_merkle_tree) { - return; + CPartialMerkleTree partial_merkle_tree; + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1)) { + case 0: { + const std::optional<CPartialMerkleTree> opt_partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider); + if (opt_partial_merkle_tree) { + partial_merkle_tree = *opt_partial_merkle_tree; + } + break; } - (void)partial_merkle_tree->GetNumTransactions(); + case 1: { + CMerkleBlock merkle_block; + const std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider); + CBloomFilter bloom_filter; + std::set<uint256> txids; + if (opt_block && !opt_block->vtx.empty()) { + if (fuzzed_data_provider.ConsumeBool()) { + merkle_block = CMerkleBlock{*opt_block, bloom_filter}; + } else if (fuzzed_data_provider.ConsumeBool()) { + while (fuzzed_data_provider.ConsumeBool()) { + txids.insert(ConsumeUInt256(fuzzed_data_provider)); + } + merkle_block = CMerkleBlock{*opt_block, txids}; + } + } + partial_merkle_tree = merkle_block.txn; + break; + } + } + (void)partial_merkle_tree.GetNumTransactions(); std::vector<uint256> matches; std::vector<unsigned int> indices; - (void)partial_merkle_tree->ExtractMatches(matches, indices); + (void)partial_merkle_tree.ExtractMatches(matches, indices); } diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 3ef03137ec..9390399878 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -16,6 +16,7 @@ #include <test/util/mining.h> #include <test/util/net.h> #include <test/util/setup_common.h> +#include <test/util/validation.h> #include <util/memory.h> #include <validationinterface.h> #include <version.h> @@ -63,10 +64,14 @@ void test_one_input(const std::vector<uint8_t>& buffer) { 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(); CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION}; CNode& p2p_node = *MakeUnique<CNode>(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, ConnectionType::OUTBOUND_FULL_RELAY).release(); p2p_node.fSuccessfullyConnected = true; @@ -76,7 +81,7 @@ void test_one_input(const std::vector<uint8_t>& buffer) g_setup->m_node.peerman->InitializeNode(&p2p_node); try { g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, - GetTime<std::chrono::microseconds>(), std::atomic<bool>{false}); + GetTime<std::chrono::microseconds>(), std::atomic<bool>{false}); } catch (const std::ios_base::failure&) { } SyncWithValidationInterfaceQueue(); diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index f722eeac3a..19ea92b750 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -12,6 +12,7 @@ #include <test/util/mining.h> #include <test/util/net.h> #include <test/util/setup_common.h> +#include <test/util/validation.h> #include <util/memory.h> #include <validation.h> #include <validationinterface.h> @@ -39,7 +40,10 @@ void test_one_input(const std::vector<uint8_t>& buffer) 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<CNode*> 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) { @@ -58,6 +62,8 @@ void test_one_input(const std::vector<uint8_t>& buffer) } 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/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp index ffc65eedc0..300c78fca0 100644 --- a/src/test/fuzz/script_flags.cpp +++ b/src/test/fuzz/script_flags.cpp @@ -31,7 +31,6 @@ void test_one_input(const std::vector<uint8_t>& buffer) try { const CTransaction tx(deserialize, ds); - const PrecomputedTransactionData txdata(tx); unsigned int verify_flags; ds >> verify_flags; @@ -41,10 +40,17 @@ void test_one_input(const std::vector<uint8_t>& buffer) unsigned int fuzzed_flags; ds >> fuzzed_flags; + std::vector<CTxOut> spent_outputs; for (unsigned i = 0; i < tx.vin.size(); ++i) { CTxOut prevout; ds >> prevout; + spent_outputs.push_back(prevout); + } + PrecomputedTransactionData txdata; + txdata.Init(tx, std::move(spent_outputs)); + for (unsigned i = 0; i < tx.vin.size(); ++i) { + const CTxOut& prevout = txdata.m_spent_outputs.at(i); const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata}; ScriptError serror; diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index d6deb7fc3d..4f972dea1c 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -95,7 +95,8 @@ void test_one_input(const std::vector<uint8_t>& buffer) CCoinsView coins_view; const CCoinsViewCache coins_view_cache(&coins_view); - (void)AreInputsStandard(tx, coins_view_cache); + (void)AreInputsStandard(tx, coins_view_cache, false); + (void)AreInputsStandard(tx, coins_view_cache, true); (void)IsWitnessStandard(tx, coins_view_cache); UniValue u(UniValue::VOBJ); |