diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index b1eaf60b1..634302103 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -835,8 +835,8 @@ func TestTraceChain(t *testing.T) { signer := types.HomesteadSigner{} var ( - ref uint32 // total refs has made - rel uint32 // total rels has made + ref atomic.Uint32 // total refs has made + rel atomic.Uint32 // total rels has made nonce uint64 ) backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) { @@ -849,8 +849,8 @@ func TestTraceChain(t *testing.T) { nonce += 1 } }) - backend.refHook = func() { atomic.AddUint32(&ref, 1) } - backend.relHook = func() { atomic.AddUint32(&rel, 1) } + backend.refHook = func() { ref.Add(1) } + backend.relHook = func() { rel.Add(1) } api := NewAPI(backend) single := `{"result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}` @@ -863,7 +863,8 @@ func TestTraceChain(t *testing.T) { {10, 20, nil}, // the middle chain range, blocks [11, 20] } for _, c := range cases { - ref, rel = 0, 0 // clean up the counters + ref.Store(0) + rel.Store(0) from, _ := api.blockByNumber(context.Background(), rpc.BlockNumber(c.start)) to, _ := api.blockByNumber(context.Background(), rpc.BlockNumber(c.end)) @@ -888,8 +889,9 @@ func TestTraceChain(t *testing.T) { if next != c.end+1 { t.Error("Missing tracing block") } - if ref != rel { - t.Errorf("Ref and deref actions are not equal, ref %d rel %d", ref, rel) + + if nref, nrel := ref.Load(), rel.Load(); nref != nrel { + t.Errorf("Ref and deref actions are not equal, ref %d rel %d", nref, nrel) } } } diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 5e75318b9..c7f171c5b 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -116,8 +116,8 @@ type StructLogger struct { gasLimit uint64 usedGas uint64 - interrupt uint32 // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption + interrupt atomic.Bool // Atomic flag to signal execution interruption + reason error // Textual reason for the interruption } // NewStructLogger returns a new logger @@ -149,7 +149,7 @@ func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common. // CaptureState also tracks SLOAD/SSTORE ops to track storage change. func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { // If tracing was interrupted, set the error and stop - if atomic.LoadUint32(&l.interrupt) > 0 { + if l.interrupt.Load() { return } // check if already accumulated the specified number of logs @@ -258,7 +258,7 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) { // Stop terminates execution of the tracer at the first opportune moment. func (l *StructLogger) Stop(err error) { l.reason = err - atomic.StoreUint32(&l.interrupt, 1) + l.interrupt.Store(true) } func (l *StructLogger) CaptureTxStart(gasLimit uint64) { diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 1b4649baa..5a2c4f911 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -48,7 +48,7 @@ func init() { type fourByteTracer struct { noopTracer ids map[string]int // ids aggregates the 4byte ids found - interrupt uint32 // Atomic flag to signal execution interruption + interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption activePrecompiles []common.Address // Updated on CaptureStart based on given rules } @@ -93,7 +93,7 @@ func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to commo // CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { // Skip if tracing was interrupted - if atomic.LoadUint32(&t.interrupt) > 0 { + if t.interrupt.Load() { return } if len(input) < 4 { @@ -124,7 +124,7 @@ func (t *fourByteTracer) GetResult() (json.RawMessage, error) { // Stop terminates execution of the tracer at the first opportune moment. func (t *fourByteTracer) Stop(err error) { t.reason = err - atomic.StoreUint32(&t.interrupt, 1) + t.interrupt.Store(true) } func bytesToHex(s []byte) string { diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index c3db1ad03..4ac03e512 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -102,8 +102,8 @@ type callTracer struct { callstack []callFrame config callTracerConfig gasLimit uint64 - interrupt uint32 // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption + interrupt atomic.Bool // Atomic flag to signal execution interruption + reason error // Textual reason for the interruption } type callTracerConfig struct { @@ -161,7 +161,7 @@ func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco return } // Skip if tracing was interrupted - if atomic.LoadUint32(&t.interrupt) > 0 { + if t.interrupt.Load() { return } switch op { @@ -197,7 +197,7 @@ func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common. return } // Skip if tracing was interrupted - if atomic.LoadUint32(&t.interrupt) > 0 { + if t.interrupt.Load() { return } @@ -262,7 +262,7 @@ func (t *callTracer) GetResult() (json.RawMessage, error) { // Stop terminates execution of the tracer at the first opportune moment. func (t *callTracer) Stop(err error) { t.reason = err - atomic.StoreUint32(&t.interrupt, 1) + t.interrupt.Store(true) } // clearFailedLogs clears the logs of a callframe and all its children diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 42ec4fe78..b71d5d621 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -62,8 +62,8 @@ type prestateTracer struct { to common.Address gasLimit uint64 // Amount of gas bought for the whole tx config prestateTracerConfig - interrupt uint32 // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption + interrupt atomic.Bool // Atomic flag to signal execution interruption + reason error // Textual reason for the interruption created map[common.Address]bool deleted map[common.Address]bool } @@ -136,6 +136,10 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, if err != nil { return } + // Skip if tracing was interrupted + if t.interrupt.Load() { + return + } stack := scope.Stack stackData := stack.Data() stackLen := len(stackData) @@ -259,7 +263,7 @@ func (t *prestateTracer) GetResult() (json.RawMessage, error) { // Stop terminates execution of the tracer at the first opportune moment. func (t *prestateTracer) Stop(err error) { t.reason = err - atomic.StoreUint32(&t.interrupt, 1) + t.interrupt.Store(true) } // lookupAccount fetches details of an account and adds it to the prestate