@@ -30,6 +30,12 @@ import (
3030 "gopkg.in/fatih/set.v0"
3131)
3232
33+ var (
34+ ExpDiffPeriod = big .NewInt (100000 )
35+ big10 = big .NewInt (10 )
36+ bigMinus99 = big .NewInt (- 99 )
37+ )
38+
3339// BlockValidator is responsible for validating block headers, uncles and
3440// processed state.
3541//
@@ -111,7 +117,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
111117 // For valid blocks this should always validate to true.
112118 rbloom := types .CreateBloom (receipts )
113119 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 )
115121 }
116122 // Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
117123 receiptSha := types .DeriveSha (receipts )
@@ -241,3 +247,127 @@ func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, che
241247 }
242248 return nil
243249}
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