Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add witness costs as tracer parameter #320

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
logged bool // deferred EVMLogger should ignore already logged steps
res []byte // result of the opcode execution function
debug = in.evm.Config.Tracer != nil
witness uint64
)
// Don't move this deferred function, it's placed before the capturestate-deferred method,
// so that it get's executed _after_: the capturestate needs the stacks before
Expand All @@ -161,9 +162,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
defer func() {
if err != nil {
if !logged {
in.evm.Config.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
in.evm.Config.Tracer.CaptureState(pcCopy, op, gasCopy, cost, 0, callContext, in.returnData, in.evm.depth, err)
} else {
in.evm.Config.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err)
in.evm.Config.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, 0, callContext, in.evm.depth, err)
}
}
}()
Expand All @@ -176,14 +177,16 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
for {
if debug {
// Capture pre-execution values for tracing.
logged, pcCopy, gasCopy = false, pc, contract.Gas
logged, pcCopy, gasCopy, witness = false, pc, contract.Gas, 0
}

if in.evm.chainRules.IsPrague && !contract.IsDeployment {
// if the PC ends up in a new "chunk" of verkleized code, charge the
// associated costs.
contractAddr := contract.Address()
contract.Gas -= touchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)), in.evm.TxContext.Accesses)
w := touchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)), in.evm.TxContext.Accesses)
contract.Gas -= w
witness += w
}

// Get the operation from the jump table and validate the stack to ensure there are
Expand Down Expand Up @@ -228,14 +231,14 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
// Do tracing before memory expansion
if debug {
in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, witness, callContext, in.returnData, in.evm.depth, err)
logged = true
}
if memorySize > 0 {
mem.Resize(memorySize)
}
} else if debug {
in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err)
in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, witness, callContext, in.returnData, in.evm.depth, err)
logged = true
}
// execute the operation
Expand Down
4 changes: 2 additions & 2 deletions core/vm/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ type EVMLogger interface {
CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
CaptureExit(output []byte, gasUsed uint64, err error)
// 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)
CaptureState(pc uint64, op OpCode, gas, cost, witness uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureFault(pc uint64, op OpCode, gas, cost, witness uint64, scope *ScopeContext, depth int, err error)
}
4 changes: 2 additions & 2 deletions eth/tracers/js/goja.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
}

// CaptureState implements the Tracer interface to trace a single step of VM execution.
func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
if !t.traceStep {
return
}
Expand All @@ -275,7 +275,7 @@ func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope
}

// CaptureFault implements the Tracer interface to trace an execution fault
func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, depth int, err error) {
if t.err != nil {
return
}
Expand Down
4 changes: 2 additions & 2 deletions eth/tracers/logger/access_list_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (a *AccessListTracer) CaptureStart(env *vm.EVM, from common.Address, to com
}

// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist.
func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
stack := scope.Stack
stackData := stack.Data()
stackLen := len(stackData)
Expand All @@ -158,7 +158,7 @@ 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) CaptureFault(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, depth int, err error) {
}

func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {}
Expand Down
6 changes: 6 additions & 0 deletions eth/tracers/logger/gen_structlog.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions eth/tracers/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type StructLog struct {
Op vm.OpCode `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
WitnessCost uint64 `json:"witnessCost"`
Memory []byte `json:"memory,omitempty"`
MemorySize int `json:"memSize"`
Stack []uint256.Int `json:"stack"`
Expand All @@ -81,6 +82,7 @@ type StructLog struct {
type structLogMarshaling struct {
Gas math.HexOrDecimal64
GasCost math.HexOrDecimal64
WitnessCost math.HexOrDecimal64
Memory hexutil.Bytes
ReturnData hexutil.Bytes
OpName string `json:"opName"` // adds call to OpName() in MarshalJSON
Expand Down Expand Up @@ -147,7 +149,7 @@ func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common.
// CaptureState logs a new structured log message and pushes it out to the environment
//
// 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) {
func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
// If tracing was interrupted, set the error and stop
if l.interrupt.Load() {
return
Expand Down Expand Up @@ -208,13 +210,13 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s
copy(rdata, rData)
}
// create a new snapshot of the EVM.
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
log := StructLog{pc, op, gas, cost, witness, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
l.logs = append(l.logs, log)
}

// CaptureFault implements the EVMLogger interface to trace an execution fault
// while running an opcode.
func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, depth int, err error) {
}

// CaptureEnd is called after the call finishes to finalize the tracing.
Expand Down Expand Up @@ -360,7 +362,7 @@ func (t *mdLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Addr
}

// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
stack := scope.Stack
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)

Expand All @@ -380,7 +382,7 @@ func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope
}
}

func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, depth int, err error) {
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
}

Expand Down
7 changes: 4 additions & 3 deletions eth/tracers/logger/logger_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ func (l *JSONLogger) CaptureStart(env *vm.EVM, from, to common.Address, create b
l.env = env
}

func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost, witness uint64, scope *vm.ScopeContext, depth int, err error) {
// TODO: Add rData to this interface as well
l.CaptureState(pc, op, gas, cost, scope, nil, depth, err)
l.CaptureState(pc, op, gas, cost, witness, scope, nil, depth, err)
}

// CaptureState outputs state information on the logger.
func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
memory := scope.Memory
stack := scope.Stack

Expand All @@ -61,6 +61,7 @@ func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco
Op: op,
Gas: gas,
GasCost: cost,
WitnessCost: witness,
MemorySize: memory.Len(),
Depth: depth,
RefundCounter: l.env.StateDB.GetRefund(),
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/native/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
// skip if the previous op caused an error
if err != nil {
return
Expand Down
8 changes: 4 additions & 4 deletions eth/tracers/native/call_flat.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ func (t *flatCallTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *flatCallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
t.tracer.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
func (t *flatCallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
t.tracer.CaptureState(pc, op, gas, cost, witness, scope, rData, depth, err)
}

// CaptureFault implements the EVMLogger interface to trace an execution fault.
func (t *flatCallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
t.tracer.CaptureFault(pc, op, gas, cost, scope, depth, err)
func (t *flatCallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, depth int, err error) {
t.tracer.CaptureFault(pc, op, gas, cost, witness, scope, depth, err)
}

// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
Expand Down
8 changes: 4 additions & 4 deletions eth/tracers/native/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ func (t *muxTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
for _, t := range t.tracers {
t.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
t.CaptureState(pc, op, gas, cost, witness, scope, rData, depth, err)
}
}

// CaptureFault implements the EVMLogger interface to trace an execution fault.
func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, depth int, err error) {
for _, t := range t.tracers {
t.CaptureFault(pc, op, gas, cost, scope, depth, err)
t.CaptureFault(pc, op, gas, cost, witness, scope, depth, err)
}
}

Expand Down
4 changes: 2 additions & 2 deletions eth/tracers/native/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, witness uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
}

// CaptureFault implements the EVMLogger interface to trace an execution fault.
func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) {
func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost, _ uint64, _ *vm.ScopeContext, depth int, err error) {
}

// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/native/prestate.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost, _ uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
if err != nil {
return
}
Expand Down
Loading