From 01bb908790a369c1bb9d3937df9325c6857bf855 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Thu, 4 Nov 2021 21:01:41 +0100 Subject: [PATCH] core,eth: cancel evm on nativecalltracer stop --- core/vm/access_list_tracer.go | 2 +- core/vm/evm.go | 12 ++++++------ core/vm/instructions.go | 2 +- core/vm/logger.go | 6 +++--- core/vm/logger_json.go | 2 +- eth/tracers/native/call.go | 4 ++-- eth/tracers/native/noop.go | 2 +- eth/tracers/tracer.go | 2 +- eth/tracers/tracer_test.go | 4 +++- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/core/vm/access_list_tracer.go b/core/vm/access_list_tracer.go index 11b4e29426..b63bc4efc2 100644 --- a/core/vm/access_list_tracer.go +++ b/core/vm/access_list_tracer.go @@ -166,7 +166,7 @@ func (*AccessListTracer) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {} -func (*AccessListTracer) CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (*AccessListTracer) CaptureEnter(env *EVM, typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } func (*AccessListTracer) CaptureExit(output []byte, gasUsed uint64, err error) {} diff --git a/core/vm/evm.go b/core/vm/evm.go index 07e9619158..4c5a309cee 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -187,7 +187,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) } else { - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value) + evm.Config.Tracer.CaptureEnter(evm, CALL, caller.Address(), addr, input, gas, value) evm.Config.Tracer.CaptureExit(ret, 0, nil) } } @@ -206,7 +206,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas }(gas, time.Now()) } else { // Handle tracer events for entering and exiting a call frame - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value) + evm.Config.Tracer.CaptureEnter(evm, CALL, caller.Address(), addr, input, gas, value) defer func(startGas uint64) { evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) }(gas) @@ -272,7 +272,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Debug { - evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value) + evm.Config.Tracer.CaptureEnter(evm, CALLCODE, caller.Address(), addr, input, gas, value) defer func(startGas uint64) { evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) }(gas) @@ -316,7 +316,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Debug { - evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, nil) + evm.Config.Tracer.CaptureEnter(evm, DELEGATECALL, caller.Address(), addr, input, gas, nil) defer func(startGas uint64) { evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) }(gas) @@ -369,7 +369,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Debug { - evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil) + evm.Config.Tracer.CaptureEnter(evm, STATICCALL, caller.Address(), addr, input, gas, nil) defer func(startGas uint64) { evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) }(gas) @@ -456,7 +456,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if evm.depth == 0 { evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value) } else { - evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value) + evm.Config.Tracer.CaptureEnter(evm, typ, caller.Address(), address, codeAndHash.code, gas, value) } } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index bda480f083..32eef57927 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -792,7 +792,7 @@ func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) interpreter.evm.StateDB.Suicide(scope.Contract.Address()) if interpreter.cfg.Debug { - interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance) + interpreter.cfg.Tracer.CaptureEnter(interpreter.evm, SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance) interpreter.cfg.Tracer.CaptureExit([]byte{}, 0, nil) } return nil, nil diff --git a/core/vm/logger.go b/core/vm/logger.go index 048b84ff6f..ecb0fe263c 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -106,7 +106,7 @@ func (s *StructLog) ErrorString() string { type EVMLogger interface { CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) - CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) + CaptureEnter(env *EVM, typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) CaptureExit(output []byte, gasUsed uint64, err error) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) @@ -227,7 +227,7 @@ func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration } } -func (l *StructLogger) CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (l *StructLogger) CaptureEnter(env *EVM, typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} @@ -350,7 +350,7 @@ func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, tm time.Duration, e output, gasUsed, err) } -func (t *mdLogger) CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (t *mdLogger) CaptureEnter(env *EVM, typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } func (t *mdLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go index 479a00c0ac..0a9e57d514 100644 --- a/core/vm/logger_json.go +++ b/core/vm/logger_json.go @@ -88,7 +88,7 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, errMsg}) } -func (l *JSONLogger) CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (l *JSONLogger) CaptureEnter(env *EVM, typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 60426891a3..b8fe0adc62 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -90,10 +90,10 @@ func (t *callTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos func (t *callTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) { } -func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (t *callTracer) CaptureEnter(env *vm.EVM, typ 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 { - // TODO: env.Cancel() + env.Cancel() return } diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index 554bb18f14..b505c9b5d4 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -32,7 +32,7 @@ func (t *noopTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos func (t *noopTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) { } -func (t *noopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (t *noopTracer) CaptureEnter(env *vm.EVM, typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } func (t *noopTracer) CaptureExit(output []byte, gasUsed uint64, err error) { diff --git a/eth/tracers/tracer.go b/eth/tracers/tracer.go index 4fee7ed966..69d373037b 100644 --- a/eth/tracers/tracer.go +++ b/eth/tracers/tracer.go @@ -750,7 +750,7 @@ func (jst *jsTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, } // CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (jst *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +func (jst *jsTracer) CaptureEnter(env *vm.EVM, typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { if !jst.traceCallFrames { return } diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 0e78f34b62..398be835ef 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -255,8 +255,10 @@ func TestEnterExit(t *testing.T) { scope := &vm.ScopeContext{ Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0), } + vmctx := testCtx() + env := vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) - tracer.CaptureEnter(vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int)) + tracer.CaptureEnter(env, vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int)) tracer.CaptureExit([]byte{}, 400, nil) have, err := tracer.GetResult()