diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-11-29 03:05:49 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2017-11-29 03:05:49 +0800 |
commit | be12392fbad9f4a861130a347e6bcf07a5c34974 (patch) | |
tree | 266aa5788b2dd154509a5de7eecdf24db0c95fc6 /core/vm/interpreter.go | |
parent | 8f35e3086cbea24839c5435b1cebe85a438b42d3 (diff) | |
download | dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar.gz dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar.bz2 dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar.lz dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar.xz dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.tar.zst dexon-be12392fbad9f4a861130a347e6bcf07a5c34974.zip |
core/vm: track 63/64 call gas off stack (#15563)
* core/vm: track 63/64 call gas off stack
Gas calculations in gasCall* relayed the available gas for calls by
replacing it on the stack. This lead to inconsistent traces, which we
papered over by copying the pre-execution stack in trace mode.
This change relays available gas using a temporary variable, off the
stack, and allows removing the weird copy.
* core/vm: remove stackCopy
* core/vm: pop call gas into pool
* core/vm: to -> addr
Diffstat (limited to 'core/vm/interpreter.go')
-rw-r--r-- | core/vm/interpreter.go | 28 |
1 files changed, 10 insertions, 18 deletions
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index ea5468f90..ac6000f97 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -138,16 +138,15 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret 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 + 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 && !logged && in.cfg.Debug { - in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stackCopy, contract, in.evm.depth, err) + in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) } }() @@ -156,21 +155,14 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret // the execution of one of the operations or until the done flag is set by the // parent context. for atomic.LoadInt32(&in.evm.abort) == 0 { - // Get the memory location of pc - op = contract.GetOp(pc) - if in.cfg.Debug { - logged = false - pcCopy = pc - gasCopy = contract.Gas - stackCopy = newstack() - for _, val := range stack.data { - stackCopy.push(val) - } + // Capture pre-execution values for tracing. + logged, pcCopy, gasCopy = false, pc, contract.Gas } - // Get the operation from the jump table matching the opcode and validate the - // stack and make sure there enough stack items available to perform the operation + // Get the operation from the jump table and validate the stack to ensure there are + // enough stack items available to perform the operation. + op = contract.GetOp(pc) operation := in.cfg.JumpTable[op] if !operation.valid { return nil, fmt.Errorf("invalid opcode 0x%x", int(op)) @@ -211,7 +203,7 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret } if in.cfg.Debug { - in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stackCopy, contract, in.evm.depth, err) + in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) logged = true } |