modify verifyHeader() for ethash
This commit is contained in:
@@ -76,6 +76,7 @@ var (
|
||||
errInvalidDifficulty = errors.New("non-positive difficulty")
|
||||
errInvalidMixDigest = errors.New("invalid mix digest")
|
||||
errInvalidPoW = errors.New("invalid proof-of-work")
|
||||
errGasLimitSet = errors.New("GasLimit should not be set after EIP1559 has finalized")
|
||||
)
|
||||
|
||||
// Author implements consensus.Engine, returning the header's coinbase as the
|
||||
@@ -263,26 +264,34 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
|
||||
if expected.Cmp(header.Difficulty) != 0 {
|
||||
return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
|
||||
}
|
||||
// Verify that the gas limit is <= 2^63-1
|
||||
cap := uint64(0x7fffffffffffffff)
|
||||
if header.GasLimit > cap {
|
||||
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
|
||||
}
|
||||
// Verify that the gasUsed is <= gasLimit
|
||||
if header.GasUsed > header.GasLimit {
|
||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
||||
|
||||
// If we have not reached the EIP1559 finalization block we need to verify that the GasLimit field is valid
|
||||
if !chain.Config().IsEIP1559Finalized(header.Number) {
|
||||
// Verify that the gas limit is <= 2^63-1
|
||||
cap := uint64(0x7fffffffffffffff)
|
||||
if header.GasLimit > cap {
|
||||
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
|
||||
}
|
||||
// Verify that the gasUsed is <= gasLimit
|
||||
if header.GasUsed > header.GasLimit {
|
||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
||||
}
|
||||
|
||||
// Verify that the gas limit remains within allowed bounds
|
||||
diff := int64(parent.GasLimit) - int64(header.GasLimit)
|
||||
if diff < 0 {
|
||||
diff *= -1
|
||||
}
|
||||
limit := parent.GasLimit / params.GasLimitBoundDivisor
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Verify that the gas limit remains within allowed bounds
|
||||
diff := int64(parent.GasLimit) - int64(header.GasLimit)
|
||||
if diff < 0 {
|
||||
diff *= -1
|
||||
}
|
||||
limit := parent.GasLimit / params.GasLimitBoundDivisor
|
||||
|
||||
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
|
||||
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
|
||||
}
|
||||
// Verify that the block number is parent's +1
|
||||
if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
|
||||
return consensus.ErrInvalidNumber
|
||||
@@ -294,6 +303,9 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
|
||||
}
|
||||
}
|
||||
// If all checks passed, validate any special fields for hard forks
|
||||
if err := misc.VerifyEIP1559BaseFee(chain.Config(), header, parent); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -17,13 +17,23 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
// VerifyForkHashes verifies that blocks conforming to network hard-forks do have
|
||||
// the correct hashes, to avoid clients going off on different chains. This is an
|
||||
// optional feature.
|
||||
@@ -41,3 +51,41 @@ func VerifyForkHashes(config *params.ChainConfig, header *types.Header, uncle bo
|
||||
// All ok, return
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyEIP1559BaseFee verifies that the EIP1559 BaseFee field is valid for the current block height
|
||||
func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Header) error {
|
||||
// If we are at the EIP1559 fork block the BaseFee needs to be equal to params.EIP1559InitialBaseFee
|
||||
if config.EIP1559Block != nil && config.EIP1559Block.Cmp(header.Number) == 0 {
|
||||
if header.BaseFee == nil || header.BaseFee.Cmp(new(big.Int).SetUint64(params.EIP1559InitialBaseFee)) != 0 {
|
||||
return errInvalidInitialBaseFee
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Verify the BaseFee is valid if we are past the EIP1559 initialization block
|
||||
if config.IsEIP1559(header.Number) {
|
||||
// A valid BASEFEE is one such that abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
|
||||
if parent.BaseFee == nil {
|
||||
return errMissingParentBaseFee
|
||||
}
|
||||
if header.BaseFee == nil {
|
||||
return errMissingBaseFee
|
||||
}
|
||||
diff := new(big.Int).Sub(header.BaseFee, parent.BaseFee)
|
||||
if diff.Sign() < 0 {
|
||||
diff.Neg(diff)
|
||||
}
|
||||
max := new(big.Int).Div(parent.BaseFee, new(big.Int).SetUint64(params.BaseFeeMaxChangeDenominator))
|
||||
if max.Cmp(common.Big1) < 0 {
|
||||
max = common.Big1
|
||||
}
|
||||
if diff.Cmp(max) > 0 {
|
||||
return errInvalidBaseFee
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// If we are before the EIP1559 initialization block the current and parent BaseFees should be nil
|
||||
if header.BaseFee != nil || parent.BaseFee != nil {
|
||||
return errHaveBaseFee
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user