diff --git a/eth/tracers/api_blocktrace.go b/eth/tracers/api_blocktrace.go index d257eb344e8e..61ca50438416 100644 --- a/eth/tracers/api_blocktrace.go +++ b/eth/tracers/api_blocktrace.go @@ -13,6 +13,7 @@ import ( type TraceBlock interface { GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (trace *types.BlockTrace, err error) + GetTxBlockTraceOnTopOfBlock(ctx context.Context, tx *types.Transaction, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (*types.BlockTrace, error) } // GetBlockTraceByNumberOrHash replays the block and returns the structured BlockTrace by hash or number. @@ -20,9 +21,10 @@ func (api *API) GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash r var block *types.Block if number, ok := blockNrOrHash.Number(); ok { block, err = api.blockByNumber(ctx, number) - } - if hash, ok := blockNrOrHash.Hash(); ok { + } else if hash, ok := blockNrOrHash.Hash(); ok { block, err = api.blockByHash(ctx, hash) + } else { + return nil, errors.New("invalid arguments; neither block number nor hash specified") } if err != nil { return nil, err @@ -30,18 +32,37 @@ func (api *API) GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash r if block.NumberU64() == 0 { return nil, errors.New("genesis is not traceable") } - if config == nil { - config = &TraceConfig{ - LogConfig: &vm.LogConfig{ - EnableMemory: false, - EnableReturnData: true, - }, - } - } else if config.Tracer != nil { - config.Tracer = nil - log.Warn("Tracer params is unsupported") + + env, err := api.createTraceEnv(ctx, config, block) + if err != nil { + return nil, err } + return env.GetBlockTrace(block) +} + +func (api *API) GetTxBlockTraceOnTopOfBlock(ctx context.Context, tx *types.Transaction, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (*types.BlockTrace, error) { + // Try to retrieve the specified block + var ( + err error + block *types.Block + ) + if number, ok := blockNrOrHash.Number(); ok { + block, err = api.blockByNumber(ctx, number) + } else if hash, ok := blockNrOrHash.Hash(); ok { + block, err = api.blockByHash(ctx, hash) + } else { + return nil, errors.New("invalid arguments; neither block number nor hash specified") + } + if err != nil { + return nil, err + } + if block.NumberU64() == 0 { + return nil, errors.New("genesis is not traceable") + } + + block = types.NewBlockWithHeader(block.Header()).WithBody([]*types.Transaction{tx}, nil) + // create current execution environment. env, err := api.createTraceEnv(ctx, config, block) if err != nil { @@ -53,6 +74,18 @@ func (api *API) GetBlockTraceByNumberOrHash(ctx context.Context, blockNrOrHash r // Make trace environment for current block. func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block *types.Block) (*core.TraceEnv, error) { + if config == nil { + config = &TraceConfig{ + LogConfig: &vm.LogConfig{ + EnableMemory: false, + EnableReturnData: true, + }, + } + } else if config.Tracer != nil { + config.Tracer = nil + log.Warn("Tracer params is unsupported") + } + parent, err := api.blockByNumberAndHash(ctx, rpc.BlockNumber(block.NumberU64()-1), block.ParentHash()) if err != nil { return nil, err @@ -65,6 +98,7 @@ func (api *API) createTraceEnv(ctx context.Context, config *TraceConfig, block * if err != nil { return nil, err } + chaindb := api.backend.ChainDb() return core.CreateTraceEnv(api.backend.ChainConfig(), api.chainContext(ctx), api.backend.Engine(), chaindb, statedb, parent, block, true) } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 0b7502ca13cc..04fc46cb421d 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -865,6 +865,12 @@ web3._extend({ call: 'scroll_getBlockTraceByNumberOrHash', params: 1 }), + new web3._extend.Method({ + name: 'getTxBlockTraceOnTopOfBlock', + call: 'scroll_getTxBlockTraceOnTopOfBlock', + params: 3, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null, null] + }), new web3._extend.Method({ name: 'getL1MessageByIndex', call: 'scroll_getL1MessageByIndex', diff --git a/params/version.go b/params/version.go index 4f05484a8662..b67e360e1bfc 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 3 // Patch version component of the current release + VersionPatch = 4 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string )