modify verifyHeader() for ethash

This commit is contained in:
Ian Norden
2020-07-03 13:32:55 -05:00
parent a4d673974b
commit 31668e7e14
2 changed files with 78 additions and 18 deletions
+30 -18
View File
@@ -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
}
+48
View File
@@ -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
}