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

feat(trace): allow override fork #836

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
5 changes: 3 additions & 2 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/scroll-tech/go-ethereum/core/rawdb"
"github.com/scroll-tech/go-ethereum/core/state"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/core/vm"
"github.com/scroll-tech/go-ethereum/ethdb"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/metrics"
Expand Down Expand Up @@ -69,7 +70,7 @@ func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engin
}

type tracerWrapper interface {
CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error)
CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, *vm.LogConfig, ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error)
}

func (v *BlockValidator) SetupTracerAndCircuitCapacityChecker(tracer tracerWrapper) {
Expand Down Expand Up @@ -298,7 +299,7 @@ func (v *BlockValidator) createTraceEnvAndGetBlockTrace(block *types.Block) (*ty
return nil, err
}

return v.tracer.CreateTraceEnvAndGetBlockTrace(v.config, v.bc, v.engine, v.bc.db, statedb, parent, block, true)
return v.tracer.CreateTraceEnvAndGetBlockTrace(v.config, nil, v.bc, v.engine, v.bc.db, statedb, parent, block, true)
}

func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*types.RowConsumption, error) {
Expand Down
21 changes: 19 additions & 2 deletions eth/tracers/api_blocktrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"

"github.com/scroll-tech/go-ethereum/consensus"
"github.com/scroll-tech/go-ethereum/consensus/misc"
"github.com/scroll-tech/go-ethereum/core"
"github.com/scroll-tech/go-ethereum/core/state"
"github.com/scroll-tech/go-ethereum/core/types"
Expand All @@ -23,7 +24,7 @@ type TraceBlock interface {
}

type scrollTracerWrapper interface {
CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, core.ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error)
CreateTraceEnvAndGetBlockTrace(*params.ChainConfig, *vm.LogConfig, core.ChainContext, consensus.Engine, ethdb.Database, *state.StateDB, *types.Block, *types.Block, bool) (*types.BlockTrace, error)
}

// GetBlockTraceByNumberOrHash replays the block and returns the structured BlockTrace by hash or number.
Expand Down Expand Up @@ -109,5 +110,21 @@ func (api *API) createTraceEnvAndGetBlockTrace(ctx context.Context, config *Trac
}

chaindb := api.backend.ChainDb()
return api.scrollTracerWrapper.CreateTraceEnvAndGetBlockTrace(api.backend.ChainConfig(), api.chainContext(ctx), api.backend.Engine(), chaindb, statedb, parent, block, true)
// create a copy of api.backend.ChainConfig to modify
chainConfig := new(params.ChainConfig)
*chainConfig = *api.backend.ChainConfig()
if config != nil && config.Overrides != nil {
// In future we can add more fork related logics here
// like upstream: https://github.com/ethereum/go-ethereum/pull/26655
if curie := config.Overrides.CurieBlock; curie != nil {
chainConfig.CurieBlock = curie
if block.Number().Cmp(curie) > 0 {
// set non zero values for these slots
misc.ApplyCurieHardFork(statedb)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if Curie fork is already enabled, this will overwrite L1GasPriceOracle's storage.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if block.Number().Cmp(api.backend.ChainConfig().CurieBlock) < 0 && block.Number().Cmp(curie) > 0 {. sounds more reasonable?

Copy link

@omerfirmak omerfirmak Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is better. But I am afraid not complete. Maybe something like below?

!api.backend.ChainConfig().IsCurie(block.Number()) && block.Number().Cmp(curie) >= 0

Copy link
Author

@lispc lispc Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact if block.Number().Cmp(curie) == 0, i think we don't need to inject system upgrades twice.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact if block.Number().Cmp(curie) == 0, i think we don't need to inject system upgrades twice.

as long as !api.backend.ChainConfig().IsCurie(block.Number()) is true, I don't think we would be applying the upgrade twice. If we apply only when block.Number().Cmp(curie) > 0, ApplyCurieHardFork will be applied one block late if I am not mistkaen.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ApplyCurieHardFork will be applied one block late": you mean the bytecode force upgrade does not happen exactly at the fork height? i don't think so..

statedb.IntermediateRoot(true)
}
}
log.Info("chainConfig overrided by traceConfig.Overrides", "chainConfig", chainConfig, "config.Overrides", config.Overrides)
}
return api.scrollTracerWrapper.CreateTraceEnvAndGetBlockTrace(chainConfig, config.LogConfig, api.chainContext(ctx), api.backend.Engine(), chaindb, statedb, parent, block, true)
}
2 changes: 1 addition & 1 deletion params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
const (
VersionMajor = 5 // Major version component of the current release
VersionMinor = 4 // Minor version component of the current release
VersionPatch = 4 // Patch version component of the current release
VersionPatch = 5 // Patch version component of the current release
VersionMeta = "mainnet" // Version metadata to append to the version string
)

Expand Down
2 changes: 1 addition & 1 deletion rollup/pipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ func (p *Pipeline) traceAndApply(tx *types.Transaction) (*types.Receipt, *types.
// 2.1 when starting handling the first tx, `state.refund` is 0 by default,
// 2.2 after tracing, the state is either committed in `core.ApplyTransaction`, or reverted, so the `state.refund` can be cleared,
// 2.3 when starting handling the following txs, `state.refund` comes as 0
trace, err = tracing.NewTracerWrapper().CreateTraceEnvAndGetBlockTrace(p.chain.Config(), p.chain, p.chain.Engine(), p.chain.Database(),
trace, err = tracing.NewTracerWrapper().CreateTraceEnvAndGetBlockTrace(p.chain.Config(), nil, p.chain, p.chain.Engine(), p.chain.Database(),
p.state, p.parent, types.NewBlockWithHeader(&p.Header).WithBody([]*types.Transaction{tx}, nil), commitStateAfterApply)
// `w.current.traceEnv.State` & `w.current.state` share a same pointer to the state, so only need to revert `w.current.state`
// revert to snapshot for calling `core.ApplyMessage` again, (both `traceEnv.GetBlockTrace` & `core.ApplyTransaction` will call `core.ApplyMessage`)
Expand Down
24 changes: 14 additions & 10 deletions rollup/tracing/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func NewTracerWrapper() *TracerWrapper {
}

// CreateTraceEnvAndGetBlockTrace wraps the whole block tracing logic for a block
func (tw *TracerWrapper) CreateTraceEnvAndGetBlockTrace(chainConfig *params.ChainConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*types.BlockTrace, error) {
traceEnv, err := CreateTraceEnv(chainConfig, chainContext, engine, chaindb, statedb, parent, block, commitAfterApply)
func (tw *TracerWrapper) CreateTraceEnvAndGetBlockTrace(chainConfig *params.ChainConfig, logConfig *vm.LogConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*types.BlockTrace, error) {
traceEnv, err := CreateTraceEnv(chainConfig, logConfig, chainContext, engine, chaindb, statedb, parent, block, commitAfterApply)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -98,6 +98,15 @@ type txTraceTask struct {
}

func CreateTraceEnvHelper(chainConfig *params.ChainConfig, logConfig *vm.LogConfig, blockCtx vm.BlockContext, startL1QueueIndex uint64, coinbase common.Address, statedb *state.StateDB, rootBefore common.Hash, block *types.Block, commitAfterApply bool) *TraceEnv {
if logConfig == nil {
logConfig = &vm.LogConfig{
DisableStorage: true,
DisableStack: true,
EnableMemory: false,
EnableReturnData: true,
}
}

return &TraceEnv{
logConfig: logConfig,
commitAfterApply: commitAfterApply,
Expand All @@ -119,7 +128,7 @@ func CreateTraceEnvHelper(chainConfig *params.ChainConfig, logConfig *vm.LogConf
}
}

func CreateTraceEnv(chainConfig *params.ChainConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*TraceEnv, error) {
func CreateTraceEnv(chainConfig *params.ChainConfig, logConfig *vm.LogConfig, chainContext core.ChainContext, engine consensus.Engine, chaindb ethdb.Database, statedb *state.StateDB, parent *types.Block, block *types.Block, commitAfterApply bool) (*TraceEnv, error) {
var coinbase common.Address

var err error
Expand Down Expand Up @@ -150,17 +159,12 @@ func CreateTraceEnv(chainConfig *params.ChainConfig, chainContext core.ChainCont
}
env := CreateTraceEnvHelper(
chainConfig,
&vm.LogConfig{
DisableStorage: true,
DisableStack: true,
EnableMemory: false,
EnableReturnData: true,
},
logConfig,
core.NewEVMBlockContext(block.Header(), chainContext, chainConfig, nil),
*startL1QueueIndex,
coinbase,
statedb,
parent.Root(),
statedb.GetRootHash(), // use `statedb.GetRootHash()` instead of `parent.Root()` because statedb might be overrided
block,
commitAfterApply,
)
Expand Down
Loading