Browse Source

core/vm: standard vm traces (#15035)

cdetrio 8 năm trước cách đây
mục cha
commit
673007d7ae
2 tập tin đã thay đổi với 20 bổ sung4 xóa
  1. 1 1
      cmd/evm/json_logger.go
  2. 19 3
      core/vm/interpreter.go

+ 1 - 1
cmd/evm/json_logger.go

@@ -40,7 +40,7 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos
 	log := vm.StructLog{
 		Pc:         pc,
 		Op:         op,
-		Gas:        gas + cost,
+		Gas:        gas,
 		GasCost:    cost,
 		MemorySize: memory.Len(),
 		Storage:    nil,

+ 19 - 3
core/vm/interpreter.go

@@ -137,12 +137,17 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
 		// to be uint256. Practically much less so feasible.
 		pc   = uint64(0) // program counter
 		cost uint64
+		// copies used by tracer
+		stackCopy = newstack() // stackCopy needed for Tracer since stack is mutated by 63/64 gas rule 
+		pcCopy uint64 // needed for the deferred Tracer
+		gasCopy uint64 // for Tracer to log gas remaining before execution
+		logged bool // deferred Tracer should ignore already logged steps
 	)
 	contract.Input = input
 
 	defer func() {
-		if err != nil && in.cfg.Debug {
-			in.cfg.Tracer.CaptureState(in.evm, pc, op, contract.Gas, cost, mem, stack, contract, in.evm.depth, err)
+		if err != nil && !logged && in.cfg.Debug {
+			in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stackCopy, contract, in.evm.depth, err)
 		}
 	}()
 
@@ -154,6 +159,16 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
 		// Get the memory location of pc
 		op = contract.GetOp(pc)
 
+		if in.cfg.Debug {
+			logged = false
+			pcCopy = uint64(pc)
+			gasCopy = uint64(contract.Gas)
+			stackCopy = newstack()
+			for _, val := range stack.data {
+				stackCopy.push(val)
+			}
+		}
+
 		// get the operation from the jump table matching the opcode
 		operation := in.cfg.JumpTable[op]
 		if err := in.enforceRestrictions(op, operation, stack); err != nil {
@@ -199,7 +214,8 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
 		}
 
 		if in.cfg.Debug {
-			in.cfg.Tracer.CaptureState(in.evm, pc, op, contract.Gas, cost, mem, stack, contract, in.evm.depth, err)
+			in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stackCopy, contract, in.evm.depth, err)
+			logged = true
 		}
 
 		// execute the operation