@@ -171,6 +171,13 @@ type StdTraceConfig struct {
171171 TxHash common.Hash
172172}
173173
174+ // txTraceContext is the contextual infos about a transaction before it gets run.
175+ type txTraceContext struct {
176+ index int // Index of the transaction within the block
177+ hash common.Hash // Hash of the transaction
178+ block common.Hash // Hash of the block containing the transaction
179+ }
180+
174181// txTraceResult is the result of a single transaction trace.
175182type txTraceResult struct {
176183 Result interface {} `json:"result,omitempty"` // Trace results produced by the tracer
@@ -269,7 +276,12 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config
269276 // Trace all the transactions contained within
270277 for i , tx := range task .block .Transactions () {
271278 msg , _ := tx .AsMessage (signer )
272- res , err := api .traceTx (ctx , msg , blockCtx , task .statedb , config )
279+ txctx := & txTraceContext {
280+ index : i ,
281+ hash : tx .Hash (),
282+ block : task .block .Hash (),
283+ }
284+ res , err := api .traceTx (ctx , msg , txctx , blockCtx , task .statedb , config )
273285 if err != nil {
274286 task .results [i ] = & txTraceResult {Error : err .Error ()}
275287 log .Warn ("Tracing failed" , "hash" , tx .Hash (), "block" , task .block .NumberU64 (), "err" , err )
@@ -481,14 +493,22 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
481493 threads = len (txs )
482494 }
483495 blockCtx := core .NewEVMBlockContext (block .Header (), api .chainContext (ctx ))
496+ blockHash := block .Hash ()
484497 for th := 0 ; th < threads ; th ++ {
485498 pend .Add (1 )
486499 go func () {
487500 defer pend .Done ()
488501 // Fetch and execute the next transaction trace tasks
489502 for task := range jobs {
490503 msg , _ := txs [task .index ].AsMessage (signer )
491- res , err := api .traceTx (ctx , msg , blockCtx , task .statedb , config )
504+
505+ txctx := & txTraceContext {
506+ index : task .index ,
507+ hash : txs [task .index ].Hash (),
508+ block : blockHash ,
509+ }
510+ res , err := api .traceTx (ctx , msg , txctx , blockCtx , task .statedb , config )
511+
492512 if err != nil {
493513 results [task .index ] = & txTraceResult {Error : err .Error ()}
494514 continue
@@ -505,9 +525,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
505525
506526 // Generate the next state snapshot fast without tracing
507527 msg , _ := tx .AsMessage (signer )
528+ statedb .Prepare (tx .Hash (), block .Hash (), i )
508529 txContext := core .NewEVMTxContext (msg )
509-
510530 vmenv := vm .NewEVM (blockCtx , txContext , snapshotdb .Instance (), statedb , api .backend .ChainConfig (), vm.Config {})
531+
511532 if _ , err := core .ApplyMessage (vmenv , msg , new (core.GasPool ).AddGas (msg .Gas ())); err != nil {
512533 failed = err
513534 break
@@ -616,6 +637,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
616637 }
617638 // Execute the transaction and flush any traces to disk
618639 vmenv := vm .NewEVM (vmctx , txContext , snapshotdb .Instance (), statedb , chainConfig , vmConf )
640+ statedb .Prepare (tx .Hash (), block .Hash (), i )
619641 _ , err = core .ApplyMessage (vmenv , msg , new (core.GasPool ).AddGas (msg .Gas ()))
620642 if writer != nil {
621643 writer .Flush ()
@@ -673,8 +695,12 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
673695 return nil , err
674696 }
675697 defer release ()
676-
677- return api .traceTx (ctx , msg , vmctx , statedb , config )
698+ txctx := & txTraceContext {
699+ index : int (index ),
700+ hash : hash ,
701+ block : blockHash ,
702+ }
703+ return api .traceTx (ctx , msg , txctx , vmctx , statedb , config )
678704}
679705
680706// TraceCall lets you trace a given eth_call. It collects the structured logs
@@ -709,13 +735,14 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHa
709735 // Execute the trace
710736 msg := args .ToMessage (api .backend .RPCGasCap ())
711737 vmctx := core .NewEVMBlockContext (block .Header (), api .chainContext (ctx ))
712- return api .traceTx (ctx , msg , vmctx , statedb , config )
738+
739+ return api .traceTx (ctx , msg , new (txTraceContext ), vmctx , statedb , config )
713740}
714741
715742// traceTx configures a new tracer according to the provided configuration, and
716743// executes the given message in the provided environment. The return value will
717744// be tracer dependent.
718- func (api * API ) traceTx (ctx context.Context , message core.Message , vmctx vm.BlockContext , statedb * state.StateDB , config * TraceConfig ) (interface {}, error ) {
745+ func (api * API ) traceTx (ctx context.Context , message core.Message , txctx * txTraceContext , vmctx vm.BlockContext , statedb * state.StateDB , config * TraceConfig ) (interface {}, error ) {
719746 // Assemble the structured logger or the JavaScript tracer
720747 var (
721748 tracer vm.Tracer
@@ -752,6 +779,9 @@ func (api *API) traceTx(ctx context.Context, message core.Message, vmctx vm.Bloc
752779 // Run the transaction with tracing enabled.
753780 vmenv := vm .NewEVM (vmctx , txContext , snapshotdb .Instance (), statedb , api .backend .ChainConfig (), vm.Config {Debug : true , Tracer : tracer })
754781
782+ // Call Prepare to clear out the statedb access list
783+ statedb .Prepare (txctx .hash , txctx .block , txctx .index )
784+
755785 result , err := core .ApplyMessage (vmenv , message , new (core.GasPool ).AddGas (message .Gas ()))
756786 if err != nil {
757787 return nil , fmt .Errorf ("tracing failed: %v" , err )
0 commit comments