diff options
author | MarcoFalke <falke.marco@gmail.com> | 2021-03-23 09:59:24 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2021-03-23 09:59:40 +0100 |
commit | fd2b22bf24d81027d9908d1e8aff498d6cf1a463 (patch) | |
tree | ab0c6f3510b54eb63aeae523d6b274da60a8e624 /src/test/fuzz/util.cpp | |
parent | d400e672a032e28f976332553b9a0e23d1927ae6 (diff) | |
parent | faa9ef49d18da9223220afcc263ac91a74c291a6 (diff) |
Merge #21142: fuzz: Add tx_pool fuzz target
faa9ef49d18da9223220afcc263ac91a74c291a6 fuzz: Add tx_pool fuzz targets (MarcoFalke)
Pull request description:
ACKs for top commit:
AnthonyRonning:
reACK faa9ef49d18da9223220afcc263ac91a74c291a6
practicalswift:
Tested ACK faa9ef49d18da9223220afcc263ac91a74c291a6
glozow:
code review ACK faa9ef49d18da9223220afcc263ac91a74c291a6, a bunch of comments but non blocking
Tree-SHA512: 8d404398faa46d8e7bf93060a2fe9afd5c0c2bd6e549ff6588d2f3dd1b912dff6c5416d5477c18edecc2e85b00db4fdf4790c3e6597a5149b0d40c9d5014d82f
Diffstat (limited to 'src/test/fuzz/util.cpp')
-rw-r--r-- | src/test/fuzz/util.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 0a541e4186..93418ab1ff 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -3,8 +3,11 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <test/fuzz/util.h> +#include <test/util/script.h> +#include <util/rbf.h> #include <version.h> + void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_version) noexcept { const ServiceFlags remote_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS); @@ -23,3 +26,78 @@ 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<std::vector<uint256>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept +{ + CMutableTransaction tx_mut; + const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool(); + tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ? + CTransaction::CURRENT_VERSION : + fuzzed_data_provider.ConsumeIntegral<int32_t>(); + tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in); + const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(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<uint32_t>(0, max_num_out); + const auto sequence = ConsumeSequence(fuzzed_data_provider); + const auto script_sig = p2wsh_op_true ? CScript{} : ConsumeScript(fuzzed_data_provider); + CScriptWitness script_wit; + if (p2wsh_op_true) { + script_wit.stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE}; + } else { + script_wit = ConsumeScriptWitness(fuzzed_data_provider); + } + CTxIn in; + in.prevout = COutPoint{txid_prev, index_out}; + in.nSequence = sequence; + in.scriptSig = script_sig; + in.scriptWitness = script_wit; + + tx_mut.vin.push_back(in); + } + for (int i = 0; i < num_out; ++i) { + const auto amount = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-10, 50 * COIN + 10); + const auto script_pk = p2wsh_op_true ? + P2WSH_OP_TRUE : + ConsumeScript(fuzzed_data_provider, /* max_length */ 128, /* maybe_p2wsh */ true); + tx_mut.vout.emplace_back(amount, script_pk); + } + return tx_mut; +} + +CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, const size_t max_stack_elem_size) noexcept +{ + CScriptWitness ret; + const auto n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_stack_elem_size); + for (size_t i = 0; i < n_elements; ++i) { + ret.stack.push_back(ConsumeRandomLengthByteVector(fuzzed_data_provider)); + } + return ret; +} + +CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length, const bool maybe_p2wsh) noexcept +{ + const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider); + CScript r_script{b.begin(), b.end()}; + if (maybe_p2wsh && fuzzed_data_provider.ConsumeBool()) { + uint256 script_hash; + CSHA256().Write(&r_script[0], r_script.size()).Finalize(script_hash.begin()); + r_script.clear(); + r_script << OP_0 << ToByteVector(script_hash); + } + return r_script; +} + +uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept +{ + return fuzzed_data_provider.ConsumeBool() ? + fuzzed_data_provider.PickValueInArray({ + CTxIn::SEQUENCE_FINAL, + CTxIn::SEQUENCE_FINAL - 1, + MAX_BIP125_RBF_SEQUENCE, + }) : + fuzzed_data_provider.ConsumeIntegral<uint32_t>(); +} |