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 110885 : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) 14 : { 15 110885 : assert(pindexLast != nullptr); 16 110885 : unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); 17 : 18 : // Only change once per difficulty adjustment interval 19 110885 : if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) 20 : { 21 110883 : 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 110735 : if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) 27 6679 : return nProofOfWorkLimit; 28 : else 29 : { 30 : // Return the last non-special-min-difficulty-rules-block 31 : const CBlockIndex* pindex = pindexLast; 32 33094306 : while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) 33 32990250 : pindex = pindex->pprev; 34 104056 : return pindex->nBits; 35 : } 36 : } 37 148 : return pindexLast->nBits; 38 : } 39 : 40 : // Go back by what we want to be 14 days worth of blocks 41 2 : int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1); 42 2 : assert(nHeightFirst >= 0); 43 2 : const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); 44 2 : assert(pindexFirst); 45 : 46 2 : return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); 47 110885 : } 48 : 49 6 : unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) 50 : { 51 6 : if (params.fPowNoRetargeting) 52 2 : return pindexLast->nBits; 53 : 54 : // Limit adjustment step 55 4 : int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; 56 4 : if (nActualTimespan < params.nPowTargetTimespan/4) 57 1 : nActualTimespan = params.nPowTargetTimespan/4; 58 4 : if (nActualTimespan > params.nPowTargetTimespan*4) 59 1 : nActualTimespan = params.nPowTargetTimespan*4; 60 : 61 : // Retarget 62 4 : const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); 63 4 : arith_uint256 bnNew; 64 4 : bnNew.SetCompact(pindexLast->nBits); 65 4 : bnNew *= nActualTimespan; 66 4 : bnNew /= params.nPowTargetTimespan; 67 : 68 4 : if (bnNew > bnPowLimit) 69 1 : bnNew = bnPowLimit; 70 : 71 4 : return bnNew.GetCompact(); 72 6 : } 73 : 74 292608 : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) 75 : { 76 292608 : bool fNegative; 77 292608 : bool fOverflow; 78 292608 : arith_uint256 bnTarget; 79 : 80 292608 : bnTarget.SetCompact(nBits, &fNegative, &fOverflow); 81 : 82 : // Check range 83 292608 : if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) 84 4 : return false; 85 : 86 : // Check proof of work matches claimed amount 87 292605 : if (UintToArith256(hash) > bnTarget) 88 21230 : return false; 89 : 90 271375 : return true; 91 292609 : }