cmd/evm, core/vm: add --nomemory, --nostack to evm (#14617)
This commit is contained in:
		
							parent
							
								
									9012863ad7
								
							
						
					
					
						commit
						9a44e1035e
					
				| @ -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.
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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)) | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user