Line data Source code
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.
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 : #include "util.h"
13 :
14 9520 : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
15 : {
16 9520 : unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
17 :
18 : // Genesis block
19 9520 : if (pindexLast == NULL)
20 : return nProofOfWorkLimit;
21 :
22 : // Only change once per difficulty adjustment interval
23 19040 : if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
24 : {
25 9520 : if (params.fPowAllowMinDifficultyBlocks)
26 : {
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 28152 : if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
31 : return nProofOfWorkLimit;
32 : else
33 : {
34 : // Return the last non-special-min-difficulty-rules-block
35 : const CBlockIndex* pindex = pindexLast;
36 797814 : while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
37 : pindex = pindex->pprev;
38 9261 : return pindex->nBits;
39 : }
40 : }
41 136 : return pindexLast->nBits;
42 : }
43 :
44 : // Go back by what we want to be 14 days worth of blocks
45 0 : int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
46 0 : assert(nHeightFirst >= 0);
47 0 : const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
48 0 : assert(pindexFirst);
49 :
50 0 : return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
51 : }
52 :
53 4 : unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
54 : {
55 : // Limit adjustment step
56 8 : int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
57 4 : LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
58 4 : if (nActualTimespan < params.nPowTargetTimespan/4)
59 1 : nActualTimespan = params.nPowTargetTimespan/4;
60 4 : if (nActualTimespan > params.nPowTargetTimespan*4)
61 1 : nActualTimespan = params.nPowTargetTimespan*4;
62 :
63 : // Retarget
64 4 : const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
65 : arith_uint256 bnNew;
66 : arith_uint256 bnOld;
67 4 : bnNew.SetCompact(pindexLast->nBits);
68 : bnOld = bnNew;
69 4 : bnNew *= nActualTimespan;
70 8 : bnNew /= params.nPowTargetTimespan;
71 :
72 4 : if (bnNew > bnPowLimit)
73 : bnNew = bnPowLimit;
74 :
75 : /// debug print
76 4 : LogPrintf("GetNextWorkRequired RETARGET\n");
77 4 : LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
78 8 : LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
79 8 : LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
80 :
81 4 : return bnNew.GetCompact();
82 : }
83 :
84 61453 : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
85 : {
86 : bool fNegative;
87 : bool fOverflow;
88 : arith_uint256 bnTarget;
89 :
90 61453 : bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
91 :
92 : // Check range
93 184359 : if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
94 0 : return error("CheckProofOfWork(): nBits below minimum work");
95 :
96 : // Check proof of work matches claimed amount
97 122906 : if (UintToArith256(hash) > bnTarget)
98 1344 : return error("CheckProofOfWork(): hash doesn't match nBits");
99 :
100 : return true;
101 : }
102 :
103 27758 : arith_uint256 GetBlockProof(const CBlockIndex& block)
104 : {
105 : arith_uint256 bnTarget;
106 : bool fNegative;
107 : bool fOverflow;
108 27758 : bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
109 55516 : if (fNegative || fOverflow || bnTarget == 0)
110 : return 0;
111 : // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
112 : // as it's too large for a arith_uint256. However, as 2**256 is at least as large
113 : // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
114 : // or ~bnTarget / (nTarget+1) + 1.
115 55516 : return (~bnTarget / (bnTarget + 1)) + 1;
116 : }
117 :
118 1000 : int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
119 : {
120 : arith_uint256 r;
121 1000 : int sign = 1;
122 2000 : if (to.nChainWork > from.nChainWork) {
123 976 : r = to.nChainWork - from.nChainWork;
124 : } else {
125 1024 : r = from.nChainWork - to.nChainWork;
126 512 : sign = -1;
127 : }
128 3000 : r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
129 1000 : if (r.bits() > 63) {
130 0 : return sign * std::numeric_limits<int64_t>::max();
131 : }
132 2000 : return sign * r.GetLow64();
133 288 : }
|