adjust verifyHeaders to validate GasLimit as calculated by new CalcGasLimitAndBaseFee function

This commit is contained in:
Ian Norden 2019-12-05 14:20:51 -06:00
parent 633f61e260
commit 7d4bcc3cbf
3 changed files with 33 additions and 14 deletions

View File

@ -265,8 +265,8 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
}
// If we have not reached the EIP1559 activation block we need to verify that the GasLimit field is valid
if !chain.Config().IsEIP1559Finalized(header.Number) {
// If EIP1559 is not active we need to verify that the GasLimit field is valid according to the legacy rules
if !chain.Config().IsEIP1559(header.Number) {
// Verify that the gas limit is <= 2^63-1
cap := uint64(0x7fffffffffffffff)
if header.GasLimit > cap {
@ -287,9 +287,9 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
}
} else if header.GasLimit != 0 {
// If EIP1559 is finalized, GasLimit should be 0
return errGasLimitSet
// If EIP1559 is active, assert that the GasLimit field is valid according to the EIP1559 rules
} else if err := misc.VerifyEIP1559GasLimit(chain.Config(), header); err != nil {
return err
}
// Verify that the block number is parent's +1

View File

@ -27,11 +27,12 @@ import (
)
var (
errInvalidInitialBaseFee = fmt.Errorf("initial BaseFee must equal %d", params.EIP1559InitialBaseFee)
errInvalidBaseFee = errors.New("invalid BaseFee")
errMissingParentBaseFee = errors.New("parent header is missing BaseFee")
errMissingBaseFee = errors.New("current header is missing BaseFee")
errHaveBaseFee = fmt.Errorf("BaseFee should not be set before block %d", params.EIP1559ForkBlockNumber)
errInvalidInitialBaseFee = fmt.Errorf("initial BaseFee must equal %d", params.EIP1559InitialBaseFee)
errInvalidBaseFee = errors.New("invalid BaseFee")
errMissingParentBaseFee = errors.New("parent header is missing BaseFee")
errMissingBaseFee = errors.New("current header is missing BaseFee")
errHaveBaseFee = fmt.Errorf("BaseFee should not be set before block %d", params.EIP1559ForkBlockNumber)
errInvalidEIP1559FinalizedGasLimit = fmt.Errorf("after EIP1559 finalization, GasLimit must equal %d", params.MaxGasEIP1559)
)
// VerifyForkHashes verifies that blocks conforming to network hard-forks do have
@ -89,3 +90,22 @@ func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Head
}
return nil
}
// VerifyEIP1559GasLimit verifies that the header.GasLimit field is valid for the current block height
// Only call this after activation has been confirmed (config.IsEIP1559(header.Number) == true)
func VerifyEIP1559GasLimit(config *params.ChainConfig, header *types.Header) error {
// If EIP1559 has been finalized then header.GasLimit should be equal to the MaxGasEIP1559 (entire limit is in EIP1559 pool)
if config.IsEIP1559Finalized(header.Number) {
if header.GasLimit != params.MaxGasEIP1559 {
return errInvalidEIP1559FinalizedGasLimit
}
return nil
}
// Else if we are between activation and finalization, header.GasLimit must be valid based on the decay function
numOfIncrements := new(big.Int).Sub(header.Number, config.EIP1559Block).Uint64()
expectedGasLimit := (params.MaxGasEIP1559 / 2) + (numOfIncrements * params.EIP1559GasIncrementAmount)
if header.GasLimit != expectedGasLimit {
return fmt.Errorf("invalid GasLimit: have %d, need %d", header.GasLimit, expectedGasLimit)
}
return nil
}

View File

@ -177,7 +177,7 @@ func calcGasLimitAndBaseFee(config *params.ChainConfig, parent *types.Block) (ui
div2 := new(big.Int).Div(div, new(big.Int).SetUint64(params.BaseFeeMaxChangeDenominator))
baseFee := new(big.Int).Add(parent.BaseFee(), div2)
// panic is the BaseFee is not valid
// Panic is the BaseFee is not valid
// A valid BASEFEE is one such that abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
diff := new(big.Int).Sub(baseFee, parent.BaseFee())
if diff.Sign() < 0 {
@ -197,9 +197,8 @@ func calcGasLimitAndBaseFee(config *params.ChainConfig, parent *types.Block) (ui
}
// Otherwise calculate how much of the MaxGasEIP1559 serves as the limit for the EIP1559 pool
// We need to shift (MaxGasEIP1559 / 2) gas from the legacy pool into the eip1559 pool over the EIP1559DecayRange
gasIncrement := (params.MaxGasEIP1559 / 2) / params.EIP1559DecayRange // 10 gas shifted per block
// The GasLimit for the legacy pool is (params.MaxGasEIP1559 - eip1559GasLimit)
numOfIncrements := new(big.Int).Sub(height, config.EIP1559Block).Uint64()
eip1559GasLimit := (params.MaxGasEIP1559 / 2) + (numOfIncrements * gasIncrement)
eip1559GasLimit := (params.MaxGasEIP1559 / 2) + (numOfIncrements * params.EIP1559GasIncrementAmount)
return eip1559GasLimit, baseFee
}