diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt index b8b395ee5..457b3a597 100644 --- a/src/test/fuzz/CMakeLists.txt +++ b/src/test/fuzz/CMakeLists.txt @@ -1,196 +1,197 @@ # Fuzzer test harness add_custom_target(bitcoin-fuzzers) define_property(GLOBAL PROPERTY FUZZ_TARGETS BRIEF_DOCS "List of fuzz targets" FULL_DOCS "A list of the fuzz targets" ) set_property(GLOBAL APPEND PROPERTY FUZZ_TARGETS bitcoin-fuzzers) include(InstallationHelper) macro(add_fuzz_target TARGET EXE_NAME) add_executable(${TARGET} EXCLUDE_FROM_ALL fuzz.cpp ${ARGN} ) set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${EXE_NAME}) target_link_libraries(${TARGET} server testutil rpcclient) add_dependencies(bitcoin-fuzzers ${TARGET}) set_property(GLOBAL APPEND PROPERTY FUZZ_TARGETS ${TARGET}) install_target(${TARGET} COMPONENT fuzzer EXCLUDE_FROM_ALL ) endmacro() function(add_regular_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} ${_fuzz_test_name} # Sources "${_fuzz_test_name}.cpp" ) endforeach() endfunction() include(SanitizeHelper) function(add_deserialize_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} ${_fuzz_test_name} # Sources deserialize.cpp ) sanitize_c_cxx_definition("" ${_fuzz_test_name} _target_definition) string(TOUPPER ${_target_definition} _target_definition) target_compile_definitions(${_fuzz_target_name} PRIVATE ${_target_definition}) endforeach() endfunction() function(add_process_message_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-process_message_" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} process_message_${_fuzz_test_name} # Sources process_message.cpp ) target_compile_definitions(${_fuzz_target_name} PRIVATE MESSAGE_TYPE=${_fuzz_test_name}) endforeach() endfunction() add_regular_fuzz_targets( addrdb asmap base_encode_decode block block_header blockfilter bloom_filter cashaddr chain descriptor_parse eval_script fee_rate flatfile float hex integer key key_io locale merkleblock multiplication_overflow net_permissions netaddress p2p_transport_deserializer parse_hd_keypath parse_iso8601 parse_numbers parse_script parse_univalue + pow process_message process_messages protocol psbt random rolling_bloom_filter script script_flags script_ops scriptnum_ops signature_checker span spanparsing string strprintf timedata transaction tx_in tx_out ) add_deserialize_fuzz_targets( addr_info_deserialize address_deserialize addrman_deserialize banentry_deserialize block_deserialize block_file_info_deserialize block_filter_deserialize block_header_and_short_txids_deserialize blockheader_deserialize blocklocator_deserialize blockmerkleroot blocktransactions_deserialize blocktransactionsrequest_deserialize blockundo_deserialize bloomfilter_deserialize coins_deserialize diskblockindex_deserialize fee_rate_deserialize flat_file_pos_deserialize inv_deserialize key_origin_info_deserialize merkle_block_deserialize messageheader_deserialize netaddr_deserialize out_point_deserialize partial_merkle_tree_deserialize partially_signed_transaction_deserialize prefilled_transaction_deserialize psbt_input_deserialize psbt_output_deserialize pub_key_deserialize script_deserialize service_deserialize snapshotmetadata_deserialize sub_net_deserialize tx_in_deserialize txoutcompressor_deserialize txundo_deserialize uint160_deserialize uint256_deserialize ) add_process_message_fuzz_targets( addr block blocktxn cmpctblock feefilter filteradd filterclear filterload getaddr getblocks getblocktxn getdata getheaders headers inv mempool notfound ping pong sendcmpct sendheaders tx verack version ) diff --git a/src/test/fuzz/pow.cpp b/src/test/fuzz/pow.cpp new file mode 100644 index 000000000..a2f045445 --- /dev/null +++ b/src/test/fuzz/pow.cpp @@ -0,0 +1,114 @@ +// 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 +#include + +#include +#include +#include + +#include +#include +#include +#include + +void initialize() { + SelectParams(CBaseChainParams::MAIN); +} + +void test_one_input(const std::vector &buffer) { + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const Config &config = GetConfig(); + const CChainParams &chainparams = config.GetChainParams(); + const Consensus::Params &consensus_params = chainparams.GetConsensus(); + std::vector blocks; + const uint32_t fixed_time = + fuzzed_data_provider.ConsumeIntegral(); + const uint32_t fixed_bits = + fuzzed_data_provider.ConsumeIntegral(); + while (fuzzed_data_provider.remaining_bytes() > 0) { + const std::optional block_header = + ConsumeDeserializable(fuzzed_data_provider); + if (!block_header) { + continue; + } + CBlockIndex current_block{*block_header}; + { + CBlockIndex *previous_block = + !blocks.empty() + ? &blocks[fuzzed_data_provider.ConsumeIntegralInRange< + size_t>(0, blocks.size() - 1)] + : nullptr; + 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; + } + if (fuzzed_data_provider.ConsumeBool()) { + current_block.nHeight = current_height; + } + if (fuzzed_data_provider.ConsumeBool()) { + current_block.nTime = + fixed_time + + current_height * consensus_params.nPowTargetSpacing; + } + if (fuzzed_data_provider.ConsumeBool()) { + current_block.nBits = fixed_bits; + } + if (fuzzed_data_provider.ConsumeBool()) { + current_block.nChainWork = + previous_block != nullptr + ? previous_block->nChainWork + + GetBlockProof(*previous_block) + : arith_uint256{0}; + } else { + current_block.nChainWork = + ConsumeArithUInt256(fuzzed_data_provider); + } + blocks.push_back(current_block); + } + { + (void)GetBlockProof(current_block); + if (current_block.nHeight != std::numeric_limits::max() && + current_block.nHeight - + (consensus_params.DifficultyAdjustmentInterval() - 1) >= + 0) { + (void)GetNextWorkRequired(¤t_block, &(*block_header), + chainparams); + } + } + { + 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)]; + try { + (void)GetBlockProofEquivalentTime(*to, *from, *tip, + consensus_params); + } catch (const uint_error &) { + } + } + { + const std::optional hash = + ConsumeDeserializable(fuzzed_data_provider); + if (hash) { + (void)CheckProofOfWork( + *hash, fuzzed_data_provider.ConsumeIntegral(), + consensus_params); + } + } + } +} diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 1e3d8d94a..14324fa2c 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -1,133 +1,139 @@ // Copyright (c) 2009-2019 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_FUZZ_UTIL_H #define BITCOIN_TEST_FUZZ_UTIL_H #include +#include #include #include