1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 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 "chainparams.h"
11 #include "primitives/block.h"
15 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
17 unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
20 if (pindexLast == NULL)
21 return nProofOfWorkLimit;
23 // Only change once per interval
24 if ((pindexLast->nHeight+1) % Params().Interval() != 0)
26 if (Params().AllowMinDifficultyBlocks())
28 // Special difficulty rule for testnet:
29 // If the new block's timestamp is more than 2* 10 minutes
30 // then allow mining of a min-difficulty block.
31 if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
32 return nProofOfWorkLimit;
35 // Return the last non-special-min-difficulty-rules-block
36 const CBlockIndex* pindex = pindexLast;
37 while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
38 pindex = pindex->pprev;
42 return pindexLast->nBits;
45 // Go back by what we want to be 14 days worth of blocks
46 const CBlockIndex* pindexFirst = pindexLast;
47 for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
48 pindexFirst = pindexFirst->pprev;
51 // Limit adjustment step
52 int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
53 LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
54 if (nActualTimespan < Params().TargetTimespan()/4)
55 nActualTimespan = Params().TargetTimespan()/4;
56 if (nActualTimespan > Params().TargetTimespan()*4)
57 nActualTimespan = Params().TargetTimespan()*4;
62 bnNew.SetCompact(pindexLast->nBits);
64 bnNew *= nActualTimespan;
65 bnNew /= Params().TargetTimespan();
67 if (bnNew > Params().ProofOfWorkLimit())
68 bnNew = Params().ProofOfWorkLimit();
71 LogPrintf("GetNextWorkRequired RETARGET\n");
72 LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
73 LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
74 LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
76 return bnNew.GetCompact();
79 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
83 arith_uint256 bnTarget;
85 if (Params().SkipProofOfWorkCheck())
88 bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
91 if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
92 return error("CheckProofOfWork(): nBits below minimum work");
94 // Check proof of work matches claimed amount
95 if (UintToArith256(hash) > bnTarget)
96 return error("CheckProofOfWork(): hash doesn't match nBits");
101 arith_uint256 GetBlockProof(const CBlockIndex& block)
103 arith_uint256 bnTarget;
106 bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
107 if (fNegative || fOverflow || bnTarget == 0)
109 // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
110 // as it's too large for a arith_uint256. However, as 2**256 is at least as large
111 // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
112 // or ~bnTarget / (nTarget+1) + 1.
113 return (~bnTarget / (bnTarget + 1)) + 1;