]>
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 | ||
6a0c7cea SB |
8 | #include "librustzcash.h" |
9 | ||
734f85c4 | 10 | #include "arith_uint256.h" |
22c4272b | 11 | #include "chain.h" |
fdda3c50 JG |
12 | #include "chainparams.h" |
13 | #include "crypto/equihash.h" | |
d2270111 | 14 | #include "primitives/block.h" |
fdda3c50 | 15 | #include "streams.h" |
df852d2b | 16 | #include "uint256.h" |
ad49c256 | 17 | #include "util.h" |
df852d2b | 18 | |
fdda3c50 JG |
19 | #include "sodium.h" |
20 | ||
d698ef69 | 21 | unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) |
df852d2b | 22 | { |
fd311996 | 23 | unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); |
df852d2b | 24 | |
25 | // Genesis block | |
26 | if (pindexLast == NULL) | |
27 | return nProofOfWorkLimit; | |
28 | ||
f2c48e15 JG |
29 | // Find the first block in the averaging interval |
30 | const CBlockIndex* pindexFirst = pindexLast; | |
7b173bd8 | 31 | arith_uint256 bnTot {0}; |
f2c48e15 | 32 | for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) { |
7b173bd8 JG |
33 | arith_uint256 bnTmp; |
34 | bnTmp.SetCompact(pindexFirst->nBits); | |
35 | bnTot += bnTmp; | |
f2c48e15 JG |
36 | pindexFirst = pindexFirst->pprev; |
37 | } | |
38 | ||
39 | // Check we have enough blocks | |
40 | if (pindexFirst == NULL) | |
41 | return nProofOfWorkLimit; | |
df852d2b | 42 | |
7b173bd8 JG |
43 | arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; |
44 | ||
29842505 | 45 | return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); |
34e5015c RN |
46 | } |
47 | ||
29842505 JG |
48 | unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, |
49 | int64_t nLastBlockTime, int64_t nFirstBlockTime, | |
50 | const Consensus::Params& params) | |
34e5015c | 51 | { |
df852d2b | 52 | // Limit adjustment step |
f2c48e15 | 53 | // Use medians to prevent time-warp attacks |
e99731b4 | 54 | int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime; |
f2c48e15 JG |
55 | LogPrint("pow", " nActualTimespan = %d before dampening\n", nActualTimespan); |
56 | nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4; | |
57 | LogPrint("pow", " nActualTimespan = %d before bounds\n", nActualTimespan); | |
58 | ||
59 | if (nActualTimespan < params.MinActualTimespan()) | |
60 | nActualTimespan = params.MinActualTimespan(); | |
61 | if (nActualTimespan > params.MaxActualTimespan()) | |
62 | nActualTimespan = params.MaxActualTimespan(); | |
df852d2b | 63 | |
64 | // Retarget | |
fd311996 | 65 | const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); |
29842505 | 66 | arith_uint256 bnNew {bnAvg}; |
f2c48e15 | 67 | bnNew /= params.AveragingWindowTimespan(); |
aa86873a | 68 | bnNew *= nActualTimespan; |
df852d2b | 69 | |
fd311996 CF |
70 | if (bnNew > bnPowLimit) |
71 | bnNew = bnPowLimit; | |
df852d2b | 72 | |
73 | /// debug print | |
f2c48e15 JG |
74 | LogPrint("pow", "GetNextWorkRequired RETARGET\n"); |
75 | LogPrint("pow", "params.AveragingWindowTimespan() = %d nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan); | |
29842505 | 76 | LogPrint("pow", "Current average: %08x %s\n", bnAvg.GetCompact(), bnAvg.ToString()); |
f2c48e15 | 77 | LogPrint("pow", "After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); |
df852d2b | 78 | |
79 | return bnNew.GetCompact(); | |
80 | } | |
81 | ||
fdda3c50 JG |
82 | bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params) |
83 | { | |
e9574728 JG |
84 | unsigned int n = params.EquihashN(); |
85 | unsigned int k = params.EquihashK(); | |
fdda3c50 JG |
86 | |
87 | // Hash state | |
88 | crypto_generichash_blake2b_state state; | |
e9574728 | 89 | EhInitialiseState(n, k, state); |
fdda3c50 JG |
90 | |
91 | // I = the block header minus nonce and solution. | |
92 | CEquihashInput I{*pblock}; | |
93 | // I||V | |
94 | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | |
95 | ss << I; | |
96 | ss << pblock->nNonce; | |
97 | ||
98 | // H(I||V||... | |
99 | crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size()); | |
100 | ||
6a0c7cea SB |
101 | // Ensure that our Rust interactions are working in production builds. This is |
102 | // temporary and should be removed. | |
103 | { | |
104 | assert(librustzcash_xor(0x0f0f0f0f0f0f0f0f, 0x1111111111111111) == 0x1e1e1e1e1e1e1e1e); | |
105 | } | |
106 | ||
e9574728 JG |
107 | bool isValid; |
108 | EhIsValidSolution(n, k, state, pblock->nSolution, isValid); | |
109 | if (!isValid) | |
fdda3c50 JG |
110 | return error("CheckEquihashSolution(): invalid solution"); |
111 | ||
112 | return true; | |
113 | } | |
114 | ||
d698ef69 | 115 | bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) |
df852d2b | 116 | { |
117 | bool fNegative; | |
118 | bool fOverflow; | |
734f85c4 | 119 | arith_uint256 bnTarget; |
f0fd00cb | 120 | |
df852d2b | 121 | bnTarget.SetCompact(nBits, &fNegative, &fOverflow); |
122 | ||
123 | // Check range | |
fd311996 | 124 | if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) |
5262fde0 | 125 | return error("CheckProofOfWork(): nBits below minimum work"); |
df852d2b | 126 | |
127 | // Check proof of work matches claimed amount | |
734f85c4 | 128 | if (UintToArith256(hash) > bnTarget) |
5262fde0 | 129 | return error("CheckProofOfWork(): hash doesn't match nBits"); |
df852d2b | 130 | |
131 | return true; | |
132 | } | |
133 | ||
734f85c4 | 134 | arith_uint256 GetBlockProof(const CBlockIndex& block) |
b343c1a1 | 135 | { |
734f85c4 | 136 | arith_uint256 bnTarget; |
b343c1a1 | 137 | bool fNegative; |
138 | bool fOverflow; | |
092b58d1 | 139 | bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); |
b343c1a1 | 140 | if (fNegative || fOverflow || bnTarget == 0) |
141 | return 0; | |
142 | // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 | |
734f85c4 | 143 | // as it's too large for a arith_uint256. However, as 2**256 is at least as large |
b343c1a1 | 144 | // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, |
145 | // or ~bnTarget / (nTarget+1) + 1. | |
146 | return (~bnTarget / (bnTarget + 1)) + 1; | |
df852d2b | 147 | } |
f7303f97 PW |
148 | |
149 | int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) | |
150 | { | |
151 | arith_uint256 r; | |
152 | int sign = 1; | |
153 | if (to.nChainWork > from.nChainWork) { | |
154 | r = to.nChainWork - from.nChainWork; | |
155 | } else { | |
156 | r = from.nChainWork - to.nChainWork; | |
157 | sign = -1; | |
158 | } | |
159 | r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); | |
160 | if (r.bits() > 63) { | |
161 | return sign * std::numeric_limits<int64_t>::max(); | |
162 | } | |
163 | return sign * r.GetLow64(); | |
164 | } |