|
|
|
@ -70,7 +70,6 @@ type StructLog struct { |
|
|
|
|
Memory []byte `json:"memory"` |
|
|
|
|
MemorySize int `json:"memSize"` |
|
|
|
|
Stack []*big.Int `json:"stack"` |
|
|
|
|
ReturnStack []uint32 `json:"returnStack"` |
|
|
|
|
ReturnData []byte `json:"returnData"` |
|
|
|
|
Storage map[common.Hash]common.Hash `json:"-"` |
|
|
|
|
Depth int `json:"depth"` |
|
|
|
@ -81,7 +80,6 @@ type StructLog struct { |
|
|
|
|
// overrides for gencodec
|
|
|
|
|
type structLogMarshaling struct { |
|
|
|
|
Stack []*math.HexOrDecimal256 |
|
|
|
|
ReturnStack []math.HexOrDecimal64 |
|
|
|
|
Gas math.HexOrDecimal64 |
|
|
|
|
GasCost math.HexOrDecimal64 |
|
|
|
|
Memory hexutil.Bytes |
|
|
|
@ -110,8 +108,8 @@ func (s *StructLog) ErrorString() string { |
|
|
|
|
// if you need to retain them beyond the current call.
|
|
|
|
|
type Tracer interface { |
|
|
|
|
CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error |
|
|
|
|
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, rData []byte, contract *Contract, depth int, err error) error |
|
|
|
|
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error |
|
|
|
|
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error |
|
|
|
|
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error |
|
|
|
|
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -148,7 +146,7 @@ func (l *StructLogger) CaptureStart(from common.Address, to common.Address, crea |
|
|
|
|
// 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(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, rData []byte, contract *Contract, depth int, err error) error { |
|
|
|
|
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error { |
|
|
|
|
// check if already accumulated the specified number of logs
|
|
|
|
|
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { |
|
|
|
|
return errTraceLimitReached |
|
|
|
@ -167,11 +165,6 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui |
|
|
|
|
stck[i] = new(big.Int).Set(item.ToBig()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
var rstack []uint32 |
|
|
|
|
if !l.cfg.DisableStack && rStack != nil { |
|
|
|
|
rstck := make([]uint32, len(rStack.data)) |
|
|
|
|
copy(rstck, rStack.data) |
|
|
|
|
} |
|
|
|
|
// Copy a snapshot of the current storage to a new container
|
|
|
|
|
var storage Storage |
|
|
|
|
if !l.cfg.DisableStorage { |
|
|
|
@ -204,14 +197,14 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui |
|
|
|
|
copy(rdata, rData) |
|
|
|
|
} |
|
|
|
|
// create a new snapshot of the EVM.
|
|
|
|
|
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rstack, rdata, storage, depth, env.StateDB.GetRefund(), err} |
|
|
|
|
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, env.StateDB.GetRefund(), err} |
|
|
|
|
l.logs = append(l.logs, log) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CaptureFault implements the Tracer interface to trace an execution fault
|
|
|
|
|
// while running an opcode.
|
|
|
|
|
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error { |
|
|
|
|
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -252,12 +245,6 @@ func WriteTrace(writer io.Writer, logs []StructLog) { |
|
|
|
|
fmt.Fprintf(writer, "%08d %x\n", len(log.Stack)-i-1, math.PaddedBigBytes(log.Stack[i], 32)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if len(log.ReturnStack) > 0 { |
|
|
|
|
fmt.Fprintln(writer, "ReturnStack:") |
|
|
|
|
for i := len(log.Stack) - 1; i >= 0; i-- { |
|
|
|
|
fmt.Fprintf(writer, "%08d 0x%x (%d)\n", len(log.Stack)-i-1, log.ReturnStack[i], log.ReturnStack[i]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if len(log.Memory) > 0 { |
|
|
|
|
fmt.Fprintln(writer, "Memory:") |
|
|
|
|
fmt.Fprint(writer, hex.Dump(log.Memory)) |
|
|
|
@ -323,7 +310,7 @@ func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create b |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, rData []byte, contract *Contract, depth int, err error) error { |
|
|
|
|
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error { |
|
|
|
|
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost) |
|
|
|
|
|
|
|
|
|
if !t.cfg.DisableStack { |
|
|
|
@ -334,14 +321,6 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64 |
|
|
|
|
} |
|
|
|
|
b := fmt.Sprintf("[%v]", strings.Join(a, ",")) |
|
|
|
|
fmt.Fprintf(t.out, "%10v |", b) |
|
|
|
|
|
|
|
|
|
// format return stack
|
|
|
|
|
a = a[:0] |
|
|
|
|
for _, elem := range rStack.data { |
|
|
|
|
a = append(a, fmt.Sprintf("%2d", elem)) |
|
|
|
|
} |
|
|
|
|
b = fmt.Sprintf("[%v]", strings.Join(a, ",")) |
|
|
|
|
fmt.Fprintf(t.out, "%10v |", b) |
|
|
|
|
} |
|
|
|
|
fmt.Fprintf(t.out, "%10v |", env.StateDB.GetRefund()) |
|
|
|
|
fmt.Fprintln(t.out, "") |
|
|
|
@ -351,7 +330,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64 |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error { |
|
|
|
|
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { |
|
|
|
|
|
|
|
|
|
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) |
|
|
|
|
|
|
|
|
|