diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 505aef4127..aaa12e4361 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -247,7 +247,9 @@ func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( if evm.Config.EnablePreimageRecording { evm.StateDB.AddPreimage(interpreter.hasherBuf, data) } - + if interpreter.evm.Config.Tracer != nil { + interpreter.evm.Config.Tracer.CaptureKeccakPreimage(common.BytesToHash(interpreter.hasherBuf[:]), data) + } size.SetBytes(interpreter.hasherBuf[:]) return nil, nil } diff --git a/core/vm/logger.go b/core/vm/logger.go index 2667908a84..d4b91ccc71 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -40,4 +40,5 @@ type EVMLogger interface { // Opcode level CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) + CaptureKeccakPreimage(hash common.Hash, data []byte) } diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index f3d63df8ed..ac8822e98f 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -286,6 +286,9 @@ func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope } } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (t *jsTracer) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + // CaptureEnd is called after the call finishes to finalize the tracing. func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { t.ctx["output"] = t.vm.ToValue(output) diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index 766ee4e4b9..c6a7bfddbe 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -161,6 +161,8 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6 func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { } +func (*AccessListTracer) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {} func (*AccessListTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index c7f171c5bd..0c9ce9aec1 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -217,6 +217,9 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (l *StructLogger) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + // CaptureEnd is called after the call finishes to finalize the tracing. func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { l.output = output @@ -384,6 +387,8 @@ func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) } +func (t *mdLogger) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { fmt.Fprintf(t.out, "\nOutput: `%#x`\nConsumed gas: `%d`\nError: `%v`\n", output, gasUsed, err) diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index a2cb4cd9fc..91def6f389 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -78,6 +78,9 @@ func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco l.encoder.Encode(log) } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (l *JSONLogger) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + // CaptureEnd is triggered at end of execution. func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { type endLog struct { diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index 8612c23387..ca5d2e6aec 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -108,6 +108,7 @@ type flatCallResultMarshaling struct { // flatCallTracer reports call frame information of a tx in a flat format, i.e. // as opposed to the nested format of `callTracer`. type flatCallTracer struct { + noopTracer tracer *callTracer config flatCallTracerConfig ctx *tracers.Context // Holds tracer context data diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index db8ddd6438..16ae47e5fa 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -86,6 +86,13 @@ func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scop } } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (t *muxTracer) CaptureKeccakPreimage(hash common.Hash, data []byte) { + for _, t := range t.tracers { + t.CaptureKeccakPreimage(hash, data) + } +} + // CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). func (t *muxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { for _, t := range t.tracers { diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index 3beecd8abf..f60f3873a0 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -54,6 +54,9 @@ func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) { } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (t *noopTracer) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + // CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). func (t *noopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } diff --git a/eth/tracers/printer.go b/eth/tracers/printer.go index 18608d6484..78f2c8b63d 100644 --- a/eth/tracers/printer.go +++ b/eth/tracers/printer.go @@ -35,6 +35,9 @@ func (p *Printer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm. fmt.Printf("CaptureFault: pc=%v, op=%v, gas=%v, cost=%v, depth=%v, err=%v\n", pc, op, gas, cost, depth, err) } +// CaptureKeccakPreimage is called during the KECCAK256 opcode. +func (p *Printer) CaptureKeccakPreimage(hash common.Hash, data []byte) {} + // CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). func (p *Printer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { fmt.Printf("CaptureEnter: typ=%v, from=%v, to=%v, input=%v, gas=%v, value=%v\n", typ, from, to, input, gas, value)