]> Git Repo - VerusCoin.git/blob - src/pow.cpp
Merge #5548: [REST] add /rest/chaininfos
[VerusCoin.git] / src / pow.cpp
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 "chainparams.h"
11 #include "primitives/block.h"
12 #include "uint256.h"
13 #include "util.h"
14
15 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
16 {
17     unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
18
19     // Genesis block
20     if (pindexLast == NULL)
21         return nProofOfWorkLimit;
22
23     // Only change once per interval
24     if ((pindexLast->nHeight+1) % Params().Interval() != 0)
25     {
26         if (Params().AllowMinDifficultyBlocks())
27         {
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;
33             else
34             {
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;
39                 return pindex->nBits;
40             }
41         }
42         return pindexLast->nBits;
43     }
44
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;
49     assert(pindexFirst);
50
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;
58
59     // Retarget
60     arith_uint256 bnNew;
61     arith_uint256 bnOld;
62     bnNew.SetCompact(pindexLast->nBits);
63     bnOld = bnNew;
64     bnNew *= nActualTimespan;
65     bnNew /= Params().TargetTimespan();
66
67     if (bnNew > Params().ProofOfWorkLimit())
68         bnNew = Params().ProofOfWorkLimit();
69
70     /// debug print
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());
75
76     return bnNew.GetCompact();
77 }
78
79 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
80 {
81     bool fNegative;
82     bool fOverflow;
83     arith_uint256 bnTarget;
84
85     if (Params().SkipProofOfWorkCheck())
86        return true;
87
88     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
89
90     // Check range
91     if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
92         return error("CheckProofOfWork(): nBits below minimum work");
93
94     // Check proof of work matches claimed amount
95     if (UintToArith256(hash) > bnTarget)
96         return error("CheckProofOfWork(): hash doesn't match nBits");
97
98     return true;
99 }
100
101 arith_uint256 GetBlockProof(const CBlockIndex& block)
102 {
103     arith_uint256 bnTarget;
104     bool fNegative;
105     bool fOverflow;
106     bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
107     if (fNegative || fOverflow || bnTarget == 0)
108         return 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;
114 }
This page took 0.029189 seconds and 4 git commands to generate.