]>
Commit | Line | Data |
---|---|---|
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 | 19 | unsigned 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 |
46 | unsigned 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 |
80 | bool 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 | 107 | int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33); |
4a4e912b | 108 | int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33]); |
c75c18fc | 109 | int32_t komodo_currentheight(); |
110 | extern int32_t KOMODO_CHOSEN_ONE; | |
6c96293f | 111 | #define KOMODO_ELECTION_GAP 2000 |
9997caa0 | 112 | |
f2dd868d | 113 | bool 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(¬aryid,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 | 173 | arith_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 | |
188 | int64_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 | } |