1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
9 #include "chainparams.h"
10 #include "core/block.h"
14 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
16 unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
19 if (pindexLast == NULL)
20 return nProofOfWorkLimit;
22 // Only change once per interval
23 if ((pindexLast->nHeight+1) % Params().Interval() != 0)
25 if (Params().AllowMinDifficultyBlocks())
27 // Special difficulty rule for testnet:
28 // If the new block's timestamp is more than 2* 10 minutes
29 // then allow mining of a min-difficulty block.
30 if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
31 return nProofOfWorkLimit;
34 // Return the last non-special-min-difficulty-rules-block
35 const CBlockIndex* pindex = pindexLast;
36 while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
37 pindex = pindex->pprev;
41 return pindexLast->nBits;
44 // Go back by what we want to be 14 days worth of blocks
45 const CBlockIndex* pindexFirst = pindexLast;
46 for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
47 pindexFirst = pindexFirst->pprev;
50 // Limit adjustment step
51 int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
52 LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
53 if (nActualTimespan < Params().TargetTimespan()/4)
54 nActualTimespan = Params().TargetTimespan()/4;
55 if (nActualTimespan > Params().TargetTimespan()*4)
56 nActualTimespan = Params().TargetTimespan()*4;
61 bnNew.SetCompact(pindexLast->nBits);
63 bnNew *= nActualTimespan;
64 bnNew /= Params().TargetTimespan();
66 if (bnNew > Params().ProofOfWorkLimit())
67 bnNew = Params().ProofOfWorkLimit();
70 LogPrintf("GetNextWorkRequired RETARGET\n");
71 LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
72 LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
73 LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
75 return bnNew.GetCompact();
78 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
84 if (Params().SkipProofOfWorkCheck())
87 bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
90 if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
91 return error("CheckProofOfWork() : nBits below minimum work");
93 // Check proof of work matches claimed amount
95 return error("CheckProofOfWork() : hash doesn't match nBits");
100 uint256 GetBlockProof(const CBlockIndex& block)
105 bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
106 if (fNegative || fOverflow || bnTarget == 0)
108 // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
109 // as it's too large for a uint256. However, as 2**256 is at least as large
110 // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
111 // or ~bnTarget / (nTarget+1) + 1.
112 return (~bnTarget / (bnTarget + 1)) + 1;