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
This commit is contained in:
committed by
Péter Szilágyi
parent
8f35e3086c
commit
be12392fba
@ -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
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user