]> Git Repo - VerusCoin.git/blob - src/pow.cpp
minor: remove unneeded bool in CWalletDB::Recover
[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 "primitives/block.h"
11 #include "uint256.h"
12 #include "util.h"
13
14 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
15 {
16     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
17
18     // Genesis block
19     if (pindexLast == NULL)
20         return nProofOfWorkLimit;
21
22     // Only change once per difficulty adjustment interval
23     if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
24     {
25         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             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                 while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
37                     pindex = pindex->pprev;
38                 return pindex->nBits;
39             }
40         }
41         return pindexLast->nBits;
42     }
43
44     // Go back by what we want to be 14 days worth of blocks
45     int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
46     assert(nHeightFirst >= 0);
47     const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
48     assert(pindexFirst);
49
50     return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
51 }
52
53 unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
54 {
55     // Limit adjustment step
56     int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
57     LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
58     if (nActualTimespan < params.nPowTargetTimespan/4)
59         nActualTimespan = params.nPowTargetTimespan/4;
60     if (nActualTimespan > params.nPowTargetTimespan*4)
61         nActualTimespan = params.nPowTargetTimespan*4;
62
63     // Retarget
64     const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
65     arith_uint256 bnNew;
66     arith_uint256 bnOld;
67     bnNew.SetCompact(pindexLast->nBits);
68     bnOld = bnNew;
69     bnNew *= nActualTimespan;
70     bnNew /= params.nPowTargetTimespan;
71
72     if (bnNew > bnPowLimit)
73         bnNew = bnPowLimit;
74
75     /// debug print
76     LogPrintf("GetNextWorkRequired RETARGET\n");
77     LogPrintf("params.nPowTargetTimespan = %d    nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
78     LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
79     LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());
80
81     return bnNew.GetCompact();
82 }
83
84 bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
85 {
86     bool fNegative;
87     bool fOverflow;
88     arith_uint256 bnTarget;
89
90     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
91
92     // Check range
93     if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
94         return error("CheckProofOfWork(): nBits below minimum work");
95
96     // Check proof of work matches claimed amount
97     if (UintToArith256(hash) > bnTarget)
98         return error("CheckProofOfWork(): hash doesn't match nBits");
99
100     return true;
101 }
102
103 arith_uint256 GetBlockProof(const CBlockIndex& block)
104 {
105     arith_uint256 bnTarget;
106     bool fNegative;
107     bool fOverflow;
108     bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
109     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     return (~bnTarget / (bnTarget + 1)) + 1;
116 }
117
118 int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
119 {
120     arith_uint256 r;
121     int sign = 1;
122     if (to.nChainWork > from.nChainWork) {
123         r = to.nChainWork - from.nChainWork;
124     } else {
125         r = from.nChainWork - to.nChainWork;
126         sign = -1;
127     }
128     r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
129     if (r.bits() > 63) {
130         return sign * std::numeric_limits<int64_t>::max();
131     }
132     return sign * r.GetLow64();
133 }
This page took 0.028989 seconds and 4 git commands to generate.