LCOV - code coverage report
Current view: top level - src - pow.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 79 86 91.9 %
Date: 2022-08-30 15:50:09 Functions: 4 4 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 40 46 87.0 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2018 The Bitcoin Core developers
#       3                 :            : // Distributed under the MIT software license, see the accompanying
#       4                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       5                 :            : 
#       6                 :            : #include <pow.h>
#       7                 :            : 
#       8                 :            : #include <arith_uint256.h>
#       9                 :            : #include <chain.h>
#      10                 :            : #include <primitives/block.h>
#      11                 :            : #include <uint256.h>
#      12                 :            : 
#      13                 :            : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
#      14                 :     202091 : {
#      15                 :     202091 :     assert(pindexLast != nullptr);
#      16                 :          0 :     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
#      17                 :            : 
#      18                 :            :     // Only change once per difficulty adjustment interval
#      19         [ +  + ]:     202091 :     if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
#      20                 :     202059 :     {
#      21         [ +  + ]:     202059 :         if (params.fPowAllowMinDifficultyBlocks)
#      22                 :     201741 :         {
#      23                 :            :             // Special difficulty rule for testnet:
#      24                 :            :             // If the new block's timestamp is more than 2* 10 minutes
#      25                 :            :             // then allow mining of a min-difficulty block.
#      26         [ +  + ]:     201741 :             if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
#      27                 :       4031 :                 return nProofOfWorkLimit;
#      28                 :     197710 :             else
#      29                 :     197710 :             {
#      30                 :            :                 // Return the last non-special-min-difficulty-rules-block
#      31                 :     197710 :                 const CBlockIndex* pindex = pindexLast;
#      32 [ +  + ][ +  + ]:   94655131 :                 while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
#                 [ +  - ]
#      33                 :   94457421 :                     pindex = pindex->pprev;
#      34                 :     197710 :                 return pindex->nBits;
#      35                 :     197710 :             }
#      36                 :     201741 :         }
#      37                 :        318 :         return pindexLast->nBits;
#      38                 :     202059 :     }
#      39                 :            : 
#      40                 :            :     // Go back by what we want to be 14 days worth of blocks
#      41                 :         32 :     int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
#      42                 :         32 :     assert(nHeightFirst >= 0);
#      43                 :          0 :     const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
#      44                 :         32 :     assert(pindexFirst);
#      45                 :            : 
#      46                 :          0 :     return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
#      47                 :     202091 : }
#      48                 :            : 
#      49                 :            : unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
#      50                 :         40 : {
#      51         [ +  + ]:         40 :     if (params.fPowNoRetargeting)
#      52                 :         32 :         return pindexLast->nBits;
#      53                 :            : 
#      54                 :            :     // Limit adjustment step
#      55                 :          8 :     int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
#      56         [ +  + ]:          8 :     if (nActualTimespan < params.nPowTargetTimespan/4)
#      57                 :          2 :         nActualTimespan = params.nPowTargetTimespan/4;
#      58         [ +  + ]:          8 :     if (nActualTimespan > params.nPowTargetTimespan*4)
#      59                 :          2 :         nActualTimespan = params.nPowTargetTimespan*4;
#      60                 :            : 
#      61                 :            :     // Retarget
#      62                 :          8 :     const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
#      63                 :          8 :     arith_uint256 bnNew;
#      64                 :          8 :     bnNew.SetCompact(pindexLast->nBits);
#      65                 :          8 :     bnNew *= nActualTimespan;
#      66                 :          8 :     bnNew /= params.nPowTargetTimespan;
#      67                 :            : 
#      68         [ +  + ]:          8 :     if (bnNew > bnPowLimit)
#      69                 :          2 :         bnNew = bnPowLimit;
#      70                 :            : 
#      71                 :          8 :     return bnNew.GetCompact();
#      72                 :         40 : }
#      73                 :            : 
#      74                 :            : // Check that on difficulty adjustments, the new difficulty does not increase
#      75                 :            : // or decrease beyond the permitted limits.
#      76                 :            : bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits)
#      77                 :     153055 : {
#      78         [ +  + ]:     153055 :     if (params.fPowAllowMinDifficultyBlocks) return true;
#      79                 :            : 
#      80         [ +  - ]:         12 :     if (height % params.DifficultyAdjustmentInterval() == 0) {
#      81                 :         12 :         int64_t smallest_timespan = params.nPowTargetTimespan/4;
#      82                 :         12 :         int64_t largest_timespan = params.nPowTargetTimespan*4;
#      83                 :            : 
#      84                 :         12 :         const arith_uint256 pow_limit = UintToArith256(params.powLimit);
#      85                 :         12 :         arith_uint256 observed_new_target;
#      86                 :         12 :         observed_new_target.SetCompact(new_nbits);
#      87                 :            : 
#      88                 :            :         // Calculate the largest difficulty value possible:
#      89                 :         12 :         arith_uint256 largest_difficulty_target;
#      90                 :         12 :         largest_difficulty_target.SetCompact(old_nbits);
#      91                 :         12 :         largest_difficulty_target *= largest_timespan;
#      92                 :         12 :         largest_difficulty_target /= params.nPowTargetTimespan;
#      93                 :            : 
#      94         [ +  + ]:         12 :         if (largest_difficulty_target > pow_limit) {
#      95                 :          4 :             largest_difficulty_target = pow_limit;
#      96                 :          4 :         }
#      97                 :            : 
#      98                 :            :         // Round and then compare this new calculated value to what is
#      99                 :            :         // observed.
#     100                 :         12 :         arith_uint256 maximum_new_target;
#     101                 :         12 :         maximum_new_target.SetCompact(largest_difficulty_target.GetCompact());
#     102         [ +  + ]:         12 :         if (maximum_new_target < observed_new_target) return false;
#     103                 :            : 
#     104                 :            :         // Calculate the smallest difficulty value possible:
#     105                 :         10 :         arith_uint256 smallest_difficulty_target;
#     106                 :         10 :         smallest_difficulty_target.SetCompact(old_nbits);
#     107                 :         10 :         smallest_difficulty_target *= smallest_timespan;
#     108                 :         10 :         smallest_difficulty_target /= params.nPowTargetTimespan;
#     109                 :            : 
#     110         [ -  + ]:         10 :         if (smallest_difficulty_target > pow_limit) {
#     111                 :          0 :             smallest_difficulty_target = pow_limit;
#     112                 :          0 :         }
#     113                 :            : 
#     114                 :            :         // Round and then compare this new calculated value to what is
#     115                 :            :         // observed.
#     116                 :         10 :         arith_uint256 minimum_new_target;
#     117                 :         10 :         minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());
#     118         [ +  + ]:         10 :         if (minimum_new_target > observed_new_target) return false;
#     119         [ #  # ]:         10 :     } else if (old_nbits != new_nbits) {
#     120                 :          0 :         return false;
#     121                 :          0 :     }
#     122                 :          8 :     return true;
#     123                 :         12 : }
#     124                 :            : 
#     125                 :            : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
#     126                 :    2129499 : {
#     127                 :    2129499 :     bool fNegative;
#     128                 :    2129499 :     bool fOverflow;
#     129                 :    2129499 :     arith_uint256 bnTarget;
#     130                 :            : 
#     131                 :    2129499 :     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
#     132                 :            : 
#     133                 :            :     // Check range
#     134 [ +  + ][ +  + ]:    2129499 :     if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
#         [ +  + ][ -  + ]
#                 [ +  + ]
#     135                 :          8 :         return false;
#     136                 :            : 
#     137                 :            :     // Check proof of work matches claimed amount
#     138         [ +  + ]:    2129491 :     if (UintToArith256(hash) > bnTarget)
#     139                 :    1095664 :         return false;
#     140                 :            : 
#     141                 :    1033827 :     return true;
#     142                 :    2129491 : }

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a