diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 7f3bef3ef9..db8a940faf 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -718,7 +718,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack * } func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(memory.lastReturn)))) + stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) return nil, nil } @@ -728,7 +728,7 @@ func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, cOff = stack.pop() l = stack.pop() ) - memory.Set(mOff.Uint64(), l.Uint64(), getData(memory.lastReturn, cOff, l)) + memory.Set(mOff.Uint64(), l.Uint64(), getData(evm.interpreter.returnData, cOff, l)) evm.interpreter.intPool.put(mOff, cOff, l) return nil, nil diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index f09f477f52..256f2ad61f 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -61,6 +61,8 @@ type Interpreter struct { intPool *intPool readonly bool + // returnData contains the last call's return data + returnData []byte } // NewInterpreter returns a new instance of the Interpreter. @@ -108,8 +110,12 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack // considered a revert-and-consume-all-gas operation. No error specific checks // should be handled to reduce complexity and errors further down the in. func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret []byte, err error) { + // Increment the call depth which is restricted to 1024. in.evm.depth++ defer func() { in.evm.depth-- }() + // Reset the previous call's return data. It's unimportant to preserve the old buffer + // as every returning call will return new data anyway. + in.returnData = nil // Don't bother with the execution if there's no code. if len(contract.Code) == 0 { @@ -228,7 +234,7 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret // if the operation returned a value make sure that is also set // the last return data. if res != nil { - mem.lastReturn = ret + in.returnData = res } } return nil, nil diff --git a/core/vm/memory.go b/core/vm/memory.go index 6dbee94eff..99a84d2271 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -22,7 +22,6 @@ import "fmt" type Memory struct { store []byte lastGasCost uint64 - lastReturn []byte } func NewMemory() *Memory {