1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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.
8 #include "arith_uint256.h"
10 #include "primitives/block.h"
13 unsigned int GetNextWorkRequired(const CBlockIndex
* pindexLast
, const CBlockHeader
*pblock
, const Consensus::Params
& params
)
15 unsigned int nProofOfWorkLimit
= UintToArith256(params
.powLimit
).GetCompact();
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
;
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
;
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
);
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;
65 const arith_uint256 bnPowLimit
= UintToArith256(params
.powLimit
);
67 bnNew
.SetCompact(pindexLast
->nBits
);
68 bnNew
*= nActualTimespan
;
69 bnNew
/= params
.nPowTargetTimespan
;
71 if (bnNew
> bnPowLimit
)
74 return bnNew
.GetCompact();
77 bool CheckProofOfWork(uint256 hash
, unsigned int nBits
, const Consensus::Params
& params
)
81 arith_uint256 bnTarget
;
83 bnTarget
.SetCompact(nBits
, &fNegative
, &fOverflow
);
86 if (fNegative
|| bnTarget
== 0 || fOverflow
|| bnTarget
> UintToArith256(params
.powLimit
))
89 // Check proof of work matches claimed amount
90 if (UintToArith256(hash
) > bnTarget
)