Эх сурвалжийг харах

cmd/evm, core/vm: add --nomemory, --nostack to evm (#14617)

Martin Holst Swende 8 жил өмнө
parent
commit
9a44e1035e

+ 20 - 13
cmd/evm/json_logger.go

@@ -28,25 +28,32 @@ import (
 
 type JSONLogger struct {
 	encoder *json.Encoder
+	cfg     *vm.LogConfig
 }
 
-func NewJSONLogger(writer io.Writer) *JSONLogger {
-	return &JSONLogger{json.NewEncoder(writer)}
+func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger {
+	return &JSONLogger{json.NewEncoder(writer), cfg}
 }
 
 // CaptureState outputs state information on the logger.
 func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
-	return l.encoder.Encode(vm.StructLog{
-		Pc:      pc,
-		Op:      op,
-		Gas:     gas + cost,
-		GasCost: cost,
-		Memory:  memory.Data(),
-		Stack:   stack.Data(),
-		Storage: nil,
-		Depth:   depth,
-		Err:     err,
-	})
+	log := vm.StructLog{
+		Pc:         pc,
+		Op:         op,
+		Gas:        gas + cost,
+		GasCost:    cost,
+		MemorySize: memory.Len(),
+		Storage:    nil,
+		Depth:      depth,
+		Err:        err,
+	}
+	if !l.cfg.DisableMemory {
+		log.Memory = memory.Data()
+	}
+	if !l.cfg.DisableStack {
+		log.Stack = stack.Data()
+	}
+	return l.encoder.Encode(log)
 }
 
 // CaptureEnd is triggered at end of execution.

+ 10 - 0
cmd/evm/main.go

@@ -102,6 +102,14 @@ var (
 		Name:  "sender",
 		Usage: "The transaction origin",
 	}
+	DisableMemoryFlag = cli.BoolFlag{
+		Name:  "nomemory",
+		Usage: "disable memory output",
+	}
+	DisableStackFlag = cli.BoolFlag{
+		Name:  "nostack",
+		Usage: "disable stack output",
+	}
 )
 
 func init() {
@@ -123,6 +131,8 @@ func init() {
 		GenesisFlag,
 		MachineFlag,
 		SenderFlag,
+		DisableMemoryFlag,
+		DisableStackFlag,
 	}
 	app.Commands = []cli.Command{
 		compileCommand,

+ 7 - 3
cmd/evm/runner.go

@@ -73,6 +73,10 @@ func runCmd(ctx *cli.Context) error {
 	glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
 	glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name)))
 	log.Root().SetHandler(glogger)
+	logconfig := &vm.LogConfig{
+		DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name),
+		DisableStack:  ctx.GlobalBool(DisableStackFlag.Name),
+	}
 
 	var (
 		tracer      vm.Tracer
@@ -82,12 +86,12 @@ func runCmd(ctx *cli.Context) error {
 		sender      = common.StringToAddress("sender")
 	)
 	if ctx.GlobalBool(MachineFlag.Name) {
-		tracer = NewJSONLogger(os.Stdout)
+		tracer = NewJSONLogger(logconfig, os.Stdout)
 	} else if ctx.GlobalBool(DebugFlag.Name) {
-		debugLogger = vm.NewStructLogger(nil)
+		debugLogger = vm.NewStructLogger(logconfig)
 		tracer = debugLogger
 	} else {
-		debugLogger = vm.NewStructLogger(nil)
+		debugLogger = vm.NewStructLogger(logconfig)
 	}
 	if ctx.GlobalString(GenesisFlag.Name) != "" {
 		gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))

+ 15 - 11
core/vm/gen_structlog.go

@@ -18,12 +18,12 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
 		Gas        math.HexOrDecimal64         `json:"gas"`
 		GasCost    math.HexOrDecimal64         `json:"gasCost"`
 		Memory     hexutil.Bytes               `json:"memory"`
+		MemorySize int                         `json:"memSize"`
 		Stack      []*math.HexOrDecimal256     `json:"stack"`
 		Storage    map[common.Hash]common.Hash `json:"-"`
 		Depth      int                         `json:"depth"`
 		Err        error                       `json:"error"`
 		OpName     string                      `json:"opName"`
-		MemorySize int                         `json:"memSize"`
 	}
 	var enc StructLog
 	enc.Pc = s.Pc
@@ -31,6 +31,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
 	enc.Gas = math.HexOrDecimal64(s.Gas)
 	enc.GasCost = math.HexOrDecimal64(s.GasCost)
 	enc.Memory = s.Memory
+	enc.MemorySize = s.MemorySize
 	if s.Stack != nil {
 		enc.Stack = make([]*math.HexOrDecimal256, len(s.Stack))
 		for k, v := range s.Stack {
@@ -41,21 +42,21 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
 	enc.Depth = s.Depth
 	enc.Err = s.Err
 	enc.OpName = s.OpName()
-	enc.MemorySize = s.MemorySize()
 	return json.Marshal(&enc)
 }
 
 func (s *StructLog) UnmarshalJSON(input []byte) error {
 	type StructLog struct {
-		Pc      *uint64                     `json:"pc"`
-		Op      *OpCode                     `json:"op"`
-		Gas     *math.HexOrDecimal64        `json:"gas"`
-		GasCost *math.HexOrDecimal64        `json:"gasCost"`
-		Memory  hexutil.Bytes               `json:"memory"`
-		Stack   []*math.HexOrDecimal256     `json:"stack"`
-		Storage map[common.Hash]common.Hash `json:"-"`
-		Depth   *int                        `json:"depth"`
-		Err     *error                      `json:"error"`
+		Pc         *uint64                     `json:"pc"`
+		Op         *OpCode                     `json:"op"`
+		Gas        *math.HexOrDecimal64        `json:"gas"`
+		GasCost    *math.HexOrDecimal64        `json:"gasCost"`
+		Memory     hexutil.Bytes               `json:"memory"`
+		MemorySize *int                        `json:"memSize"`
+		Stack      []*math.HexOrDecimal256     `json:"stack"`
+		Storage    map[common.Hash]common.Hash `json:"-"`
+		Depth      *int                        `json:"depth"`
+		Err        *error                      `json:"error"`
 	}
 	var dec StructLog
 	if err := json.Unmarshal(input, &dec); err != nil {
@@ -76,6 +77,9 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
 	if dec.Memory != nil {
 		s.Memory = dec.Memory
 	}
+	if dec.MemorySize != nil {
+		s.MemorySize = *dec.MemorySize
+	}
 	if dec.Stack != nil {
 		s.Stack = make([]*big.Int, len(dec.Stack))
 		for k, v := range dec.Stack {

+ 16 - 20
core/vm/logger.go

@@ -54,35 +54,31 @@ type LogConfig struct {
 // StructLog is emitted to the EVM each cycle and lists information about the current internal state
 // prior to the execution of the statement.
 type StructLog struct {
-	Pc      uint64                      `json:"pc"`
-	Op      OpCode                      `json:"op"`
-	Gas     uint64                      `json:"gas"`
-	GasCost uint64                      `json:"gasCost"`
-	Memory  []byte                      `json:"memory"`
-	Stack   []*big.Int                  `json:"stack"`
-	Storage map[common.Hash]common.Hash `json:"-"`
-	Depth   int                         `json:"depth"`
-	Err     error                       `json:"error"`
+	Pc         uint64                      `json:"pc"`
+	Op         OpCode                      `json:"op"`
+	Gas        uint64                      `json:"gas"`
+	GasCost    uint64                      `json:"gasCost"`
+	Memory     []byte                      `json:"memory"`
+	MemorySize int                         `json:"memSize"`
+	Stack      []*big.Int                  `json:"stack"`
+	Storage    map[common.Hash]common.Hash `json:"-"`
+	Depth      int                         `json:"depth"`
+	Err        error                       `json:"error"`
 }
 
 // overrides for gencodec
 type structLogMarshaling struct {
-	Stack      []*math.HexOrDecimal256
-	Gas        math.HexOrDecimal64
-	GasCost    math.HexOrDecimal64
-	Memory     hexutil.Bytes
-	OpName     string `json:"opName"`
-	MemorySize int    `json:"memSize"`
+	Stack   []*math.HexOrDecimal256
+	Gas     math.HexOrDecimal64
+	GasCost math.HexOrDecimal64
+	Memory  hexutil.Bytes
+	OpName  string `json:"opName"`
 }
 
 func (s *StructLog) OpName() string {
 	return s.Op.String()
 }
 
-func (s *StructLog) MemorySize() int {
-	return len(s.Memory)
-}
-
 // Tracer is used to collect execution traces from an EVM transaction
 // execution. CaptureState is called for each step of the VM with the
 // current VM state.
@@ -181,7 +177,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
 		}
 	}
 	// create a new snaptshot of the EVM.
-	log := StructLog{pc, op, gas, cost, mem, stck, storage, env.depth, err}
+	log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, err}
 
 	l.logs = append(l.logs, log)
 	return nil