consensus/ethash: implement Metropolis EIP 100
This commit is contained in:
		
				
					committed by
					
						
						Péter Szilágyi
					
				
			
			
				
	
			
			
			
						parent
						
							a0aa071ca6
						
					
				
				
					commit
					c4d28aee9b
				
			@@ -289,6 +289,8 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
 | 
			
		||||
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
 | 
			
		||||
	next := new(big.Int).Add(parent.Number, common.Big1)
 | 
			
		||||
	switch {
 | 
			
		||||
	case config.IsMetropolis(next):
 | 
			
		||||
		return calcDifficultyMetropolis(time, parent)
 | 
			
		||||
	case config.IsHomestead(next):
 | 
			
		||||
		return calcDifficultyHomestead(time, parent)
 | 
			
		||||
	default:
 | 
			
		||||
@@ -299,10 +301,56 @@ func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Heade
 | 
			
		||||
// Some weird constants to avoid constant memory allocs for them.
 | 
			
		||||
var (
 | 
			
		||||
	expDiffPeriod = big.NewInt(100000)
 | 
			
		||||
	big9          = big.NewInt(9)
 | 
			
		||||
	big10         = big.NewInt(10)
 | 
			
		||||
	bigMinus99    = big.NewInt(-99)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func calcDifficultyMetropolis(time uint64, parent *types.Header) *big.Int {
 | 
			
		||||
	bigTime := new(big.Int).SetUint64(time)
 | 
			
		||||
	bigParentTime := new(big.Int).Set(parent.Time)
 | 
			
		||||
 | 
			
		||||
	// adj_factor = max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)
 | 
			
		||||
	var x *big.Int
 | 
			
		||||
	if parent.UncleHash == types.EmptyUncleHash {
 | 
			
		||||
		x = big.NewInt(1)
 | 
			
		||||
	} else {
 | 
			
		||||
		x = big.NewInt(2)
 | 
			
		||||
	}
 | 
			
		||||
	z := new(big.Int).Sub(bigTime, bigParentTime)
 | 
			
		||||
	z.Div(z, big9)
 | 
			
		||||
	x.Sub(x, z)
 | 
			
		||||
 | 
			
		||||
	// max(1 - (block_timestamp - parent_timestamp) // 10, -99)))
 | 
			
		||||
	if x.Cmp(bigMinus99) < 0 {
 | 
			
		||||
		x.Set(bigMinus99)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
 | 
			
		||||
	y := new(big.Int).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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// for the exponential factor
 | 
			
		||||
	periodCount := new(big.Int).Add(parent.Number, common.Big1)
 | 
			
		||||
	periodCount.Div(periodCount, expDiffPeriod)
 | 
			
		||||
 | 
			
		||||
	// the exponential factor, commonly referred to as "the bomb"
 | 
			
		||||
	// diff = diff + 2^(periodCount - 2)
 | 
			
		||||
	if periodCount.Cmp(common.Big1) > 0 {
 | 
			
		||||
		y.Sub(periodCount, common.Big2)
 | 
			
		||||
		y.Exp(common.Big2, y, nil)
 | 
			
		||||
		x.Add(x, y)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// calcDifficultyHomestead 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 Homestead rules.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user