@@ -119,72 +119,110 @@ unsigned int DigishieldCalculateNextWorkRequired(const CBlockIndex* pindexLast,
119
119
120
120
unsigned int LwmaGetNextWorkRequired (const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params, bool fLegacy )
121
121
{
122
- int64_t nPowTargetSpacing = params.nPowTargetSpacing ;
123
- int64_t nLwmaAveragingWindow = params.nLwmaAveragingWindow ;
124
-
125
- if (fLegacy ) {
126
- nPowTargetSpacing = params.nLegacyPowTargetSpacing ;
127
- nLwmaAveragingWindow = params.nLegacyLwmaAveragingWindow ;
128
- }
129
-
130
122
// Special difficulty rule for testnet:
131
123
// If the new block's timestamp is more than 2 * 10 minutes
132
124
// then allow mining of a min-difficulty block.
133
125
if (params.fPowAllowMinDifficultyBlocks &&
134
- pblock->GetBlockTime () > pindexLast->GetBlockTime () + nPowTargetSpacing * 2 ) {
126
+ pblock->GetBlockTime () > pindexLast->GetBlockTime () + params. nPowTargetSpacing * 2 ) {
135
127
return UintToArith256 (params.powLimit ).GetCompact ();
136
128
}
137
- return LwmaCalculateNextWorkRequired (pindexLast, params, nPowTargetSpacing, nLwmaAveragingWindow );
129
+ return LwmaCalculateNextWorkRequired (pindexLast, params, fLegacy );
138
130
}
139
131
140
- unsigned int LwmaCalculateNextWorkRequired (const CBlockIndex* pindexLast, const Consensus::Params& params, const int64_t T, const int64_t N )
132
+ unsigned int LwmaCalculateNextWorkRequired (const CBlockIndex* pindexLast, const Consensus::Params& params, bool fLegacy )
141
133
{
142
- // Define a k that will be used to get a proper average after weighting the solvetimes.
143
- const int64_t k = N * (N + 1 ) * T / 2 ;
144
-
145
- const int64_t height = pindexLast->nHeight ;
146
134
const arith_uint256 powLimit = UintToArith256 (params.powLimit );
135
+ arith_uint256 nextTarget;
136
+ arith_uint256 avgTarget;
147
137
148
- // New coins just "give away" first N blocks. It's better to guess
149
- // this value instead of using powLimit, but err on high side to not get stuck.
150
- if (height < N) { return powLimit.GetCompact (); }
138
+ if (fLegacy ) {
139
+ // Define a k that will be used to get a proper average after weighting the solvetimes.
140
+ const int64_t T = params.nLegacyPowTargetSpacing ;
141
+ const int64_t N = params.nLegacyLwmaAveragingWindow ;
142
+ const int64_t k = N * (N + 1 ) * T / 2 ;
151
143
152
- arith_uint256 avgTarget, nextTarget;
153
- int64_t thisTimestamp, previousTimestamp;
154
- int64_t sumWeightedSolvetimes = 0 , j = 0 ;
144
+ const int64_t height = pindexLast->nHeight ;
155
145
156
- const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor (height - N);
157
- previousTimestamp = blockPreviousTimestamp->GetBlockTime ();
146
+ // New coins just "give away" first N blocks. It's better to guess
147
+ // this value instead of using powLimit, but err on high side to not get stuck.
148
+ if (height < N) { return powLimit.GetCompact (); }
158
149
159
- // Loop through N most recent blocks.
160
- for (int64_t i = height - N + 1 ; i <= height; i++) {
161
- const CBlockIndex* block = pindexLast->GetAncestor (i);
150
+ int64_t thisTimestamp, previousTimestamp;
151
+ int64_t sumWeightedSolvetimes = 0 , j = 0 ;
162
152
163
- // Prevent solvetimes from being negative in a safe way. It must be done like this.
164
- // Do not attempt anything like if (solvetime < 1) {solvetime=1;}
165
- // The +1 ensures new coins do not calculate nextTarget = 0.
166
- thisTimestamp = (block->GetBlockTime () > previousTimestamp) ? block->GetBlockTime () : previousTimestamp + 1 ;
153
+ const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor (height - N);
154
+ previousTimestamp = blockPreviousTimestamp->GetBlockTime ();
167
155
168
- // 6*T limit prevents large drops in diff from long solvetimes which would cause oscillations.
169
- int64_t solvetime = std::min (6 * T, thisTimestamp - previousTimestamp);
156
+ // Loop through N most recent blocks.
157
+ for (int64_t i = height - N + 1 ; i <= height; i++) {
158
+ const CBlockIndex* block = pindexLast->GetAncestor (i);
170
159
171
- // The following is part of "preventing negative solvetimes".
172
- previousTimestamp = thisTimestamp;
160
+ // Prevent solvetimes from being negative in a safe way. It must be done like this.
161
+ // Do not attempt anything like if (solvetime < 1) {solvetime=1;}
162
+ // The +1 ensures new coins do not calculate nextTarget = 0.
163
+ thisTimestamp = (block->GetBlockTime () > previousTimestamp) ? block->GetBlockTime () : previousTimestamp + 1 ;
173
164
174
- // Give linearly higher weight to more recent solvetimes.
175
- j++;
176
- sumWeightedSolvetimes += solvetime * j;
165
+ // 6*T limit prevents large drops in diff from long solvetimes which would cause oscillations.
166
+ int64_t solvetime = std::min (6 * T, thisTimestamp - previousTimestamp);
177
167
178
- arith_uint256 target;
179
- target.SetCompact (block->nBits );
180
- avgTarget += target / N / k; // Dividing by k here prevents an overflow below.
181
- }
168
+ // The following is part of "preventing negative solvetimes".
169
+ previousTimestamp = thisTimestamp;
182
170
183
- // Desired equation in next line was nextTarget = avgTarget * sumWeightSolvetimes / k
184
- // but 1/k was moved to line above to prevent overflow in new coins
185
- nextTarget = avgTarget * sumWeightedSolvetimes;
171
+ // Give linearly higher weight to more recent solvetimes.
172
+ j++;
173
+ sumWeightedSolvetimes += solvetime * j;
174
+
175
+ arith_uint256 target;
176
+ target.SetCompact (block->nBits );
177
+ avgTarget += target / N / k; // Dividing by k here prevents an overflow below.
178
+ }
186
179
187
- if (nextTarget > powLimit) { nextTarget = powLimit; }
180
+ // Desired equation in next line was nextTarget = avgTarget * sumWeightSolvetimes / k
181
+ // but 1/k was moved to line above to prevent overflow in new coins
182
+ nextTarget = avgTarget * sumWeightedSolvetimes;
183
+ } else {
184
+ const int height = pindexLast->nHeight + 1 ;
185
+ const int64_t T = params.nPowTargetSpacing ;
186
+ const int N = params.nLwmaAveragingWindow ;
187
+ const int k = params.nLwmaAdjustedWeight ;
188
+ const int dnorm = params.nLwmaMinDenominator ;
189
+ const bool limit_st = params.fLwmaSolvetimeLimitation ;
190
+ assert (height > N);
191
+
192
+ int t = 0 , j = 0 ;
193
+
194
+ // Loop through N most recent blocks.
195
+ for (int i = height - N; i < height; i++) {
196
+ const CBlockIndex* block = pindexLast->GetAncestor (i);
197
+ const CBlockIndex* block_Prev = block->GetAncestor (i - 1 );
198
+ int64_t solvetime = block->GetBlockTime () - block_Prev->GetBlockTime ();
199
+
200
+ if (limit_st && solvetime > 6 * T) {
201
+ solvetime = 6 * T;
202
+ }
203
+
204
+ j++;
205
+ t += solvetime * j; // Weighted solvetime sum.
206
+
207
+ // Target sum divided by a factor, (k N^2).
208
+ // The factor is a part of the final equation. However we divide avgTarget here to avoid
209
+ // potential overflow.
210
+ arith_uint256 target;
211
+ target.SetCompact (block->nBits );
212
+ avgTarget += target / (k * N * N);
213
+ }
214
+
215
+ // Keep t reasonable in case strange solvetimes occurred.
216
+ if (t < N * k / dnorm) {
217
+ t = N * k / dnorm;
218
+ }
219
+
220
+ nextTarget = avgTarget * t;
221
+ }
222
+
223
+ if (nextTarget > powLimit) {
224
+ nextTarget = powLimit;
225
+ }
188
226
189
227
return nextTarget.GetCompact ();
190
228
}
0 commit comments