Branch data Line data Source code
1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : : // Copyright (c) 2009-2022 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 : 0 : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) 14 : : { 15 [ # # ]: 0 : assert(pindexLast != nullptr); 16 : 0 : unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); 17 : : 18 : : // Only change once per difficulty adjustment interval 19 [ # # ]: 0 : if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) 20 : : { 21 [ # # ]: 0 : if (params.fPowAllowMinDifficultyBlocks) 22 : : { 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 [ # # ]: 0 : if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) 27 : 0 : return nProofOfWorkLimit; 28 : : else 29 : : { 30 : : // Return the last non-special-min-difficulty-rules-block 31 : 0 : const CBlockIndex* pindex = pindexLast; 32 [ # # # # : 0 : while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) # # ] 33 : 0 : pindex = pindex->pprev; 34 : 0 : return pindex->nBits; 35 : : } 36 : : } 37 : 0 : return pindexLast->nBits; 38 : : } 39 : : 40 : : // Go back by what we want to be 14 days worth of blocks 41 : 0 : int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1); 42 [ # # ]: 0 : assert(nHeightFirst >= 0); 43 : 0 : const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); 44 [ # # ]: 0 : assert(pindexFirst); 45 : : 46 : 0 : return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); 47 : 0 : } 48 : : 49 : 0 : unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) 50 : : { 51 [ # # ]: 0 : if (params.fPowNoRetargeting) 52 : 0 : return pindexLast->nBits; 53 : : 54 : : // Limit adjustment step 55 : 0 : int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; 56 [ # # ]: 0 : if (nActualTimespan < params.nPowTargetTimespan/4) 57 : 0 : nActualTimespan = params.nPowTargetTimespan/4; 58 [ # # ]: 0 : if (nActualTimespan > params.nPowTargetTimespan*4) 59 : 0 : nActualTimespan = params.nPowTargetTimespan*4; 60 : : 61 : : // Retarget 62 : 0 : const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); 63 : 0 : arith_uint256 bnNew; 64 : 0 : bnNew.SetCompact(pindexLast->nBits); 65 : 0 : bnNew *= nActualTimespan; 66 : 0 : bnNew /= params.nPowTargetTimespan; 67 : : 68 [ # # ]: 0 : if (bnNew > bnPowLimit) 69 : 0 : bnNew = bnPowLimit; 70 : : 71 : 0 : return bnNew.GetCompact(); 72 : 0 : } 73 : : 74 : 2 : // Check that on difficulty adjustments, the new difficulty does not increase 75 : : // or decrease beyond the permitted limits. 76 : 0 : bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits) 77 : : { 78 [ # # ]: 0 : if (params.fPowAllowMinDifficultyBlocks) return true; 79 : : 80 [ # # ]: 0 : if (height % params.DifficultyAdjustmentInterval() == 0) { 81 : 0 : int64_t smallest_timespan = params.nPowTargetTimespan/4; 82 : 0 : int64_t largest_timespan = params.nPowTargetTimespan*4; 83 : : 84 : 0 : const arith_uint256 pow_limit = UintToArith256(params.powLimit); 85 : 0 : arith_uint256 observed_new_target; 86 : 0 : observed_new_target.SetCompact(new_nbits); 87 : : 88 : : // Calculate the largest difficulty value possible: 89 : 0 : arith_uint256 largest_difficulty_target; 90 : 0 : largest_difficulty_target.SetCompact(old_nbits); 91 : 0 : largest_difficulty_target *= largest_timespan; 92 : 0 : largest_difficulty_target /= params.nPowTargetTimespan; 93 : : 94 [ # # ]: 0 : if (largest_difficulty_target > pow_limit) { 95 : 0 : largest_difficulty_target = pow_limit; 96 : 0 : } 97 : : 98 : : // Round and then compare this new calculated value to what is 99 : : // observed. 100 : 0 : arith_uint256 maximum_new_target; 101 : 0 : maximum_new_target.SetCompact(largest_difficulty_target.GetCompact()); 102 [ # # ]: 0 : if (maximum_new_target < observed_new_target) return false; 103 : : 104 : : // Calculate the smallest difficulty value possible: 105 : 0 : arith_uint256 smallest_difficulty_target; 106 : 0 : smallest_difficulty_target.SetCompact(old_nbits); 107 : 0 : smallest_difficulty_target *= smallest_timespan; 108 : 0 : smallest_difficulty_target /= params.nPowTargetTimespan; 109 : : 110 [ # # ]: 0 : 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 : 0 : arith_uint256 minimum_new_target; 117 : 0 : minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact()); 118 [ # # ]: 0 : if (minimum_new_target > observed_new_target) return false; 119 [ # # ]: 0 : } else if (old_nbits != new_nbits) { 120 : 0 : return false; 121 : : } 122 : 0 : return true; 123 : 0 : } 124 : : 125 : 2 : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) 126 : : { 127 : : bool fNegative; 128 : : bool fOverflow; 129 : 2 : arith_uint256 bnTarget; 130 : : 131 : 2 : bnTarget.SetCompact(nBits, &fNegative, &fOverflow); 132 : : 133 : : // Check range 134 [ + - + - : 2 : if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) - + - + ] 135 : 0 : return false; 136 : : 137 : : // Check proof of work matches claimed amount 138 [ - + ]: 2 : if (UintToArith256(hash) > bnTarget) 139 : 0 : return false; 140 : : 141 : 2 : return true; 142 : 2 : }