Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

try using parent.GasLimit in plugin/evm/header #1472

Draft
wants to merge 15 commits into
base: merge-coreth-master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ import (
"os"
"path"

"github.com/ava-labs/subnet-evm/consensus/dummy"
"github.com/ava-labs/subnet-evm/core/state"
"github.com/ava-labs/subnet-evm/core/types"
"github.com/ava-labs/subnet-evm/core/vm"
"github.com/ava-labs/subnet-evm/eth/tracers"
"github.com/ava-labs/subnet-evm/eth/tracers/logger"
"github.com/ava-labs/subnet-evm/params"
customheader "github.com/ava-labs/subnet-evm/plugin/evm/header"
"github.com/ava-labs/subnet-evm/tests"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -90,7 +90,7 @@ type input struct {
}

func Transition(ctx *cli.Context) error {
var getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { return nil, nil }
getTracer := func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { return nil, nil }

baseDir, err := createBasedir(ctx)
if err != nil {
Expand Down Expand Up @@ -222,15 +222,15 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
BaseFee: env.ParentBaseFee,
GasUsed: env.ParentGasUsed,
GasLimit: env.ParentGasLimit,
Extra: make([]byte, params.DynamicFeeExtraDataSize), // TODO: consider passing extra through env
Extra: make([]byte, customheader.FeeWindowSize), // TODO: consider passing extra through env
}
feeConfig := params.DefaultFeeConfig
if env.MinBaseFee != nil {
// Override the default min base fee if it's set in the env
feeConfig.MinBaseFee = env.MinBaseFee
}
var err error
_, env.BaseFee, err = dummy.CalcBaseFee(chainConfig, feeConfig, parent, env.Timestamp)
env.BaseFee, err = customheader.BaseFee(chainConfig, feeConfig, parent, env.Timestamp)
if err != nil {
return NewError(ErrorConfig, fmt.Errorf("failed calculating base fee: %v", err))
}
Expand Down Expand Up @@ -282,7 +282,7 @@ func saveFile(baseDir, filename string, data interface{}) error {
return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
}
location := path.Join(baseDir, filename)
if err = os.WriteFile(location, b, 0644); err != nil {
if err = os.WriteFile(location, b, 0o644); err != nil {
return NewError(ErrorIO, fmt.Errorf("failed writing output: %v", err))
}
log.Info("Wrote file", "file", location)
Expand Down
2 changes: 2 additions & 0 deletions commontype/fee_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ func (f *FeeConfig) Verify() error {
return fmt.Errorf("minBlockGasCost = %d cannot be greater than maxBlockGasCost = %d", f.MinBlockGasCost, f.MaxBlockGasCost)
case f.BlockGasCostStep.Cmp(common.Big0) == -1:
return fmt.Errorf("blockGasCostStep = %d cannot be less than 0", f.BlockGasCostStep)
case !f.MaxBlockGasCost.IsUint64():
return fmt.Errorf("maxBlockGasCost = %d is not a valid uint64", f.MaxBlockGasCost)
}
return f.checkByteLens()
}
Expand Down
149 changes: 62 additions & 87 deletions consensus/dummy/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ava-labs/subnet-evm/core/types"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/trie"
"github.com/ava-labs/subnet-evm/utils"
"github.com/ava-labs/subnet-evm/vmerrs"
"github.com/ethereum/go-ethereum/common"

Expand All @@ -26,11 +27,8 @@ import (
var (
allowedFutureBlockTime = 10 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks

errInvalidBlockTime = errors.New("timestamp less than parent's")
errUnclesUnsupported = errors.New("uncles unsupported")
errBlockGasCostNil = errors.New("block gas cost is nil")
errBlockGasCostTooLarge = errors.New("block gas cost is not uint64")
errBaseFeeNil = errors.New("base fee is nil")
errInvalidBlockTime = errors.New("timestamp less than parent's")
errUnclesUnsupported = errors.New("uncles unsupported")
)

type Mode struct {
Expand Down Expand Up @@ -117,14 +115,6 @@ func (eng *DummyEngine) verifyCoinbase(config *params.ChainConfig, header *types
}

func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header, chain consensus.ChainHeaderReader) error {
// Verify that the gas limit is <= 2^63-1
if header.GasLimit > params.MaxGasLimit {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit)
}
// Verify that the gasUsed is <= gasLimit
if header.GasUsed > header.GasLimit {
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
}
// We verify the current block by checking the parent fee config
// this is because the current block cannot set the fee config for itself
// Fee config might depend on the state when precompile is activated
Expand All @@ -134,67 +124,45 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
if err != nil {
return err
}
if config.IsSubnetEVM(header.Time) {
expectedGasLimit := feeConfig.GasLimit.Uint64()
if header.GasLimit != expectedGasLimit {
return fmt.Errorf("expected gas limit to be %d, but found %d", expectedGasLimit, header.GasLimit)
}
} else {
// 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 BaseFee is not present before Subnet EVM
if header.BaseFee != nil {
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
}
if header.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", header.BlockGasCost)
}
return nil
// 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 baseFee and rollupWindow encoding as part of header verification
// starting in Subnet EVM
expectedRollupWindowBytes, expectedBaseFee, err := CalcBaseFee(config, feeConfig, parent, header.Time)
if err != nil {
return fmt.Errorf("failed to calculate base fee: %w", err)
if err := customheader.VerifyGasLimit(config, feeConfig, parent, header); err != nil {
return err
}
if len(header.Extra) < len(expectedRollupWindowBytes) || !bytes.Equal(expectedRollupWindowBytes, header.Extra[:len(expectedRollupWindowBytes)]) {
return fmt.Errorf("expected rollup window bytes: %x, found %x", expectedRollupWindowBytes, header.Extra)
// Verify header.Extra matches the expected value.
expectedExtraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time)
if err != nil {
return fmt.Errorf("failed to calculate extra prefix: %w", err)
}
if header.BaseFee == nil {
return errors.New("expected baseFee to be non-nil")
if !bytes.HasPrefix(header.Extra, expectedExtraPrefix) {
return fmt.Errorf("expected header.Extra to have prefix: %x, found %x", expectedExtraPrefix, header.Extra)
}
if bfLen := header.BaseFee.BitLen(); bfLen > 256 {
return fmt.Errorf("too large base fee: bitlen %d", bfLen)

// Verify header.BaseFee matches the expected value.
expectedBaseFee, err := customheader.BaseFee(config, feeConfig, parent, header.Time)
if err != nil {
return fmt.Errorf("failed to calculate base fee: %w", err)
}
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
if !utils.BigEqual(header.BaseFee, expectedBaseFee) {
return fmt.Errorf("expected base fee (%d), found (%d)", expectedBaseFee, header.BaseFee)
}

if !config.IsSubnetEVM(header.Time) {
if header.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", header.BlockGasCost)
}
return nil
}

// Enforce BlockGasCost constraints
expectedBlockGasCost := calcBlockGasCost(
feeConfig.TargetBlockRate,
feeConfig.MinBlockGasCost,
feeConfig.MaxBlockGasCost,
feeConfig.BlockGasCostStep,
parent.BlockGasCost,
parent.Time, header.Time,
expectedBlockGasCost := customheader.BlockGasCost(
feeConfig,
parent,
header.Time,
)
if header.BlockGasCost == nil {
return errBlockGasCostNil
}
if !header.BlockGasCost.IsUint64() {
return errBlockGasCostTooLarge
}
if header.BlockGasCost.Cmp(expectedBlockGasCost) != 0 {
if !utils.BigEqualUint64(header.BlockGasCost, expectedBlockGasCost) {
return fmt.Errorf("invalid block gas cost: have %d, want %d", header.BlockGasCost, expectedBlockGasCost)
}
return nil
Expand Down Expand Up @@ -358,32 +326,31 @@ func (eng *DummyEngine) verifyBlockFee(
}

func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types.Block, parent *types.Header, state *state.StateDB, receipts []*types.Receipt) error {
if chain.Config().IsSubnetEVM(block.Time()) {
config := chain.Config()
timestamp := block.Time()
if config.IsSubnetEVM(block.Time()) {
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return err
}

// Calculate the expected blockGasCost for this block.
// Note: this is a deterministic transtion that defines an exact block fee for this block.
blockGasCost := calcBlockGasCost(
feeConfig.TargetBlockRate,
feeConfig.MinBlockGasCost,
feeConfig.MaxBlockGasCost,
feeConfig.BlockGasCostStep,
parent.BlockGasCost,
parent.Time, block.Time(),
// Verify the BlockGasCost set in the header matches the expected value.
blockGasCost := block.BlockGasCost()
expectedBlockGasCost := customheader.BlockGasCost(
feeConfig,
parent,
timestamp,
)
// Verify the BlockGasCost set in the header matches the calculated value.
if blockBlockGasCost := block.BlockGasCost(); blockBlockGasCost == nil || !blockBlockGasCost.IsUint64() || blockBlockGasCost.Cmp(blockGasCost) != 0 {
return fmt.Errorf("invalid blockGasCost: have %d, want %d", blockBlockGasCost, blockGasCost)
if !utils.BigEqualUint64(blockGasCost, expectedBlockGasCost) {
return fmt.Errorf("invalid blockGasCost: have %d, want %d", blockGasCost, expectedBlockGasCost)
}

// Verify the block fee was paid.
if err := eng.verifyBlockFee(
block.BaseFee(),
block.BlockGasCost(),
blockGasCost,
block.Transactions(),
receipts,
); err != nil {
Expand All @@ -397,22 +364,22 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types
func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, parent *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt,
) (*types.Block, error) {
if chain.Config().IsSubnetEVM(header.Time) {
config := chain.Config()
if config.IsSubnetEVM(header.Time) {
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return nil, err
}
// Calculate the required block gas cost for this block.
header.BlockGasCost = calcBlockGasCost(
feeConfig.TargetBlockRate,
feeConfig.MinBlockGasCost,
feeConfig.MaxBlockGasCost,
feeConfig.BlockGasCostStep,
parent.BlockGasCost,
parent.Time, header.Time,
blockGasCost := customheader.BlockGasCost(
feeConfig,
parent,
header.Time,
)
header.BlockGasCost = new(big.Int).SetUint64(blockGasCost)

// Verify that this block covers the block fee.
if err := eng.verifyBlockFee(
header.BaseFee,
Expand All @@ -423,8 +390,16 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h
return nil, err
}
}

// finalize the header.Extra
extraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time)
if err != nil {
return nil, fmt.Errorf("failed to calculate new header.Extra: %w", err)
}
header.Extra = append(extraPrefix, header.Extra...)

// commit the final state root
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.Root = state.IntermediateRoot(config.IsEIP158(header.Number))

// Header seems complete, assemble into a block and return
return types.NewBlock(
Expand Down
Loading
Loading