Skip to content

Commit

Permalink
Merge branch 'master' into libevm
Browse files Browse the repository at this point in the history
Up to commit 3d2037f
  • Loading branch information
qdm12 committed Feb 24, 2025
2 parents 95f9444 + 3d2037f commit 20c5470
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 89 deletions.
49 changes: 19 additions & 30 deletions consensus/dummy/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ import (
"math/big"
"time"

"github.com/ava-labs/avalanchego/utils/math"
"github.com/ava-labs/avalanchego/utils/timer/mockable"
"github.com/ava-labs/coreth/consensus"
"github.com/ava-labs/coreth/consensus/misc/eip4844"
"github.com/ava-labs/coreth/core/state"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/utils"
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/trie"

customheader "github.com/ava-labs/coreth/plugin/evm/header"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
)

var (
Expand Down Expand Up @@ -113,35 +111,17 @@ func NewFullFaker() *DummyEngine {
}
}

func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header) error {
configExtra := params.GetExtra(config)
// 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)
}
func (eng *DummyEngine) verifyHeaderGasFields(config *extras.ChainConfig, header *types.Header, parent *types.Header) error {
// 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 configExtra.IsCortina(header.Time) {
if header.GasLimit != cortina.GasLimit {
return fmt.Errorf("expected gas limit to be %d in Cortina, but found %d", cortina.GasLimit, header.GasLimit)
}
} else if configExtra.IsApricotPhase1(header.Time) {
if header.GasLimit != ap1.GasLimit {
return fmt.Errorf("expected gas limit to be %d in ApricotPhase1, but found %d", ap1.GasLimit, header.GasLimit)
}
} else {
// Verify that the gas limit remains within allowed bounds
diff := math.AbsDiff(parent.GasLimit, header.GasLimit)
limit := parent.GasLimit / params.GasLimitBoundDivisor
if diff >= limit || header.GasLimit < params.MinGasLimit {
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
}
if err := customheader.VerifyGasLimit(config, parent, header); err != nil {
return err
}

// Verify header.Extra matches the expected value.
expectedExtraPrefix, err := customheader.ExtraPrefix(configExtra, parent, header.Time)
expectedExtraPrefix, err := customheader.ExtraPrefix(config, parent, header.Time)
if err != nil {
return fmt.Errorf("failed to calculate extra prefix: %w", err)
}
Expand All @@ -150,7 +130,7 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
}

// Verify header.BaseFee matches the expected value.
expectedBaseFee, err := customheader.BaseFee(configExtra, parent, header.Time)
expectedBaseFee, err := customheader.BaseFee(config, parent, header.Time)
if err != nil {
return fmt.Errorf("failed to calculate base fee: %w", err)
}
Expand All @@ -159,7 +139,7 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header
}

// Verify BlockGasCost, ExtDataGasUsed not present before AP4
if !configExtra.IsApricotPhase4(header.Time) {
if !config.IsApricotPhase4(header.Time) {
if header.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", header.BlockGasCost)
}
Expand All @@ -171,7 +151,7 @@ func (eng *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, header

// Enforce BlockGasCost constraints
expectedBlockGasCost := customheader.BlockGasCost(
configExtra,
config,
parent,
header.Time,
)
Expand Down Expand Up @@ -199,13 +179,14 @@ func (eng *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header *

// Verify the extra data is well-formed.
config := chain.Config()
rules := params.GetExtra(config).GetAvalancheRules(header.Time)
configExtra := params.GetExtra(config)
rules := configExtra.GetAvalancheRules(header.Time)
if err := customheader.VerifyExtra(rules, header.Extra); err != nil {
return err
}

// Ensure gas-related header fields are correct
if err := eng.verifyHeaderGasFields(config, header, parent); err != nil {
if err := eng.verifyHeaderGasFields(configExtra, header, parent); err != nil {
return err
}

Expand Down Expand Up @@ -446,6 +427,14 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h
return nil, err
}
}

// finalize the header.Extra
extraPrefix, err := customheader.ExtraPrefix(configExtra, 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))

Expand Down
19 changes: 2 additions & 17 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ import (
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/plugin/evm/header"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/core/vm"
"github.com/ava-labs/libevm/ethdb"
Expand Down Expand Up @@ -373,22 +371,10 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
}

func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.StateDB, engine consensus.Engine) *types.Header {
time := parent.Time() + gap // block time is fixed at [gap] seconds

var gasLimit uint64
configExtra := params.GetExtra(cm.config)
if configExtra.IsCortina(time) {
gasLimit = cortina.GasLimit
} else if configExtra.IsApricotPhase1(time) {
gasLimit = ap1.GasLimit
} else {
gasLimit = CalcGasLimit(parent.GasUsed(), parent.GasLimit(), parent.GasLimit(), parent.GasLimit())
}
time := parent.Time() + gap // block time is fixed at [gap] seconds

extra, err := header.ExtraPrefix(configExtra, parent.Header(), time)
if err != nil {
panic(err)
}
gasLimit := header.GasLimit(configExtra, parent.Header(), time)
baseFee, err := header.BaseFee(configExtra, parent.Header(), time)
if err != nil {
panic(err)
Expand All @@ -402,7 +388,6 @@ func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.S
GasLimit: gasLimit,
Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time,
Extra: extra,
BaseFee: baseFee,
}

Expand Down
7 changes: 3 additions & 4 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import (
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/plugin/evm/header"
customheader "github.com/ava-labs/coreth/plugin/evm/header"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap3"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
Expand Down Expand Up @@ -364,8 +364,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
fakeChainReader := newChainMaker(nil, config, engine)
time := parent.Time() + 10
configExtra := params.GetExtra(config)
extra, _ := header.ExtraPrefix(configExtra, parent.Header(), time)
baseFee, _ := header.BaseFee(configExtra, parent.Header(), time)
baseFee, _ := customheader.BaseFee(configExtra, parent.Header(), time)
header := &types.Header{
ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(),
Expand All @@ -378,7 +377,6 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
GasLimit: parent.GasLimit(),
Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time,
Extra: extra,
UncleHash: types.EmptyUncleHash,
BaseFee: baseFee,
}
Expand All @@ -403,6 +401,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
cumulativeGas += tx.Gas()
nBlobs += len(tx.BlobHashes())
}
header.Extra, _ = customheader.ExtraPrefix(configExtra, parent.Header(), time)
header.Root = common.BytesToHash(hasher.Sum(nil))
if config.IsCancun(header.Number, header.Time) {
var pExcess, pUsed = uint64(0), uint64(0)
Expand Down
21 changes: 1 addition & 20 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ import (
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/plugin/evm/header"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
"github.com/ava-labs/coreth/precompile/precompileconfig"
"github.com/ava-labs/coreth/predicate"
"github.com/ava-labs/libevm/common"
Expand Down Expand Up @@ -148,24 +146,8 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte
timestamp = parent.Time
}

var gasLimit uint64
chainExtra := params.GetExtra(w.chainConfig)
if chainExtra.IsCortina(timestamp) {
gasLimit = cortina.GasLimit
} else if chainExtra.IsApricotPhase1(timestamp) {
gasLimit = ap1.GasLimit
} else {
// The gas limit is set in phase1 to [ap1.GasLimit] because the ceiling
// and floor were set to the same value such that the gas limit
// converged to it. Since this is hardcoded now, we remove the ability
// to configure it.
gasLimit = core.CalcGasLimit(parent.GasUsed, parent.GasLimit, ap1.GasLimit, ap1.GasLimit)
}

extra, err := header.ExtraPrefix(chainExtra, parent, timestamp)
if err != nil {
return nil, fmt.Errorf("failed to calculate new extra prefix: %w", err)
}
gasLimit := header.GasLimit(chainExtra, parent, timestamp)
baseFee, err := header.BaseFee(chainExtra, parent, timestamp)
if err != nil {
return nil, fmt.Errorf("failed to calculate new base fee: %w", err)
Expand All @@ -176,7 +158,6 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte
Number: new(big.Int).Add(parent.Number, common.Big1),
GasLimit: gasLimit,
Time: timestamp,
Extra: extra,
BaseFee: baseFee,
}

Expand Down
18 changes: 0 additions & 18 deletions plugin/evm/block_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap0"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap5"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
"github.com/ava-labs/coreth/utils"
)

Expand Down Expand Up @@ -110,23 +109,6 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error {
return fmt.Errorf("invalid mix digest: %v", ethHeader.MixDigest)
}

// Enforce static gas limit after ApricotPhase1 (prior to ApricotPhase1 it's handled in processing).
if rulesExtra.IsCortina {
if ethHeader.GasLimit != cortina.GasLimit {
return fmt.Errorf(
"expected gas limit to be %d after cortina but got %d",
cortina.GasLimit, ethHeader.GasLimit,
)
}
} else if rulesExtra.IsApricotPhase1 {
if ethHeader.GasLimit != ap1.GasLimit {
return fmt.Errorf(
"expected gas limit to be %d after apricot phase 1 but got %d",
ap1.GasLimit, ethHeader.GasLimit,
)
}
}

// Verify the extra data is well-formed.
if err := header.VerifyExtra(rulesExtra.AvalancheRules, ethHeader.Extra); err != nil {
return err
Expand Down
89 changes: 89 additions & 0 deletions plugin/evm/header/gas_limit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// (c) 2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package header

import (
"errors"
"fmt"

"github.com/ava-labs/avalanchego/utils/math"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/plugin/evm/upgrade/ap1"
"github.com/ava-labs/coreth/plugin/evm/upgrade/cortina"
)

var errInvalidGasLimit = errors.New("invalid gas limit")

// GasLimit takes the previous header and the timestamp of its child block and
// calculates the gas limit for the child block.
func GasLimit(
config *extras.ChainConfig,
parent *types.Header,
timestamp uint64,
) uint64 {
switch {
case config.IsCortina(timestamp):
return cortina.GasLimit
case config.IsApricotPhase1(timestamp):
return ap1.GasLimit
default:
// The gas limit prior Apricot Phase 1 started at the genesis value and
// migrated towards the [ap1.GasLimit] following the `core.CalcGasLimit`
// updates. However, since all chains have activated Apricot Phase 1,
// this code is not used in production. To avoid a dependency on the
// `core` package, this code is modified to just return the parent gas
// limit; which was valid to do prior to Apricot Phase 1.
return parent.GasLimit
}
}

// VerifyGasLimit verifies that the gas limit for the header is valid.
func VerifyGasLimit(
config *extras.ChainConfig,
parent *types.Header,
header *types.Header,
) error {
switch {
case config.IsCortina(header.Time):
if header.GasLimit != cortina.GasLimit {
return fmt.Errorf("%w: expected to be %d in Cortina, but found %d",
errInvalidGasLimit,
cortina.GasLimit,
header.GasLimit,
)
}
case config.IsApricotPhase1(header.Time):
if header.GasLimit != ap1.GasLimit {
return fmt.Errorf("%w: expected to be %d in ApricotPhase1, but found %d",
errInvalidGasLimit,
ap1.GasLimit,
header.GasLimit,
)
}
default:
if header.GasLimit < params.MinGasLimit || header.GasLimit > params.MaxGasLimit {
return fmt.Errorf("%w: %d not in range [%d, %d]",
errInvalidGasLimit,
header.GasLimit,
params.MinGasLimit,
params.MaxGasLimit,
)
}

// Verify that the gas limit remains within allowed bounds
diff := math.AbsDiff(parent.GasLimit, header.GasLimit)
limit := parent.GasLimit / params.GasLimitBoundDivisor
if diff >= limit {
return fmt.Errorf("%w: have %d, want %d += %d",
errInvalidGasLimit,
header.GasLimit,
parent.GasLimit,
limit,
)
}
}
return nil
}
Loading

0 comments on commit 20c5470

Please sign in to comment.