From a91e6822349b6daa30a311f75b7d824739e5823d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= <peterke@gmail.com>
Date: Sat, 14 Oct 2017 15:42:48 +0300
Subject: [PATCH] core/vm: check opcode stack before readonly enforcement

---
 core/vm/interpreter.go | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 94b922c79..516438509 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -138,10 +138,10 @@ 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
+		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
 
@@ -169,22 +169,19 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
 			}
 		}
 
-		// get the operation from the jump table matching the opcode
+		// 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
 		operation := in.cfg.JumpTable[op]
-		if err := in.enforceRestrictions(op, operation, stack); err != nil {
-			return nil, err
-		}
-
-		// if the op is invalid abort the process and return an error
 		if !operation.valid {
 			return nil, fmt.Errorf("invalid opcode 0x%x", int(op))
 		}
-
-		// validate the stack and make sure there enough stack items available
-		// to perform the operation
 		if err := operation.validateStack(stack); err != nil {
 			return nil, err
 		}
+		// If the operation is valid, enforce and write restrictions
+		if err := in.enforceRestrictions(op, operation, stack); err != nil {
+			return nil, err
+		}
 
 		var memorySize uint64
 		// calculate the new memory size and expand the memory to fit
-- 
GitLab