]> Git Repo - VerusCoin.git/blame - src/pow.cpp
test
[VerusCoin.git] / src / pow.cpp
CommitLineData
df852d2b 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
78253fcb 3// Distributed under the MIT software license, see the accompanying
df852d2b 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "pow.h"
7
734f85c4 8#include "arith_uint256.h"
22c4272b 9#include "chain.h"
fdda3c50
JG
10#include "chainparams.h"
11#include "crypto/equihash.h"
d2270111 12#include "primitives/block.h"
fdda3c50 13#include "streams.h"
df852d2b 14#include "uint256.h"
ad49c256 15#include "util.h"
df852d2b 16
fdda3c50
JG
17#include "sodium.h"
18
d698ef69 19unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
df852d2b 20{
fd311996 21 unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
df852d2b 22
23 // Genesis block
e583c8f8 24 if (pindexLast == NULL )
df852d2b 25 return nProofOfWorkLimit;
26
f2c48e15
JG
27 // Find the first block in the averaging interval
28 const CBlockIndex* pindexFirst = pindexLast;
7b173bd8 29 arith_uint256 bnTot {0};
f2c48e15 30 for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
7b173bd8
JG
31 arith_uint256 bnTmp;
32 bnTmp.SetCompact(pindexFirst->nBits);
33 bnTot += bnTmp;
f2c48e15
JG
34 pindexFirst = pindexFirst->pprev;
35 }
36
37 // Check we have enough blocks
38 if (pindexFirst == NULL)
39 return nProofOfWorkLimit;
df852d2b 40
7b173bd8
JG
41 arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
42
29842505 43 return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
34e5015c
RN
44}
45
29842505
JG
46unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
47 int64_t nLastBlockTime, int64_t nFirstBlockTime,
48 const Consensus::Params& params)
34e5015c 49{
df852d2b 50 // Limit adjustment step
f2c48e15 51 // Use medians to prevent time-warp attacks
e99731b4 52 int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime;
f2c48e15
JG
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();
df852d2b 61
62 // Retarget
fd311996 63 const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
29842505 64 arith_uint256 bnNew {bnAvg};
f2c48e15 65 bnNew /= params.AveragingWindowTimespan();
aa86873a 66 bnNew *= nActualTimespan;
df852d2b 67
fd311996
CF
68 if (bnNew > bnPowLimit)
69 bnNew = bnPowLimit;
df852d2b 70
71 /// debug print
f2c48e15
JG
72 LogPrint("pow", "GetNextWorkRequired RETARGET\n");
73 LogPrint("pow", "params.AveragingWindowTimespan() = %d nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan);
29842505 74 LogPrint("pow", "Current average: %08x %s\n", bnAvg.GetCompact(), bnAvg.ToString());
f2c48e15 75 LogPrint("pow", "After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
df852d2b 76
77 return bnNew.GetCompact();
78}
79
fdda3c50
JG
80bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
81{
e9574728
JG
82 unsigned int n = params.EquihashN();
83 unsigned int k = params.EquihashK();
fdda3c50
JG
84
85 // Hash state
86 crypto_generichash_blake2b_state state;
e9574728 87 EhInitialiseState(n, k, state);
fdda3c50
JG
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
e9574728
JG
99 bool isValid;
100 EhIsValidSolution(n, k, state, pblock->nSolution, isValid);
101 if (!isValid)
fdda3c50
JG
102 return error("CheckEquihashSolution(): invalid solution");
103
104 return true;
105}
106
a5f315c7 107int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33);
4a4e912b 108int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33]);
c75c18fc 109int32_t komodo_currentheight();
110extern int32_t KOMODO_CHOSEN_ONE;
6c96293f 111#define KOMODO_ELECTION_GAP 2000
9997caa0 112
f2dd868d 113bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash, unsigned int nBits, const Consensus::Params& params)
df852d2b 114{
60b85bee 115 extern int32_t KOMODO_REWIND;
206c579d 116 bool fNegative,fOverflow; int32_t i,nonz=0,special=0,special2=0,notaryid=-1,flag = 0;
734f85c4 117 arith_uint256 bnTarget;
f0fd00cb 118
df852d2b 119 bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
0d2cefb0 120 if ( height == 0 )
c75c18fc 121 height = komodo_currentheight() + 1;
70ce79b0 122 if ( height > 34000 ) // 0 -> non-special notary
9997caa0 123 {
a5f315c7 124 special = komodo_chosennotary(&notaryid,height,pubkey33);
9997caa0 125 for (i=0; i<33; i++)
681589a5 126 {
127 if ( pubkey33[i] != 0 )
128 nonz++;
681589a5 129 }
681589a5 130 if ( nonz == 0 )
f9e18307 131 return(true); // will come back via different path with pubkey set
c0225afd 132 special2 = komodo_is_special(height,pubkey33);
8c0ffb40 133 /*if ( notaryid >= 0 && ((height >= 64000 && height <= 90065) || (height % KOMODO_ELECTION_GAP) > 64) )
f5927d73 134 {
0a7c6500 135 if ( (height >= 64000 && height <= 90065) || (height % KOMODO_ELECTION_GAP) == 0 || (height < 80000 && (special != 0 || special2 > 0)) || (height >= 80000 && special2 > 0) )
4a4e912b 136 {
137 bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
138 flag = 1;
139 }
8c0ffb40 140 }*/
141 if ( notaryid >= 0 )
142 {
143 if ( height < 80000 && (special != 0 || special2 > 0) )
144 flag = 1;
145 else if ( height >= 80000 && height < 108000 && special2 > 0 )
146 flag = 1;
147 else if ( height >= 108000 && special2 > 0 )
148 flag = ((height % KOMODO_ELECTION_GAP) > 64 || (height % KOMODO_ELECTION_GAP) == 0);
149 if ( flag != 0 )
150 bnTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
fb9fcbf8 151 }
9997caa0 152 }
fd311996 153 if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
5262fde0 154 return error("CheckProofOfWork(): nBits below minimum work");
df852d2b 155 // Check proof of work matches claimed amount
4a4e912b 156 if ( UintToArith256(hash) > bnTarget )
9ebb63d7 157 {
ff67b241 158 {
159 int32_t i;
160 for (i=31; i>=0; i--)
161 printf("%02x",((uint8_t *)&hash)[i]);
162 printf(" hash vs ");
163 for (i=31; i>=0; i--)
164 printf("%02x",((uint8_t *)&bnTarget)[i]);
165 printf(" ht.%d REWIND.%d special.%d notaryid.%d ht.%d mod.%d error\n",height,KOMODO_REWIND,special,notaryid,height,(height % 35));
8c0ffb40 166 if ( height < 90000 || height > 110000 )
167 return error("CheckProofOfWork(): hash doesn't match nBits");
ff67b241 168 }
9ebb63d7 169 }
df852d2b 170 return true;
171}
172
734f85c4 173arith_uint256 GetBlockProof(const CBlockIndex& block)
b343c1a1 174{
734f85c4 175 arith_uint256 bnTarget;
b343c1a1 176 bool fNegative;
177 bool fOverflow;
092b58d1 178 bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
b343c1a1 179 if (fNegative || fOverflow || bnTarget == 0)
180 return 0;
181 // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
734f85c4 182 // as it's too large for a arith_uint256. However, as 2**256 is at least as large
b343c1a1 183 // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
184 // or ~bnTarget / (nTarget+1) + 1.
185 return (~bnTarget / (bnTarget + 1)) + 1;
df852d2b 186}
f7303f97
PW
187
188int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
189{
190 arith_uint256 r;
191 int sign = 1;
192 if (to.nChainWork > from.nChainWork) {
193 r = to.nChainWork - from.nChainWork;
194 } else {
195 r = from.nChainWork - to.nChainWork;
196 sign = -1;
197 }
198 r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
199 if (r.bits() > 63) {
200 return sign * std::numeric_limits<int64_t>::max();
201 }
202 return sign * r.GetLow64();
203}
This page took 0.19112 seconds and 4 git commands to generate.