Merge #9578: Add missing mempool lock for CalculateMemPoolAncestors
[bitcoinplatinum.git] / src / pow.cpp
blobe57fd866f8a620d0beb17b8df7412d0717500060
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include "pow.h"
8 #include "arith_uint256.h"
9 #include "chain.h"
10 #include "primitives/block.h"
11 #include "uint256.h"
13 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
15 unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
17 // Genesis block
18 if (pindexLast == NULL)
19 return nProofOfWorkLimit;
21 // Only change once per difficulty adjustment interval
22 if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
24 if (params.fPowAllowMinDifficultyBlocks)
26 // Special difficulty rule for testnet:
27 // If the new block's timestamp is more than 2* 10 minutes
28 // then allow mining of a min-difficulty block.
29 if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
30 return nProofOfWorkLimit;
31 else
33 // Return the last non-special-min-difficulty-rules-block
34 const CBlockIndex* pindex = pindexLast;
35 while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
36 pindex = pindex->pprev;
37 return pindex->nBits;
40 return pindexLast->nBits;
43 // Go back by what we want to be 14 days worth of blocks
44 int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
45 assert(nHeightFirst >= 0);
46 const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
47 assert(pindexFirst);
49 return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
52 unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
54 if (params.fPowNoRetargeting)
55 return pindexLast->nBits;
57 // Limit adjustment step
58 int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
59 if (nActualTimespan < params.nPowTargetTimespan/4)
60 nActualTimespan = params.nPowTargetTimespan/4;
61 if (nActualTimespan > params.nPowTargetTimespan*4)
62 nActualTimespan = params.nPowTargetTimespan*4;
64 // Retarget
65 const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
66 arith_uint256 bnNew;
67 bnNew.SetCompact(pindexLast->nBits);
68 bnNew *= nActualTimespan;
69 bnNew /= params.nPowTargetTimespan;
71 if (bnNew > bnPowLimit)
72 bnNew = bnPowLimit;
74 return bnNew.GetCompact();
77 bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
79 bool fNegative;
80 bool fOverflow;
81 arith_uint256 bnTarget;
83 bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
85 // Check range
86 if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
87 return false;
89 // Check proof of work matches claimed amount
90 if (UintToArith256(hash) > bnTarget)
91 return false;
93 return true;