Skip to content

eth/tracers: refactor tracers to deduplicate code, use same underlying block/tx tracing methods for all code paths #31748

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

jwasinger
Copy link
Contributor

@jwasinger jwasinger commented Apr 30, 2025

Currently, tracers duplicate transaction execution logic three times. This PR modifies the implementation of the tracers so that block/transaction trace logic is only implemented once, and used by all tracers.

@jwasinger jwasinger changed the title eth/tracers: fix standardTraceBlockToFile, standardTraceBadBlockToFile. refactor standardTrace* and native/js tracers, deduplicating the shared logic between them eth/tracers: refactor tracers to deduplicate code, use same block/tx tracing methods for all code paths May 2, 2025
@jwasinger jwasinger changed the title eth/tracers: refactor tracers to deduplicate code, use same block/tx tracing methods for all code paths eth/tracers: refactor tracers to deduplicate code, use same underlying block/tx tracing methods for all code paths May 2, 2025
@@ -333,7 +324,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
close(resCh)
}()
// Feed all the blocks both into the tracer, as well as fast process concurrently
for number = start.NumberU64(); number < end.NumberU64(); number++ {
for number = start.NumberU64() + 1; number <= end.NumberU64(); number++ {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test case has been changed: number is now the block that we are scheduling a tracing task for. The reason for this change is that I separate block prestate retrieval into a separate method that is reused in other areas of this file, and this block number takes the block that we want to retrieve a prestate for (parent block is no longer explicitly needed in this function).

Comment on lines -381 to -391
// Insert block's parent beacon block root in the state
// as per EIP-4788.
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
evm := vm.NewEVM(context, statedb, api.backend.ChainConfig(), vm.Config{})
if beaconRoot := next.BeaconRoot(); beaconRoot != nil {
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
}
// Insert parent hash in history contract.
if api.backend.ChainConfig().IsPrague(next.Number(), next.Time()) {
core.ProcessParentBlockHash(next.ParentHash(), evm)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved this into traceBlockWithState

Comment on lines +805 to +809
type traceExecOptions struct {
txTimeout time.Duration
reexec uint64
parallel bool
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

traceBlock and traceTx (now execTx) are now agnostic to the type of tracer (call vs standard-trace vs js/native-trace). Now, we extract the trace execution parameters from the config type in the outer method call (StdTrace, TraceConfig, TraceCallConfig) into a traceExecOptions instance which is used by the internal tracing methods.

This reduces the size of some method signatures and prevents duplication of config instantiation logic.

@jwasinger jwasinger marked this pull request as ready for review May 9, 2025 04:14
@jwasinger jwasinger requested a review from s1na as a code owner May 9, 2025 04:14
}

execOpt := standardTraceExecOpt(config)
execOpt.txTimeout = 100 * time.Hour
Copy link
Contributor

@mask-pp mask-pp May 13, 2025

Choose a reason for hiding this comment

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

The timeout value is too long.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't currently have a timeout for the standardTrace methods. I think the reasoning is that these are usually used for debugging, and we want to ensure that the trace completes regardless of how long it takes.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's right to consider it from debug point.

execOpt := standardTraceExecOpt(config)
execOpt.txTimeout = 100 * time.Hour
if _, err := api.traceBlock(ctx, block, execOpt, chainConfig, instantiateTracer); err != nil {
return nil, err
Copy link
Contributor

Choose a reason for hiding this comment

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

If appear error, we also need to return the other successful traces.

Copy link
Contributor Author

@jwasinger jwasinger May 13, 2025

Choose a reason for hiding this comment

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

Good catch! also, traceBlock will not emit the traces if an error occurs midway through the trace.

Copy link
Contributor

Choose a reason for hiding this comment

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

So return dumps[:len(dumps)-1], err if len(dumps) > 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants