]> Git Repo - VerusCoin.git/blob - src/pow.cpp
test
[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 "crypto/equihash.h"
12 #include "primitives/block.h"
13 #include "streams.h"
14 #include "uint256.h"
15 #include "util.h"
16
17 #include "sodium.h"
18
19 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
20 {
21     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
22
23     // Genesis block
24     if (pindexLast == NULL )
25         return nProofOfWorkLimit;
26
27     // Find the first block in the averaging interval
28     const CBlockIndex* pindexFirst = pindexLast;
29     arith_uint256 bnTot {0};
30     for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
31         arith_uint256 bnTmp;
32         bnTmp.SetCompact(pindexFirst->nBits);
33         bnTot += bnTmp;
34         pindexFirst = pindexFirst->pprev;
35     }
36
37     // Check we have enough blocks
38     if (pindexFirst == NULL)
39         return nProofOfWorkLimit;
40
41     arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
42
43     return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
44 }
45
46 unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
47                                        int64_t nLastBlockTime, int64_t nFirstBlockTime,
48                                        const Consensus::Params& params)
49 {
50     // Limit adjustment step
51     // Use medians to prevent time-warp attacks
52     int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime;
53     LogPrint("pow", "  nActualTimespan = %d  before dampening\n", nActualTimespan);
54     nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4;
55     LogPrint("pow", "  nActualTimespan = %d  before bounds\n", nActualTimespan);
56
57     if (nActualTimespan < params.MinActualTimespan())
58         nActualTimespan = params.MinActualTimespan();
59     if (nActualTimespan > params.MaxActualTimespan())
60         nActualTimespan = params.MaxActualTimespan();
61
62     // Retarget
63     const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
64     arith_uint256 bnNew {bnAvg};
65     bnNew /= params.AveragingWindowTimespan();
66     bnNew *= nActualTimespan;
67
68     if (bnNew > bnPowLimit)
69         bnNew = bnPowLimit;
70
71     /// debug print
72     LogPrint("pow", "GetNextWorkRequired RETARGET\n");
73     LogPrint("pow", "params.AveragingWindowTimespan() = %d    nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan);
74     LogPrint("pow", "Current average: %08x  %s\n", bnAvg.GetCompact(), bnAvg.ToString());
75     LogPrint("pow", "After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());
76
77     return bnNew.GetCompact();
78 }
79
80 bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
81 {
82     unsigned int n = params.EquihashN();
83     unsigned int k = params.EquihashK();
84
85     // Hash state
86     crypto_generichash_blake2b_state state;
87     EhInitialiseState(n, k, state);
88
89     // I = the block header minus nonce and solution.
90     CEquihashInput I{*pblock};
91     // I||V
92     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
93     ss << I;
94     ss << pblock->nNonce;
95
96     // H(I||V||...
97     crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
98
99     bool isValid;
100     EhIsValidSolution(n, k, state, pblock->nSolution, isValid);
101     if (!isValid)
102         return error("CheckEquihashSolution(): invalid solution");
103
104     return true;
105 }
106
107 int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33);
108
109 bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash, unsigned int nBits, const Consensus::Params& params)
110 {
111     bool fNegative,fOverflow; int32_t i,nonz=0,special,notaryid,flag = 0;
112     arith_uint256 bnTarget;
113
114     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
115     if ( height > 34000 ) // 0 -> non-special notary
116     {
117         special = komodo_chosennotary(&notaryid,height,pubkey33);
118         for (i=0; i<33; i++)
119         {
120             if ( pubkey33[i] != 0 )
121                 nonz++;
122             //fprintf(stderr,"%02x",pubkey33[i]);
123         }
124         //fprintf(stderr," height.%d special.%d nonz.%d\n",height,special,nonz);
125         if ( nonz == 0 )
126             return(true); // will come back via different path with pubkey set
127         if ( special > 0 ) // special notary id == (height % numnotaries)
128         {
129             if (UintToArith256(hash) <= bnTarget) // accept normal diff
130                 return true;
131             bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
132             flag = 1;
133         } //else bnTarget /= 8;
134     }
135     // Check range
136     if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
137         return error("CheckProofOfWork(): nBits below minimum work");
138     // Check proof of work matches claimed amount
139     if (UintToArith256(hash) > bnTarget)
140     {
141         return error("CheckProofOfWork(): hash doesn't match nBits");
142     }
143     if ( flag != 0 )
144     {
145         for (i=0; i<33; i++)
146             fprintf(stderr,"%02x",pubkey33[i]);
147         fprintf(stderr," <- Round Robin ht.%d for notary.%d special.%d\n",height,notaryid,special);
148     }
149     return true;
150 }
151
152 arith_uint256 GetBlockProof(const CBlockIndex& block)
153 {
154     arith_uint256 bnTarget;
155     bool fNegative;
156     bool fOverflow;
157     bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
158     if (fNegative || fOverflow || bnTarget == 0)
159         return 0;
160     // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
161     // as it's too large for a arith_uint256. However, as 2**256 is at least as large
162     // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
163     // or ~bnTarget / (nTarget+1) + 1.
164     return (~bnTarget / (bnTarget + 1)) + 1;
165 }
166
167 int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
168 {
169     arith_uint256 r;
170     int sign = 1;
171     if (to.nChainWork > from.nChainWork) {
172         r = to.nChainWork - from.nChainWork;
173     } else {
174         r = from.nChainWork - to.nChainWork;
175         sign = -1;
176     }
177     r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
178     if (r.bits() > 63) {
179         return sign * std::numeric_limits<int64_t>::max();
180     }
181     return sign * r.GetLow64();
182 }
This page took 0.035883 seconds and 4 git commands to generate.