diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/process_message.cpp | 7 | ||||
-rw-r--r-- | src/test/fuzz/process_messages.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/script.cpp | 39 | ||||
-rw-r--r-- | src/test/fuzz/script_bitcoin_consensus.cpp | 31 | ||||
-rw-r--r-- | src/test/fuzz/script_descriptor_cache.cpp | 42 | ||||
-rw-r--r-- | src/test/fuzz/script_interpreter.cpp | 41 | ||||
-rw-r--r-- | src/test/fuzz/script_sigcache.cpp | 45 | ||||
-rw-r--r-- | src/test/fuzz/script_sign.cpp | 149 | ||||
-rw-r--r-- | src/test/fuzz/string.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 57 | ||||
-rw-r--r-- | src/test/raii_event_tests.cpp | 19 |
11 files changed, 428 insertions, 10 deletions
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index 665a6224b4..c51ee3cf29 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -14,6 +14,7 @@ #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/util/mining.h> +#include <test/util/net.h> #include <test/util/setup_common.h> #include <util/memory.h> #include <validationinterface.h> @@ -63,19 +64,23 @@ void initialize() 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(); 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; } CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION}; - CNode p2p_node{0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, false}; + 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{}, false).release(); p2p_node.fSuccessfullyConnected = true; p2p_node.nVersion = PROTOCOL_VERSION; p2p_node.SetSendVersion(PROTOCOL_VERSION); + connman.AddTestNode(p2p_node); g_setup->m_node.peer_logic->InitializeNode(&p2p_node); try { (void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false}); } catch (const std::ios_base::failure&) { } SyncWithValidationInterfaceQueue(); + LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement + g_setup->m_node.connman->StopNodes(); } diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp index bcbf65bdca..ad6c115a49 100644 --- a/src/test/fuzz/process_messages.cpp +++ b/src/test/fuzz/process_messages.cpp @@ -75,6 +75,7 @@ void test_one_input(const std::vector<uint8_t>& buffer) } catch (const std::ios_base::failure&) { } } - connman.ClearTestNodes(); SyncWithValidationInterfaceQueue(); + LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement + g_setup->m_node.connman->StopNodes(); } diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index e0c4ad7eb7..933cf9049d 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -11,6 +11,7 @@ #include <script/descriptor.h> #include <script/interpreter.h> #include <script/script.h> +#include <script/script_error.h> #include <script/sign.h> #include <script/signingprovider.h> #include <script/standard.h> @@ -21,6 +22,8 @@ #include <univalue.h> #include <util/memory.h> +#include <algorithm> +#include <cassert> #include <cstdint> #include <optional> #include <string> @@ -124,4 +127,40 @@ void test_one_input(const std::vector<uint8_t>& buffer) wit.SetNull(); } } + + (void)GetOpName(ConsumeOpcodeType(fuzzed_data_provider)); + (void)ScriptErrorString(static_cast<ScriptError>(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, SCRIPT_ERR_ERROR_COUNT))); + + { + const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider); + CScript append_script{bytes.begin(), bytes.end()}; + append_script << fuzzed_data_provider.ConsumeIntegral<int64_t>(); + append_script << ConsumeOpcodeType(fuzzed_data_provider); + append_script << CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; + append_script << ConsumeRandomLengthByteVector(fuzzed_data_provider); + } + + { + WitnessUnknown witness_unknown_1{}; + witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown_1.length = witness_unknown_program_1.size(); + std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown_1.program); + + WitnessUnknown witness_unknown_2{}; + witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_2 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown_2.length = witness_unknown_program_2.size(); + std::copy(witness_unknown_program_2.begin(), witness_unknown_program_2.end(), witness_unknown_2.program); + + (void)(witness_unknown_1 == witness_unknown_2); + (void)(witness_unknown_1 < witness_unknown_2); + } + + { + const CTxDestination tx_destination_1 = ConsumeTxDestination(fuzzed_data_provider); + const CTxDestination tx_destination_2 = ConsumeTxDestination(fuzzed_data_provider); + (void)(tx_destination_1 == tx_destination_2); + (void)(tx_destination_1 < tx_destination_2); + } } diff --git a/src/test/fuzz/script_bitcoin_consensus.cpp b/src/test/fuzz/script_bitcoin_consensus.cpp new file mode 100644 index 0000000000..22f4b4f44a --- /dev/null +++ b/src/test/fuzz/script_bitcoin_consensus.cpp @@ -0,0 +1,31 @@ +// 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 <script/bitcoinconsensus.h> +#include <script/interpreter.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider); + const std::vector<uint8_t> random_bytes_2 = ConsumeRandomLengthByteVector(fuzzed_data_provider); + const CAmount money = ConsumeMoney(fuzzed_data_provider); + bitcoinconsensus_error err; + bitcoinconsensus_error* err_p = fuzzed_data_provider.ConsumeBool() ? &err : nullptr; + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + assert(bitcoinconsensus_version() == BITCOINCONSENSUS_API_VER); + if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) { + return; + } + (void)bitcoinconsensus_verify_script(random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); + (void)bitcoinconsensus_verify_script_with_amount(random_bytes_1.data(), random_bytes_1.size(), money, random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); +} diff --git a/src/test/fuzz/script_descriptor_cache.cpp b/src/test/fuzz/script_descriptor_cache.cpp new file mode 100644 index 0000000000..4bfe61cec7 --- /dev/null +++ b/src/test/fuzz/script_descriptor_cache.cpp @@ -0,0 +1,42 @@ +// 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 <optional.h> +#include <pubkey.h> +#include <script/descriptor.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <string> +#include <vector> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + DescriptorCache descriptor_cache; + while (fuzzed_data_provider.ConsumeBool()) { + const std::vector<uint8_t> code = fuzzed_data_provider.ConsumeBytes<uint8_t>(BIP32_EXTKEY_SIZE); + if (code.size() == BIP32_EXTKEY_SIZE) { + CExtPubKey xpub; + xpub.Decode(code.data()); + const uint32_t key_exp_pos = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + CExtPubKey xpub_fetched; + if (fuzzed_data_provider.ConsumeBool()) { + (void)descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched); + descriptor_cache.CacheParentExtPubKey(key_exp_pos, xpub); + assert(descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched)); + } else { + const uint32_t der_index = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + (void)descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched); + descriptor_cache.CacheDerivedExtPubKey(key_exp_pos, der_index, xpub); + assert(descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched)); + } + assert(xpub == xpub_fetched); + } + (void)descriptor_cache.GetCachedParentExtPubKeys(); + (void)descriptor_cache.GetCachedDerivedExtPubKeys(); + } +} diff --git a/src/test/fuzz/script_interpreter.cpp b/src/test/fuzz/script_interpreter.cpp new file mode 100644 index 0000000000..26d5732f24 --- /dev/null +++ b/src/test/fuzz/script_interpreter.cpp @@ -0,0 +1,41 @@ +// 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 <primitives/transaction.h> +#include <script/interpreter.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <optional> +#include <string> +#include <vector> + +bool CastToBool(const std::vector<unsigned char>& vch); + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + { + const CScript script_code = ConsumeScript(fuzzed_data_provider); + const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (mtx) { + const CTransaction tx_to{*mtx}; + const unsigned int in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + if (in < tx_to.vin.size()) { + (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), nullptr); + const std::optional<CMutableTransaction> mtx_precomputed = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (mtx_precomputed) { + const CTransaction tx_precomputed{*mtx_precomputed}; + const PrecomputedTransactionData precomputed_transaction_data{tx_precomputed}; + (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), &precomputed_transaction_data); + } + } + } + } + { + (void)CastToBool(ConsumeRandomLengthByteVector(fuzzed_data_provider)); + } +} diff --git a/src/test/fuzz/script_sigcache.cpp b/src/test/fuzz/script_sigcache.cpp new file mode 100644 index 0000000000..434a47b702 --- /dev/null +++ b/src/test/fuzz/script_sigcache.cpp @@ -0,0 +1,45 @@ +// 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 <chainparams.h> +#include <chainparamsbase.h> +#include <key.h> +#include <pubkey.h> +#include <script/sigcache.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cstdint> +#include <optional> +#include <string> +#include <vector> + +void initialize() +{ + static const ECCVerifyHandle ecc_verify_handle; + ECC_Start(); + SelectParams(CBaseChainParams::REGTEST); + InitSignatureCache(); +} + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + const CTransaction tx = mutable_transaction ? CTransaction{*mutable_transaction} : CTransaction{}; + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + const CAmount amount = ConsumeMoney(fuzzed_data_provider); + const bool store = fuzzed_data_provider.ConsumeBool(); + PrecomputedTransactionData tx_data; + CachingTransactionSignatureChecker caching_transaction_signature_checker{mutable_transaction ? &tx : nullptr, n_in, amount, store, tx_data}; + const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); + if (pub_key) { + const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider); + if (!random_bytes.empty()) { + (void)caching_transaction_signature_checker.VerifySignature(random_bytes, *pub_key, ConsumeUInt256(fuzzed_data_provider)); + } + } +} diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp new file mode 100644 index 0000000000..c626f950e7 --- /dev/null +++ b/src/test/fuzz/script_sign.cpp @@ -0,0 +1,149 @@ +// 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 <chainparams.h> +#include <chainparamsbase.h> +#include <key.h> +#include <pubkey.h> +#include <script/keyorigin.h> +#include <script/sign.h> +#include <script/signingprovider.h> +#include <streams.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> + +#include <cassert> +#include <cstdint> +#include <iostream> +#include <map> +#include <optional> +#include <string> +#include <vector> + +void initialize() +{ + static const ECCVerifyHandle ecc_verify_handle; + ECC_Start(); + SelectParams(CBaseChainParams::REGTEST); +} + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128); + + { + CDataStream random_data_stream = ConsumeDataStream(fuzzed_data_provider); + std::map<CPubKey, KeyOriginInfo> hd_keypaths; + try { + DeserializeHDKeypaths(random_data_stream, key, hd_keypaths); + } catch (const std::ios_base::failure&) { + } + CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; + SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + } + + { + std::map<CPubKey, KeyOriginInfo> hd_keypaths; + while (fuzzed_data_provider.ConsumeBool()) { + const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); + if (!pub_key) { + break; + } + const std::optional<KeyOriginInfo> key_origin_info = ConsumeDeserializable<KeyOriginInfo>(fuzzed_data_provider); + if (!key_origin_info) { + break; + } + hd_keypaths[*pub_key] = *key_origin_info; + } + CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION}; + try { + SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>()); + } catch (const std::ios_base::failure&) { + } + std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths; + try { + DeserializeHDKeypaths(serialized, key, hd_keypaths); + } catch (const std::ios_base::failure&) { + } + assert(hd_keypaths.size() >= deserialized_hd_keypaths.size()); + } + + { + SignatureData signature_data_1{ConsumeScript(fuzzed_data_provider)}; + SignatureData signature_data_2{ConsumeScript(fuzzed_data_provider)}; + signature_data_1.MergeSignatureData(signature_data_2); + } + + FillableSigningProvider provider; + CKey k; + const std::vector<uint8_t> key_data = ConsumeRandomLengthByteVector(fuzzed_data_provider); + k.Set(key_data.begin(), key_data.end(), fuzzed_data_provider.ConsumeBool()); + if (k.IsValid()) { + provider.AddKey(k); + } + + { + const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + const std::optional<CTxOut> tx_out = ConsumeDeserializable<CTxOut>(fuzzed_data_provider); + const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + if (mutable_transaction && tx_out && mutable_transaction->vin.size() > n_in) { + SignatureData signature_data_1 = DataFromTransaction(*mutable_transaction, n_in, *tx_out); + CTxIn input; + UpdateInput(input, signature_data_1); + const CScript script = ConsumeScript(fuzzed_data_provider); + SignatureData signature_data_2{script}; + signature_data_1.MergeSignatureData(signature_data_2); + } + if (mutable_transaction) { + CTransaction tx_from{*mutable_transaction}; + CMutableTransaction tx_to; + const std::optional<CMutableTransaction> opt_tx_to = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider); + if (opt_tx_to) { + tx_to = *opt_tx_to; + } + CMutableTransaction script_tx_to = tx_to; + CMutableTransaction sign_transaction_tx_to = tx_to; + if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) { + (void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>()); + } + if (n_in < script_tx_to.vin.size()) { + (void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()); + MutableTransactionSignatureCreator signature_creator{&tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()}; + std::vector<unsigned char> vch_sig; + CKeyID address; + if (fuzzed_data_provider.ConsumeBool()) { + if (k.IsValid()) { + address = k.GetPubKey().GetID(); + } + } else { + address = CKeyID{ConsumeUInt160(fuzzed_data_provider)}; + } + (void)signature_creator.CreateSig(provider, vch_sig, address, ConsumeScript(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0})); + } + std::map<COutPoint, Coin> coins; + while (fuzzed_data_provider.ConsumeBool()) { + const std::optional<COutPoint> outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider); + if (!outpoint) { + break; + } + const std::optional<Coin> coin = ConsumeDeserializable<Coin>(fuzzed_data_provider); + if (!coin) { + break; + } + coins[*outpoint] = *coin; + } + std::map<int, std::string> input_errors; + (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors); + } + } + + { + SignatureData signature_data_1; + (void)ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_1); + SignatureData signature_data_2; + (void)ProduceSignature(provider, DUMMY_MAXIMUM_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_2); + } +} diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp index 50984b1aef..271062dc95 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -12,6 +12,7 @@ #include <rpc/server.h> #include <rpc/util.h> #include <script/descriptor.h> +#include <script/script.h> #include <serialize.h> #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> @@ -89,6 +90,10 @@ void test_one_input(const std::vector<uint8_t>& buffer) (void)urlDecode(random_string_1); (void)ValidAsCString(random_string_1); (void)_(random_string_1.c_str()); + try { + throw scriptnum_error{random_string_1}; + } catch (const std::runtime_error&) { + } { CDataStream data_stream{SER_NETWORK, INIT_PROTO_VERSION}; diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 9d0fb02128..f26878a704 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -12,6 +12,7 @@ #include <consensus/consensus.h> #include <primitives/transaction.h> #include <script/script.h> +#include <script/standard.h> #include <serialize.h> #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> @@ -20,6 +21,7 @@ #include <uint256.h> #include <version.h> +#include <algorithm> #include <cstdint> #include <optional> #include <string> @@ -31,6 +33,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr return {s.begin(), s.end()}; } +NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept +{ + return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION}; +} + NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept { const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size); @@ -87,10 +94,19 @@ NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_pro return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()}; } +NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + const std::vector<uint8_t> v160 = fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8); + if (v160.size() != 160 / 8) { + return {}; + } + return uint160{v160}; +} + NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept { - const std::vector<unsigned char> v256 = fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256)); - if (v256.size() != sizeof(uint256)) { + const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8); + if (v256.size() != 256 / 8) { return {}; } return uint256{v256}; @@ -116,6 +132,43 @@ NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzze return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}}; } +NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + CTxDestination tx_destination; + switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) { + case 0: { + tx_destination = CNoDestination{}; + break; + } + case 1: { + tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 2: { + tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 3: { + tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)}; + break; + } + case 4: { + tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)}; + break; + } + case 5: { + WitnessUnknown witness_unknown{}; + witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<int>(); + const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40); + witness_unknown.length = witness_unknown_program_1.size(); + std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program); + tx_destination = witness_unknown; + break; + } + } + return tx_destination; +} + template <typename T> NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept { diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 04bf7c20c1..8c2712f764 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -4,9 +4,6 @@ #include <event2/event.h> -#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED -// It would probably be ideal to define dummy test(s) that report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) - #include <map> #include <stdlib.h> @@ -16,6 +13,10 @@ #include <boost/test/unit_test.hpp> +BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) + +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED + static std::map<void*, short> tags; static std::map<void*, uint16_t> orders; static uint16_t tagSequence = 0; @@ -34,8 +35,6 @@ static void tag_free(void* mem) { free(mem); } -BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) - BOOST_AUTO_TEST_CASE(raii_event_creation) { event_set_mem_functions(tag_malloc, realloc, tag_free); @@ -87,6 +86,14 @@ BOOST_AUTO_TEST_CASE(raii_event_order) event_set_mem_functions(malloc, realloc, free); } -BOOST_AUTO_TEST_SUITE_END() +#else + +BOOST_AUTO_TEST_CASE(raii_event_tests_SKIPPED) +{ + // It would probably be ideal to report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) + BOOST_TEST_MESSAGE("Skipping raii_event_tess: libevent doesn't support event_set_mem_functions"); +} #endif // EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED + +BOOST_AUTO_TEST_SUITE_END() |