Branch data Line data Source code
1 : : // Copyright (c) 2020-2022 The Bitcoin Core developers 2 : : // Distributed under the MIT software license, see the accompanying 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : : 5 : : #include <chain.h> 6 : : #include <chainparams.h> 7 : : #include <pow.h> 8 : : #include <primitives/block.h> 9 : : #include <test/fuzz/FuzzedDataProvider.h> 10 : : #include <test/fuzz/fuzz.h> 11 : : #include <test/fuzz/util.h> 12 : : #include <util/chaintype.h> 13 : : #include <util/check.h> 14 : : #include <util/overflow.h> 15 : : 16 : : #include <cstdint> 17 : : #include <optional> 18 : : #include <string> 19 : : #include <vector> 20 : : 21 : 2 : void initialize_pow() 22 : : { 23 : 2 : SelectParams(ChainType::MAIN); 24 : 2 : } 25 : : 26 [ + - - + ]: 629 : FUZZ_TARGET(pow, .init = initialize_pow) 27 : : { 28 : 283 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 29 : 283 : const Consensus::Params& consensus_params = Params().GetConsensus(); 30 : 283 : std::vector<std::unique_ptr<CBlockIndex>> blocks; 31 [ + - ]: 283 : const uint32_t fixed_time = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); 32 [ + - ]: 283 : const uint32_t fixed_bits = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); 33 [ + - + + : 139385 : LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 10000) { + + ] 34 : 139102 : const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider); 35 [ + + ]: 139102 : if (!block_header) { 36 : 50745 : continue; 37 : : } 38 : 88357 : CBlockIndex& current_block{ 39 [ + - + - : 88357 : *blocks.emplace_back(std::make_unique<CBlockIndex>(*block_header))}; + - + - ] 40 : : { 41 [ + - + - ]: 88357 : CBlockIndex* previous_block = blocks.empty() ? nullptr : PickValue(fuzzed_data_provider, blocks).get(); 42 [ + - - + ]: 88357 : const int current_height = (previous_block != nullptr && previous_block->nHeight != std::numeric_limits<int>::max()) ? previous_block->nHeight + 1 : 0; 43 [ + - + + ]: 88357 : if (fuzzed_data_provider.ConsumeBool()) { 44 : 50080 : current_block.pprev = previous_block; 45 : 50080 : } 46 [ + - + + ]: 88357 : if (fuzzed_data_provider.ConsumeBool()) { 47 : 50010 : current_block.nHeight = current_height; 48 : 50010 : } 49 [ + - + + ]: 88357 : if (fuzzed_data_provider.ConsumeBool()) { 50 : 49935 : const uint32_t seconds = current_height * consensus_params.nPowTargetSpacing; 51 [ + + ]: 49935 : if (!AdditionOverflow(fixed_time, seconds)) { 52 : 48912 : current_block.nTime = fixed_time + seconds; 53 : 48912 : } 54 : 49935 : } 55 [ + - + + ]: 88357 : if (fuzzed_data_provider.ConsumeBool()) { 56 : 49928 : current_block.nBits = fixed_bits; 57 : 49928 : } 58 [ + - + + ]: 88357 : if (fuzzed_data_provider.ConsumeBool()) { 59 [ + - + - : 49697 : current_block.nChainWork = previous_block != nullptr ? previous_block->nChainWork + GetBlockProof(*previous_block) : arith_uint256{0}; + - # # # # + - + - ] 60 : 49697 : } else { 61 [ + - ]: 38660 : current_block.nChainWork = ConsumeArithUInt256(fuzzed_data_provider); 62 : : } 63 : : } 64 : : { 65 [ + - ]: 88357 : (void)GetBlockProof(current_block); 66 [ + - + - ]: 88357 : (void)CalculateNextWorkRequired(¤t_block, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, std::numeric_limits<int64_t>::max()), consensus_params); 67 [ + - + - : 88357 : if (current_block.nHeight != std::numeric_limits<int>::max() && current_block.nHeight - (consensus_params.DifficultyAdjustmentInterval() - 1) >= 0) { - + ] 68 [ # # # # ]: 0 : (void)GetNextWorkRequired(¤t_block, &(*block_header), consensus_params); 69 : 0 : } 70 : : } 71 : : { 72 [ + - ]: 88357 : const auto& to = PickValue(fuzzed_data_provider, blocks); 73 [ + - ]: 88357 : const auto& from = PickValue(fuzzed_data_provider, blocks); 74 [ + - ]: 88530 : const auto& tip = PickValue(fuzzed_data_provider, blocks); 75 : : try { 76 [ + - + - : 88357 : (void)GetBlockProofEquivalentTime(*to, *from, *tip, consensus_params); + - + + ] 77 [ + - ]: 88357 : } catch (const uint_error&) { 78 [ + - ]: 60745 : } 79 : : } 80 : : { 81 : 88357 : const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider); 82 [ + + ]: 88357 : if (hash) { 83 [ + - + - : 42771 : (void)CheckProofOfWork(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params); + - ] 84 : 42771 : } 85 : : } 86 : 88357 : } 87 : 61028 : } 88 : : 89 : : 90 [ + - - + ]: 477 : FUZZ_TARGET(pow_transition, .init = initialize_pow) 91 : : { 92 : 131 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 93 : 131 : const Consensus::Params& consensus_params{Params().GetConsensus()}; 94 : 131 : std::vector<std::unique_ptr<CBlockIndex>> blocks; 95 : : 96 [ + - ]: 131 : const uint32_t old_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; 97 [ + - ]: 131 : const uint32_t new_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; 98 [ + - ]: 131 : const int32_t version{fuzzed_data_provider.ConsumeIntegral<int32_t>()}; 99 [ + - ]: 131 : uint32_t nbits{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; 100 : : 101 [ + - ]: 131 : const arith_uint256 pow_limit = UintToArith256(consensus_params.powLimit); 102 [ + - ]: 131 : arith_uint256 old_target; 103 [ + - ]: 131 : old_target.SetCompact(nbits); 104 [ + - + + ]: 131 : if (old_target > pow_limit) { 105 [ + - ]: 3 : nbits = pow_limit.GetCompact(); 106 : 3 : } 107 : : // Create one difficulty adjustment period worth of headers 108 [ + - + + ]: 264227 : for (int height = 0; height < consensus_params.DifficultyAdjustmentInterval(); ++height) { 109 [ + - ]: 264096 : CBlockHeader header; 110 : 264096 : header.nVersion = version; 111 : 264096 : header.nTime = old_time; 112 : 264096 : header.nBits = nbits; 113 [ + - + + ]: 264096 : if (height == consensus_params.DifficultyAdjustmentInterval() - 1) { 114 : 131 : header.nTime = new_time; 115 : 131 : } 116 [ + - ]: 264096 : auto current_block{std::make_unique<CBlockIndex>(header)}; 117 [ + + ]: 264096 : current_block->pprev = blocks.empty() ? nullptr : blocks.back().get(); 118 : 264096 : current_block->nHeight = height; 119 [ + - ]: 264096 : blocks.emplace_back(std::move(current_block)); 120 : 264096 : } 121 : 131 : auto last_block{blocks.back().get()}; 122 [ + - ]: 131 : unsigned int new_nbits{GetNextWorkRequired(last_block, nullptr, consensus_params)}; 123 [ + - + - ]: 131 : Assert(PermittedDifficultyTransition(consensus_params, last_block->nHeight + 1, last_block->nBits, new_nbits)); 124 : 131 : }