From 94809905ea97122148623a071fb2d2b52baa731e Mon Sep 17 00:00:00 2001 From: Akira Takizawa Date: Sat, 1 Sep 2018 23:38:15 +0900 Subject: [PATCH] Defuse difficulty bomb before block 3M + New difficulty calculation will be activated on CLOHF1 --- consensus/ethash/consensus.go | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 1a064abfa3..40598bdcc1 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -306,6 +306,8 @@ func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, p func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { next := new(big.Int).Add(parent.Number, big1) switch { + case config.IsCLOHF1(next): + return calcDifficultyCLOHF1(time, parent) case config.IsBombDisposal(next): return calcDifficultyBombDisposal(time, parent) case config.IsByzantium(next): @@ -330,6 +332,47 @@ var ( big2999999 = big.NewInt(2999999) ) +// calcDifficultyCLOHF1 is the difficulty adjustment algorithm. It returns +// the difficulty that a new block should have when created at time given the +// parent block's time and difficulty. The calculation uses the CLOHF1 rules. +func calcDifficultyCLOHF1(time uint64, parent *types.Header) *big.Int { + // https://github.com/ethereum/EIPs/issues/100. + // algorithm: + // diff = (parent_diff + + // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) + // ) + + bigTime := new(big.Int).SetUint64(time) + bigParentTime := new(big.Int).Set(parent.Time) + + // holds intermediate values to make the algo easier to read & audit + x := new(big.Int) + y := new(big.Int) + + // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 + x.Sub(bigTime, bigParentTime) + x.Div(x, big9) + if parent.UncleHash == types.EmptyUncleHash { + x.Sub(big1, x) + } else { + x.Sub(big2, x) + } + // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) + if x.Cmp(bigMinus99) < 0 { + x.Set(bigMinus99) + } + // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) + y.Div(parent.Difficulty, params.DifficultyBoundDivisor) + x.Mul(y, x) + x.Add(parent.Difficulty, x) + + // minimum difficulty can ever be (before exponential factor) + if x.Cmp(params.MinimumDifficulty) < 0 { + x.Set(params.MinimumDifficulty) + } + return x +} + // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns // the difficulty that a new block should have when created at time given the // parent block's time and difficulty. The calculation uses the Byzantium rules.