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 15377 : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) 14 : { 15 15377 : assert(pindexLast != nullptr); 16 15377 : unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); 17 : 18 : // Only change once per difficulty adjustment interval 19 15377 : if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) 20 : { 21 15377 : 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 15377 : if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) 27 14727 : return nProofOfWorkLimit; 28 : else 29 : { 30 : // Return the last non-special-min-difficulty-rules-block 31 650 : const CBlockIndex* pindex = pindexLast; 32 110550 : while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) 33 109900 : pindex = pindex->pprev; 34 650 : 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 15377 : } 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 872 : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) 126 : { 127 : bool fNegative; 128 : bool fOverflow; 129 872 : arith_uint256 bnTarget; 130 : 131 872 : bnTarget.SetCompact(nBits, &fNegative, &fOverflow); 132 : 133 : // Check range 134 872 : if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) 135 0 : return false; 136 : 137 : // Check proof of work matches claimed amount 138 872 : if (UintToArith256(hash) > bnTarget) 139 270 : return false; 140 : 141 602 : return true; 142 872 : }