mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
cmd/evm: better json output, add result to json
This commit is contained in:
parent
c437b70c97
commit
567f69539e
3 changed files with 79 additions and 7 deletions
|
|
@ -86,8 +86,9 @@ func runCmd(ctx *cli.Context) error {
|
||||||
} else if ctx.GlobalBool(DebugFlag.Name) {
|
} else if ctx.GlobalBool(DebugFlag.Name) {
|
||||||
debugLogger = vm.NewStructLogger(nil)
|
debugLogger = vm.NewStructLogger(nil)
|
||||||
tracer = debugLogger
|
tracer = debugLogger
|
||||||
|
} else {
|
||||||
|
debugLogger = vm.NewStructLogger(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.GlobalString(GenesisFlag.Name) != "" {
|
if ctx.GlobalString(GenesisFlag.Name) != "" {
|
||||||
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
|
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
|
||||||
_, statedb = gen.ToBlock()
|
_, statedb = gen.ToBlock()
|
||||||
|
|
@ -216,11 +217,14 @@ GC calls: %d
|
||||||
|
|
||||||
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC)
|
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC)
|
||||||
}
|
}
|
||||||
|
if tracer != nil {
|
||||||
fmt.Printf("0x%x", ret)
|
tracer.CaptureEnd(ret, 0, execTime)
|
||||||
if err != nil {
|
} else {
|
||||||
fmt.Printf(" error: %v", err)
|
fmt.Printf("0x%x\n", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" error: %v\n", err)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
|
|
@ -61,6 +62,50 @@ type StructLog struct {
|
||||||
Depth int
|
Depth int
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
type StructLogJsonOut struct {
|
||||||
|
Pc uint64 `json:"pc"`
|
||||||
|
Op OpCode `json:"op"`
|
||||||
|
OpName string `json:"opName"`
|
||||||
|
Gas math.HexOrDecimal64 `json:"gas"`
|
||||||
|
GasCost math.HexOrDecimal64 `json:"gasCost"`
|
||||||
|
Memory string `json:"memory"`
|
||||||
|
Stack hexArray `json:"stack"`
|
||||||
|
//Storage map[common.Hash]common.Hash `json:"storage"`
|
||||||
|
Depth int `json:"depth"`
|
||||||
|
//Err error
|
||||||
|
}
|
||||||
|
type hexArray []*big.Int
|
||||||
|
|
||||||
|
// MarshalJSON encodes the memory as 32-byte hex strings instead of bigints
|
||||||
|
func (a hexArray) MarshalJSON() ([]byte, error) {
|
||||||
|
|
||||||
|
if items := ([]*big.Int)(a); len(items) > 0 {
|
||||||
|
hexitems := make([]*math.HexOrDecimal256, len(items))
|
||||||
|
for i, item := range items {
|
||||||
|
x := math.HexOrDecimal256(*item)
|
||||||
|
hexitems[i] = &x
|
||||||
|
}
|
||||||
|
return json.Marshal(hexitems)
|
||||||
|
}
|
||||||
|
return []byte("[]"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON encodes StructLog for json output
|
||||||
|
func (s StructLog) MarshalJSON() ([]byte, error) {
|
||||||
|
var enc StructLogJsonOut
|
||||||
|
enc.Pc = s.Pc
|
||||||
|
enc.Op = s.Op
|
||||||
|
enc.OpName = s.Op.String()
|
||||||
|
enc.Gas = math.HexOrDecimal64(s.Gas)
|
||||||
|
enc.GasCost = math.HexOrDecimal64(s.GasCost)
|
||||||
|
//enc.Memory = fmt.Sprintf("0x%v", len(common.Bytes2Hex(s.Memory))/2)
|
||||||
|
enc.Memory = fmt.Sprintf("%v bytes", len(s.Memory))
|
||||||
|
|
||||||
|
enc.Stack = s.Stack
|
||||||
|
//enc.Storage = s.Storage
|
||||||
|
enc.Depth = s.Depth
|
||||||
|
return json.Marshal(&enc)
|
||||||
|
}
|
||||||
|
|
||||||
// Tracer is used to collect execution traces from an EVM transaction
|
// Tracer is used to collect execution traces from an EVM transaction
|
||||||
// execution. CaptureState is called for each step of the VM with the
|
// execution. CaptureState is called for each step of the VM with the
|
||||||
|
|
@ -69,6 +114,7 @@ type StructLog struct {
|
||||||
// if you need to retain them beyond the current call.
|
// if you need to retain them beyond the current call.
|
||||||
type Tracer interface {
|
type Tracer interface {
|
||||||
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
|
CaptureState(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) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructLogger is an EVM state logger and implements Tracer.
|
// StructLogger is an EVM state logger and implements Tracer.
|
||||||
|
|
@ -110,9 +156,20 @@ func NewJSONLogger(writer io.Writer) *JSONLogger {
|
||||||
|
|
||||||
// CaptureState outputs state information on the logger
|
// CaptureState outputs state information on the logger
|
||||||
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
|
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
|
||||||
log := StructLog{pc, op, gas, cost, memory.Data(), stack.Data(), nil, env.depth, err}
|
log := StructLog{pc, op, gas + cost, cost, memory.Data(), stack.Data(), nil, env.depth, err}
|
||||||
return l.encoder.Encode(log)
|
return l.encoder.Encode(log)
|
||||||
}
|
}
|
||||||
|
func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
||||||
|
type endLog struct {
|
||||||
|
Output string `json:"output"`
|
||||||
|
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
|
||||||
|
Time time.Duration `json:"time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
log := endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t}
|
||||||
|
return l.encoder.Encode(log)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// CaptureState logs a new structured log message and pushes it out to the environment
|
// CaptureState logs a new structured log message and pushes it out to the environment
|
||||||
//
|
//
|
||||||
|
|
@ -184,6 +241,10 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||||
l.logs = append(l.logs, log)
|
l.logs = append(l.logs, log)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
||||||
|
fmt.Printf("0x%x", output)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// StructLogs returns a list of captured log entries
|
// StructLogs returns a list of captured log entries
|
||||||
func (l *StructLogger) StructLogs() []StructLog {
|
func (l *StructLogger) StructLogs() []StructLog {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -344,6 +345,12 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CaptureEnd is called after the call finishes
|
||||||
|
func (jst *JavascriptTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
||||||
|
//TODO! @Arachnid please figure out of there's anything we can use this method for
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
|
// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
|
||||||
func (jst *JavascriptTracer) GetResult() (result interface{}, err error) {
|
func (jst *JavascriptTracer) GetResult() (result interface{}, err error) {
|
||||||
if jst.err != nil {
|
if jst.err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue