@@ -30,6 +30,12 @@ import (
30
30
"gopkg.in/fatih/set.v0"
31
31
)
32
32
33
+ var (
34
+ ExpDiffPeriod = big .NewInt (100000 )
35
+ big10 = big .NewInt (10 )
36
+ bigMinus99 = big .NewInt (- 99 )
37
+ )
38
+
33
39
// BlockValidator is responsible for validating block headers, uncles and
34
40
// processed state.
35
41
//
@@ -111,7 +117,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
111
117
// For valid blocks this should always validate to true.
112
118
rbloom := types .CreateBloom (receipts )
113
119
if rbloom != header .Bloom {
114
- return fmt .Errorf ("unable to replicate block's bloom=%x" , rbloom )
120
+ return fmt .Errorf ("unable to replicate block's bloom=%x vs calculated bloom=%x" , header . Bloom , rbloom )
115
121
}
116
122
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
117
123
receiptSha := types .DeriveSha (receipts )
@@ -241,3 +247,127 @@ func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, che
241
247
}
242
248
return nil
243
249
}
250
+
251
+ // CalcDifficulty is the difficulty adjustment algorithm. It returns
252
+ // the difficulty that a new block should have when created at time
253
+ // given the parent block's time and difficulty.
254
+ func CalcDifficulty (time , parentTime uint64 , parentNumber , parentDiff * big.Int ) * big.Int {
255
+ if params .IsHomestead (new (big.Int ).Add (parentNumber , common .Big1 )) {
256
+ return calcDifficultyHomestead (time , parentTime , parentNumber , parentDiff )
257
+ } else {
258
+ return calcDifficultyFrontier (time , parentTime , parentNumber , parentDiff )
259
+ }
260
+ }
261
+
262
+ func calcDifficultyHomestead (time , parentTime uint64 , parentNumber , parentDiff * big.Int ) * big.Int {
263
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
264
+ // algorithm:
265
+ // diff = (parent_diff +
266
+ // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
267
+ // ) + 2^(periodCount - 2)
268
+
269
+ bigTime := new (big.Int ).SetUint64 (time )
270
+ bigParentTime := new (big.Int ).SetUint64 (parentTime )
271
+
272
+ // holds intermediate values to make the algo easier to read & audit
273
+ x := new (big.Int )
274
+ y := new (big.Int )
275
+
276
+ // 1 - (block_timestamp -parent_timestamp) // 10
277
+ x .Sub (bigTime , bigParentTime )
278
+ x .Div (x , big10 )
279
+ x .Sub (common .Big1 , x )
280
+
281
+ // max(1 - (block_timestamp - parent_timestamp) // 10, -99)))
282
+ if x .Cmp (bigMinus99 ) < 0 {
283
+ x .Set (bigMinus99 )
284
+ }
285
+
286
+ // (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
287
+ y .Div (parentDiff , params .DifficultyBoundDivisor )
288
+ x .Mul (y , x )
289
+ x .Add (parentDiff , x )
290
+
291
+ // minimum difficulty can ever be (before exponential factor)
292
+ if x .Cmp (params .MinimumDifficulty ) < 0 {
293
+ x = params .MinimumDifficulty
294
+ }
295
+
296
+ // for the exponential factor
297
+ periodCount := new (big.Int ).Add (parentNumber , common .Big1 )
298
+ periodCount .Div (periodCount , ExpDiffPeriod )
299
+
300
+ // the exponential factor, commonly refered to as "the bomb"
301
+ // diff = diff + 2^(periodCount - 2)
302
+ if periodCount .Cmp (common .Big1 ) > 0 {
303
+ y .Sub (periodCount , common .Big2 )
304
+ y .Exp (common .Big2 , y , nil )
305
+ x .Add (x , y )
306
+ }
307
+
308
+ return x
309
+ }
310
+
311
+ func calcDifficultyFrontier (time , parentTime uint64 , parentNumber , parentDiff * big.Int ) * big.Int {
312
+ diff := new (big.Int )
313
+ adjust := new (big.Int ).Div (parentDiff , params .DifficultyBoundDivisor )
314
+ bigTime := new (big.Int )
315
+ bigParentTime := new (big.Int )
316
+
317
+ bigTime .SetUint64 (time )
318
+ bigParentTime .SetUint64 (parentTime )
319
+
320
+ if bigTime .Sub (bigTime , bigParentTime ).Cmp (params .DurationLimit ) < 0 {
321
+ diff .Add (parentDiff , adjust )
322
+ } else {
323
+ diff .Sub (parentDiff , adjust )
324
+ }
325
+ if diff .Cmp (params .MinimumDifficulty ) < 0 {
326
+ diff = params .MinimumDifficulty
327
+ }
328
+
329
+ periodCount := new (big.Int ).Add (parentNumber , common .Big1 )
330
+ periodCount .Div (periodCount , ExpDiffPeriod )
331
+ if periodCount .Cmp (common .Big1 ) > 0 {
332
+ // diff = diff + 2^(periodCount - 2)
333
+ expDiff := periodCount .Sub (periodCount , common .Big2 )
334
+ expDiff .Exp (common .Big2 , expDiff , nil )
335
+ diff .Add (diff , expDiff )
336
+ diff = common .BigMax (diff , params .MinimumDifficulty )
337
+ }
338
+
339
+ return diff
340
+ }
341
+
342
+ // CalcGasLimit computes the gas limit of the next block after parent.
343
+ // The result may be modified by the caller.
344
+ // This is miner strategy, not consensus protocol.
345
+ func CalcGasLimit (parent * types.Block ) * big.Int {
346
+ // contrib = (parentGasUsed * 3 / 2) / 1024
347
+ contrib := new (big.Int ).Mul (parent .GasUsed (), big .NewInt (3 ))
348
+ contrib = contrib .Div (contrib , big .NewInt (2 ))
349
+ contrib = contrib .Div (contrib , params .GasLimitBoundDivisor )
350
+
351
+ // decay = parentGasLimit / 1024 -1
352
+ decay := new (big.Int ).Div (parent .GasLimit (), params .GasLimitBoundDivisor )
353
+ decay .Sub (decay , big .NewInt (1 ))
354
+
355
+ /*
356
+ strategy: gasLimit of block-to-mine is set based on parent's
357
+ gasUsed value. if parentGasUsed > parentGasLimit * (2/3) then we
358
+ increase it, otherwise lower it (or leave it unchanged if it's right
359
+ at that usage) the amount increased/decreased depends on how far away
360
+ from parentGasLimit * (2/3) parentGasUsed is.
361
+ */
362
+ gl := new (big.Int ).Sub (parent .GasLimit (), decay )
363
+ gl = gl .Add (gl , contrib )
364
+ gl .Set (common .BigMax (gl , params .MinGasLimit ))
365
+
366
+ // however, if we're now below the target (GenesisGasLimit) we increase the
367
+ // limit as much as we can (parentGasLimit / 1024 -1)
368
+ if gl .Cmp (params .GenesisGasLimit ) < 0 {
369
+ gl .Add (parent .GasLimit (), decay )
370
+ gl .Set (common .BigMin (gl , params .GenesisGasLimit ))
371
+ }
372
+ return gl
373
+ }
0 commit comments