consensus/ethash: implement Metropolis EIP 100
This commit is contained in:
		
				
					committed by
					
						 Péter Szilágyi
						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 { | func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { | ||||||
| 	next := new(big.Int).Add(parent.Number, common.Big1) | 	next := new(big.Int).Add(parent.Number, common.Big1) | ||||||
| 	switch { | 	switch { | ||||||
|  | 	case config.IsMetropolis(next): | ||||||
|  | 		return calcDifficultyMetropolis(time, parent) | ||||||
| 	case config.IsHomestead(next): | 	case config.IsHomestead(next): | ||||||
| 		return calcDifficultyHomestead(time, parent) | 		return calcDifficultyHomestead(time, parent) | ||||||
| 	default: | 	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. | // Some weird constants to avoid constant memory allocs for them. | ||||||
| var ( | var ( | ||||||
| 	expDiffPeriod = big.NewInt(100000) | 	expDiffPeriod = big.NewInt(100000) | ||||||
|  | 	big9          = big.NewInt(9) | ||||||
| 	big10         = big.NewInt(10) | 	big10         = big.NewInt(10) | ||||||
| 	bigMinus99    = big.NewInt(-99) | 	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 | // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns | ||||||
| // the difficulty that a new block should have when created at time given the | // 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. | // parent block's time and difficulty. The calculation uses the Homestead rules. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user