LCOV - code coverage report
Current view: top level - src/test/fuzz - pow.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 2 85 2.4 %
Date: 2023-11-06 23:13:05 Functions: 2 7 28.6 %
Branches: 2 140 1.4 %

           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                 :          0 : void initialize_pow()
      22                 :            : {
      23                 :          0 :     SelectParams(ChainType::MAIN);
      24                 :          0 : }
      25                 :            : 
      26         [ +  - ]:          4 : FUZZ_TARGET(pow, .init = initialize_pow)
      27                 :            : {
      28                 :          0 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      29                 :          0 :     const Consensus::Params& consensus_params = Params().GetConsensus();
      30                 :          0 :     std::vector<std::unique_ptr<CBlockIndex>> blocks;
      31         [ #  # ]:          0 :     const uint32_t fixed_time = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
      32         [ #  # ]:          0 :     const uint32_t fixed_bits = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
      33 [ #  # ][ #  # ]:          0 :     LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 10000) {
                 [ #  # ]
      34                 :          0 :         const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
      35         [ #  # ]:          0 :         if (!block_header) {
      36                 :          0 :             continue;
      37                 :            :         }
      38                 :          0 :         CBlockIndex& current_block{
      39 [ #  # ][ #  # ]:          0 :             *blocks.emplace_back(std::make_unique<CBlockIndex>(*block_header))};
      40                 :            :         {
      41 [ #  # ][ #  # ]:          0 :             CBlockIndex* previous_block = blocks.empty() ? nullptr : PickValue(fuzzed_data_provider, blocks).get();
      42 [ #  # ][ #  # ]:          0 :             const int current_height = (previous_block != nullptr && previous_block->nHeight != std::numeric_limits<int>::max()) ? previous_block->nHeight + 1 : 0;
      43 [ #  # ][ #  # ]:          0 :             if (fuzzed_data_provider.ConsumeBool()) {
      44                 :          0 :                 current_block.pprev = previous_block;
      45                 :          0 :             }
      46 [ #  # ][ #  # ]:          0 :             if (fuzzed_data_provider.ConsumeBool()) {
      47                 :          0 :                 current_block.nHeight = current_height;
      48                 :          0 :             }
      49 [ #  # ][ #  # ]:          0 :             if (fuzzed_data_provider.ConsumeBool()) {
      50                 :          0 :                 const uint32_t seconds = current_height * consensus_params.nPowTargetSpacing;
      51         [ #  # ]:          0 :                 if (!AdditionOverflow(fixed_time, seconds)) {
      52                 :          0 :                     current_block.nTime = fixed_time + seconds;
      53                 :          0 :                 }
      54                 :          0 :             }
      55 [ #  # ][ #  # ]:          0 :             if (fuzzed_data_provider.ConsumeBool()) {
      56                 :          0 :                 current_block.nBits = fixed_bits;
      57                 :          0 :             }
      58 [ #  # ][ #  # ]:          0 :             if (fuzzed_data_provider.ConsumeBool()) {
      59 [ #  # ][ #  # ]:          0 :                 current_block.nChainWork = previous_block != nullptr ? previous_block->nChainWork + GetBlockProof(*previous_block) : arith_uint256{0};
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      60                 :          0 :             } else {
      61         [ #  # ]:          0 :                 current_block.nChainWork = ConsumeArithUInt256(fuzzed_data_provider);
      62                 :            :             }
      63                 :            :         }
      64                 :            :         {
      65         [ #  # ]:          0 :             (void)GetBlockProof(current_block);
      66 [ #  # ][ #  # ]:          0 :             (void)CalculateNextWorkRequired(&current_block, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, std::numeric_limits<int64_t>::max()), consensus_params);
      67 [ #  # ][ #  # ]:          0 :             if (current_block.nHeight != std::numeric_limits<int>::max() && current_block.nHeight - (consensus_params.DifficultyAdjustmentInterval() - 1) >= 0) {
                 [ #  # ]
      68         [ #  # ]:          0 :                 (void)GetNextWorkRequired(&current_block, &(*block_header), consensus_params);
      69                 :          0 :             }
      70                 :            :         }
      71                 :            :         {
      72         [ #  # ]:          0 :             const auto& to = PickValue(fuzzed_data_provider, blocks);
      73         [ #  # ]:          0 :             const auto& from = PickValue(fuzzed_data_provider, blocks);
      74         [ #  # ]:          0 :             const auto& tip = PickValue(fuzzed_data_provider, blocks);
      75                 :            :             try {
      76         [ #  # ]:          0 :                 (void)GetBlockProofEquivalentTime(*to, *from, *tip, consensus_params);
      77         [ #  # ]:          0 :             } catch (const uint_error&) {
      78         [ #  # ]:          0 :             }
      79                 :            :         }
      80                 :            :         {
      81                 :          0 :             const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider);
      82         [ #  # ]:          0 :             if (hash) {
      83 [ #  # ][ #  # ]:          0 :                 (void)CheckProofOfWork(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params);
      84                 :          0 :             }
      85                 :            :         }
      86                 :          0 :     }
      87                 :          0 : }
      88                 :            : 
      89                 :            : 
      90         [ +  - ]:          4 : FUZZ_TARGET(pow_transition, .init = initialize_pow)
      91                 :            : {
      92                 :          0 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      93                 :          0 :     const Consensus::Params& consensus_params{Params().GetConsensus()};
      94                 :          0 :     std::vector<std::unique_ptr<CBlockIndex>> blocks;
      95                 :            : 
      96         [ #  # ]:          0 :     const uint32_t old_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
      97         [ #  # ]:          0 :     const uint32_t new_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
      98         [ #  # ]:          0 :     const int32_t version{fuzzed_data_provider.ConsumeIntegral<int32_t>()};
      99         [ #  # ]:          0 :     uint32_t nbits{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
     100                 :            : 
     101         [ #  # ]:          0 :     const arith_uint256 pow_limit = UintToArith256(consensus_params.powLimit);
     102         [ #  # ]:          0 :     arith_uint256 old_target;
     103         [ #  # ]:          0 :     old_target.SetCompact(nbits);
     104 [ #  # ][ #  # ]:          0 :     if (old_target > pow_limit) {
     105         [ #  # ]:          0 :         nbits = pow_limit.GetCompact();
     106                 :          0 :     }
     107                 :            :     // Create one difficulty adjustment period worth of headers
     108 [ #  # ][ #  # ]:          0 :     for (int height = 0; height < consensus_params.DifficultyAdjustmentInterval(); ++height) {
     109         [ #  # ]:          0 :         CBlockHeader header;
     110                 :          0 :         header.nVersion = version;
     111                 :          0 :         header.nTime = old_time;
     112                 :          0 :         header.nBits = nbits;
     113 [ #  # ][ #  # ]:          0 :         if (height == consensus_params.DifficultyAdjustmentInterval() - 1) {
     114                 :          0 :             header.nTime = new_time;
     115                 :          0 :         }
     116         [ #  # ]:          0 :         auto current_block{std::make_unique<CBlockIndex>(header)};
     117         [ #  # ]:          0 :         current_block->pprev = blocks.empty() ? nullptr : blocks.back().get();
     118                 :          0 :         current_block->nHeight = height;
     119         [ #  # ]:          0 :         blocks.emplace_back(std::move(current_block));
     120                 :          0 :     }
     121                 :          0 :     auto last_block{blocks.back().get()};
     122         [ #  # ]:          0 :     unsigned int new_nbits{GetNextWorkRequired(last_block, nullptr, consensus_params)};
     123 [ #  # ][ #  # ]:          0 :     Assert(PermittedDifficultyTransition(consensus_params, last_block->nHeight + 1, last_block->nBits, new_nbits));
     124                 :          0 : }

Generated by: LCOV version 1.14