@@ -22,6 +22,7 @@ import (
2222 "fmt"
2323 "math/big"
2424 "strings"
25+ "sync/atomic"
2526
2627 "github.com/ethereum/go-ethereum/common"
2728 "github.com/ethereum/go-ethereum/common/hexutil"
@@ -119,7 +120,7 @@ type flatCallTracer struct {
119120 tracer * callTracer
120121 config flatCallTracerConfig
121122 ctx * tracers.Context // Holds tracer context data
122- reason error // Textual reason for the interruption
123+ interrupt atomic. Bool // Atomic flag to signal execution interruption
123124 activePrecompiles []common.Address // Updated on CaptureStart based on given rules
124125}
125126
@@ -159,6 +160,9 @@ func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Trace
159160
160161// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
161162func (t * flatCallTracer ) CaptureStart (env * vm.EVM , from common.Address , to common.Address , create bool , input []byte , gas uint64 , value * big.Int ) {
163+ if t .interrupt .Load () {
164+ return
165+ }
162166 t .tracer .CaptureStart (env , from , to , create , input , gas , value )
163167 // Update list of precompiles based on current block
164168 rules := env .ChainConfig ().Rules (env .Context .BlockNumber , env .Context .Random != nil , env .Context .Time , env .Context .ArbOSVersion )
@@ -167,21 +171,33 @@ func (t *flatCallTracer) CaptureStart(env *vm.EVM, from common.Address, to commo
167171
168172// CaptureEnd is called after the call finishes to finalize the tracing.
169173func (t * flatCallTracer ) CaptureEnd (output []byte , gasUsed uint64 , err error ) {
174+ if t .interrupt .Load () {
175+ return
176+ }
170177 t .tracer .CaptureEnd (output , gasUsed , err )
171178}
172179
173180// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
174181func (t * flatCallTracer ) CaptureState (pc uint64 , op vm.OpCode , gas , cost uint64 , scope * vm.ScopeContext , rData []byte , depth int , err error ) {
182+ if t .interrupt .Load () {
183+ return
184+ }
175185 t .tracer .CaptureState (pc , op , gas , cost , scope , rData , depth , err )
176186}
177187
178188// CaptureFault implements the EVMLogger interface to trace an execution fault.
179189func (t * flatCallTracer ) CaptureFault (pc uint64 , op vm.OpCode , gas , cost uint64 , scope * vm.ScopeContext , depth int , err error ) {
190+ if t .interrupt .Load () {
191+ return
192+ }
180193 t .tracer .CaptureFault (pc , op , gas , cost , scope , depth , err )
181194}
182195
183196// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
184197func (t * flatCallTracer ) CaptureEnter (typ vm.OpCode , from common.Address , to common.Address , input []byte , gas uint64 , value * big.Int ) {
198+ if t .interrupt .Load () {
199+ return
200+ }
185201 t .tracer .CaptureEnter (typ , from , to , input , gas , value )
186202
187203 // Child calls must have a value, even if it's zero.
@@ -194,6 +210,9 @@ func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to com
194210// CaptureExit is called when EVM exits a scope, even if the scope didn't
195211// execute any code.
196212func (t * flatCallTracer ) CaptureExit (output []byte , gasUsed uint64 , err error ) {
213+ if t .interrupt .Load () {
214+ return
215+ }
197216 t .tracer .CaptureExit (output , gasUsed , err )
198217
199218 // Parity traces don't include CALL/STATICCALLs to precompiles.
@@ -216,10 +235,16 @@ func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
216235}
217236
218237func (t * flatCallTracer ) CaptureTxStart (gasLimit uint64 ) {
238+ if t .interrupt .Load () {
239+ return
240+ }
219241 t .tracer .CaptureTxStart (gasLimit )
220242}
221243
222244func (t * flatCallTracer ) CaptureTxEnd (restGas uint64 ) {
245+ if t .interrupt .Load () {
246+ return
247+ }
223248 t .tracer .CaptureTxEnd (restGas )
224249}
225250
@@ -243,12 +268,13 @@ func (t *flatCallTracer) GetResult() (json.RawMessage, error) {
243268 if err != nil {
244269 return nil , err
245270 }
246- return res , t .reason
271+ return res , t .tracer . reason
247272}
248273
249274// Stop terminates execution of the tracer at the first opportune moment.
250275func (t * flatCallTracer ) Stop (err error ) {
251276 t .tracer .Stop (err )
277+ t .interrupt .Store (true )
252278}
253279
254280// isPrecompiled returns whether the addr is a precompile.
0 commit comments