From 0d268b796cc8a01533b8eaa46ac1607050660c58 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Wed, 8 Nov 2023 19:28:42 +0300 Subject: [PATCH] fix TxStart for traceCall --- cmd/evm/internal/t8ntool/execution.go | 2 +- core/state_processor.go | 2 +- core/vm/logger.go | 4 +++- core/vm/runtime/runtime.go | 6 +++--- eth/tracers/api.go | 2 +- eth/tracers/directory/noop.go | 2 +- eth/tracers/internal/tracetest/calltrace_test.go | 4 ++-- eth/tracers/internal/tracetest/flat_calltrace_test.go | 2 +- eth/tracers/internal/tracetest/prestate_test.go | 2 +- eth/tracers/js/goja.go | 2 +- eth/tracers/js/tracer_test.go | 6 +++--- eth/tracers/live/printer.go | 2 +- eth/tracers/logger/logger.go | 2 +- eth/tracers/logger/logger_json.go | 2 +- eth/tracers/logger/logger_test.go | 2 +- eth/tracers/native/4byte.go | 2 +- eth/tracers/native/call.go | 2 +- eth/tracers/native/call_flat.go | 4 ++-- eth/tracers/native/mux.go | 4 ++-- eth/tracers/native/prestate.go | 9 +-------- 20 files changed, 29 insertions(+), 34 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 4dc9aa264d..532e36fd1e 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -234,7 +234,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, ) evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig) - tracer.CaptureTxStart(evm, tx) + tracer.CaptureTxStart(evm, tx, msg.From) // (ret []byte, usedGas uint64, failed bool, err error) msgResult, err := core.ApplyMessage(evm, msg, gaspool) if err != nil { diff --git a/core/state_processor.go b/core/state_processor.go index e2e2fe1a02..d2740a1bdc 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -113,7 +113,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // this method takes an already created EVM instance as input. func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) { if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureTxStart(evm, tx) + evm.Config.Tracer.CaptureTxStart(evm, tx, msg.From) defer func() { evm.Config.Tracer.CaptureTxEnd(receipt, err) }() diff --git a/core/vm/logger.go b/core/vm/logger.go index a675563821..94c499b0a4 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -30,7 +30,9 @@ import ( // if you need to retain them beyond the current call. type EVMLogger interface { // Transaction level - CaptureTxStart(evm *EVM, tx *types.Transaction) + // Call simulations don't come with a valid signature. `from` field + // to be used for address of the caller. + CaptureTxStart(evm *EVM, tx *types.Transaction, from common.Address) CaptureTxEnd(receipt *types.Receipt, err error) // Top call frame CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 57b367a529..37bf38303c 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -122,7 +122,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) if cfg.EVMConfig.Tracer != nil { - cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit})) + cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) @@ -158,7 +158,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) if cfg.EVMConfig.Tracer != nil { - cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit})) + cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) @@ -189,7 +189,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time) ) if cfg.EVMConfig.Tracer != nil { - cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit})) + cfg.EVMConfig.Tracer.CaptureTxStart(vmenv, types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin) } // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) diff --git a/eth/tracers/api.go b/eth/tracers/api.go index c1fb506e38..9278bb74a1 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -784,7 +784,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Execute the transaction and flush any traces to disk vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf) statedb.SetTxContext(tx.Hash(), i) - vmConf.Tracer.CaptureTxStart(vmenv, tx) + vmConf.Tracer.CaptureTxStart(vmenv, tx, msg.From) vmRet, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)) vmConf.Tracer.CaptureTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, err) if writer != nil { diff --git a/eth/tracers/directory/noop.go b/eth/tracers/directory/noop.go index 973b1abb47..f02884e33b 100644 --- a/eth/tracers/directory/noop.go +++ b/eth/tracers/directory/noop.go @@ -70,7 +70,7 @@ func (t *NoopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common. func (t *NoopTracer) CaptureExit(output []byte, gasUsed uint64, err error) { } -func (*NoopTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) {} +func (*NoopTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) {} func (*NoopTracer) CaptureTxEnd(receipt *types.Receipt, err error) {} diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 6a17693a40..4c30cddf09 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -153,7 +153,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - tracer.CaptureTxStart(evm, tx) + tracer.CaptureTxStart(evm, tx, msg.From) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { t.Fatalf("failed to execute transaction: %v", err) @@ -401,7 +401,7 @@ func TestInternals(t *testing.T) { if err != nil { t.Fatalf("test %v: failed to create message: %v", tc.name, err) } - tc.tracer.CaptureTxStart(evm, tx) + tc.tracer.CaptureTxStart(evm, tx, msg.From) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { t.Fatalf("test %v: failed to execute transaction: %v", tc.name, err) diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index dcd59d2566..4b56dfd6b9 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -113,7 +113,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string if err != nil { return fmt.Errorf("failed to prepare transaction for tracing: %v", err) } - tracer.CaptureTxStart(evm, tx) + tracer.CaptureTxStart(evm, tx, msg.From) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { return fmt.Errorf("failed to execute transaction: %v", err) diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 1a371d2715..9a9189e399 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -122,7 +122,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - tracer.CaptureTxStart(evm, tx) + tracer.CaptureTxStart(evm, tx, msg.From) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { t.Fatalf("failed to execute transaction: %v", err) diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index c21b01525a..021ae9d104 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -214,7 +214,7 @@ func newJsTracer(code string, ctx *directory.Context, cfg json.RawMessage) (dire // CaptureTxStart implements the Tracer interface and is invoked at the beginning of // transaction processing. -func (t *jsTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (t *jsTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { t.env = env // Need statedb access for db object db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf} diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 0706690c89..a247b99318 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -74,7 +74,7 @@ func runTrace(tracer directory.Tracer, vmctx *vmContext, chaincfg *params.ChainC contract.Code = contractCode } - tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{Gas: gasLimit})) + tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{Gas: gasLimit}), contract.Caller()) tracer.CaptureStart(contract.Caller(), contract.Address(), false, []byte{}, startGas, value) ret, err := env.Interpreter().Run(contract, []byte{}, false) tracer.CaptureEnd(ret, startGas-contract.Gas, err) @@ -185,7 +185,7 @@ func TestHaltBetweenSteps(t *testing.T) { Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0), } env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) - tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{})) + tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{}), common.Address{}) tracer.CaptureStart(common.Address{}, common.Address{}, false, []byte{}, 0, big.NewInt(0)) tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) timeout := errors.New("stahp") @@ -207,7 +207,7 @@ func TestNoStepExec(t *testing.T) { t.Fatal(err) } env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) - tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{})) + tracer.CaptureTxStart(env, types.NewTx(&types.LegacyTx{}), common.Address{}) tracer.CaptureStart(common.Address{}, common.Address{}, false, []byte{}, 1000, big.NewInt(0)) tracer.CaptureEnd(nil, 0, nil) ret, err := tracer.GetResult() diff --git a/eth/tracers/live/printer.go b/eth/tracers/live/printer.go index 1f51a6fc3f..27657ae56e 100644 --- a/eth/tracers/live/printer.go +++ b/eth/tracers/live/printer.go @@ -58,7 +58,7 @@ func (p *Printer) CaptureExit(output []byte, gasUsed uint64, err error) { fmt.Printf("CaptureExit: output=%s, gasUsed=%v, err=%v\n", hexutil.Bytes(output), gasUsed, err) } -func (p *Printer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (p *Printer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { buf, err := json.Marshal(tx) if err != nil { fmt.Printf("err: %v\n", err) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 22294252af..6ca12846ad 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -246,7 +246,7 @@ func (l *StructLogger) Stop(err error) { l.interrupt.Store(true) } -func (l *StructLogger) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (l *StructLogger) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { l.env = env } diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index 1ea014a0d6..96d6f1a101 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -90,6 +90,6 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), errMsg}) } -func (l *JSONLogger) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (l *JSONLogger) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { l.env = env } diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go index e6c3be41cd..a244e3f9ca 100644 --- a/eth/tracers/logger/logger_test.go +++ b/eth/tracers/logger/logger_test.go @@ -60,7 +60,7 @@ func TestStoreCapture(t *testing.T) { ) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)} var index common.Hash - logger.CaptureTxStart(env, nil) + logger.CaptureTxStart(env, nil, common.Address{}) logger.CaptureStart(common.Address{}, contract.Address(), false, nil, 0, nil) _, err := env.Interpreter().Run(contract, []byte{}, false) if err != nil { diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index b25ff06ae2..c7c45cfaa4 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -80,7 +80,7 @@ func (t *fourByteTracer) store(id []byte, size int) { t.ids[key] += 1 } -func (t *fourByteTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (t *fourByteTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { t.env = env // Update list of precompiles based on current block rules := t.env.ChainConfig().Rules(t.env.Context.BlockNumber, t.env.Context.Random != nil, t.env.Context.Time) diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index bb2ea19b54..6f1654d3f1 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -196,7 +196,7 @@ func (t *callTracer) CaptureExit(output []byte, gasUsed uint64, err error) { t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call) } -func (t *callTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (t *callTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { t.gasLimit = tx.Gas() } diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index d5aebc00fd..dbbe6901a3 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -200,8 +200,8 @@ func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) { } } -func (t *flatCallTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { - t.tracer.CaptureTxStart(env, tx) +func (t *flatCallTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { + t.tracer.CaptureTxStart(env, tx, from) // Update list of precompiles based on current block rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time) t.activePrecompiles = vm.ActivePrecompiles(rules) diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index dab284a3a3..c39d840876 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -117,9 +117,9 @@ func (t *muxTracer) CaptureExit(output []byte, gasUsed uint64, err error) { } } -func (t *muxTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (t *muxTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { for _, t := range t.tracers { - t.CaptureTxStart(env, tx) + t.CaptureTxStart(env, tx, from) } } diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index f3298e7599..a53a42ab1b 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -19,7 +19,6 @@ package native import ( "bytes" "encoding/json" - "fmt" "math/big" "sync/atomic" @@ -156,14 +155,8 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, } } -func (t *prestateTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction) { +func (t *prestateTracer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) { t.env = env - signer := types.MakeSigner(env.ChainConfig(), env.Context.BlockNumber, env.Context.Time) - from, err := types.Sender(signer, tx) - if err != nil { - t.Stop(fmt.Errorf("could not recover sender address: %v", err)) - return - } if tx.To() == nil { t.create = true t.to = crypto.CreateAddress(from, env.StateDB.GetNonce(from))