cmd/evm, core/vm: add --nomemory, --nostack to evm (#14617)
This commit is contained in:
		
				
					committed by
					
						
						Felix Lange
					
				
			
			
				
	
			
			
			
						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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user