LCOV - code coverage report
Current view: top level - src/test/fuzz - pow.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 82 84 97.6 %
Date: 2023-10-05 15:40:34 Functions: 8 8 100.0 %
Branches: 90 158 57.0 %

           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(&current_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(&current_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 : }

Generated by: LCOV version 1.14