From feef194829b07570e91873ed5d1e8cc51e8fa430 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Thu, 23 Oct 2014 14:04:00 +0200
Subject: [PATCH] Chnged to use GetOp instead & added error + checking

---
 tests/ethtest/main.go |  3 ++-
 vm/errors.go          | 51 +++++++++++++++++++++++++++++++++++++++++++
 vm/execution.go       |  4 ++--
 vm/vm_debug.go        |  6 ++---
 4 files changed, 58 insertions(+), 6 deletions(-)
 create mode 100644 vm/errors.go

diff --git a/tests/ethtest/main.go b/tests/ethtest/main.go
index e19892557..1f2a15e1c 100644
--- a/tests/ethtest/main.go
+++ b/tests/ethtest/main.go
@@ -63,7 +63,7 @@ func RunVmTest(js string) (failed int) {
 		// When an error is returned it doesn't always mean the tests fails.
 		// Have to come up with some conditional failing mechanism.
 		if err != nil {
-			helper.Log.Infoln(err)
+			log.Println(err)
 		}
 
 		rexp := helper.FromHex(test.Out)
@@ -96,6 +96,7 @@ func RunVmTest(js string) (failed int) {
 }
 
 func main() {
+	helper.Logger.SetLogLevel(5)
 	if len(os.Args) == 1 {
 		log.Fatalln("no json supplied")
 	}
diff --git a/vm/errors.go b/vm/errors.go
new file mode 100644
index 000000000..ab011bd62
--- /dev/null
+++ b/vm/errors.go
@@ -0,0 +1,51 @@
+package vm
+
+import (
+	"fmt"
+	"math/big"
+)
+
+type OutOfGasError struct {
+	req, has *big.Int
+}
+
+func OOG(req, has *big.Int) OutOfGasError {
+	return OutOfGasError{req, has}
+}
+
+func (self OutOfGasError) Error() string {
+	return fmt.Sprintf("out of gas! require %v, have %v", self.req, self.has)
+}
+
+func IsOOGErr(err error) bool {
+	_, ok := err.(OutOfGasError)
+	return ok
+}
+
+type StackError struct {
+	req, has int
+}
+
+func StackErr(req, has int) StackError {
+	return StackError{req, has}
+}
+
+func (self StackError) Error() string {
+	return fmt.Sprintf("stack error! require %v, have %v", self.req, self.has)
+}
+
+func IsStack(err error) bool {
+	_, ok := err.(StackError)
+	return ok
+}
+
+type DepthError struct{}
+
+func (self DepthError) Error() string {
+	return fmt.Sprintf("Max call depth exceeded (%d)", MaxCallDepth)
+}
+
+func IsDepthErr(err error) bool {
+	_, ok := err.(DepthError)
+	return ok
+}
diff --git a/vm/execution.go b/vm/execution.go
index bd174d64e..c518c4b57 100644
--- a/vm/execution.go
+++ b/vm/execution.go
@@ -36,7 +36,7 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte,
 
 	snapshot := env.State().Copy()
 	defer func() {
-		if err != nil {
+		if IsDepthErr(err) || IsOOGErr(err) {
 			env.State().Set(snapshot)
 		}
 	}()
@@ -76,7 +76,7 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte,
 			if self.vm.Depth() == MaxCallDepth {
 				c.UseGas(self.Gas)
 
-				return c.Return(nil), fmt.Errorf("Max call depth exceeded (%d)", MaxCallDepth)
+				return c.Return(nil), DepthError{}
 			}
 
 			// Executer the closure and get the return value (if any)
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index fe004046c..b44604121 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -107,7 +107,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 		step++
 		// Get the memory location of pc
-		op = OpCode(closure.Get(pc).Uint())
+		op = closure.GetOp(int(pc.Uint64()))
 
 		// XXX Leave this Println intact. Don't change this to the log system.
 		// Used for creating diffs between implementations
@@ -246,11 +246,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 		if !closure.UseGas(gas) {
 			self.Endl()
 
-			err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
+			tmp := new(big.Int).Set(closure.Gas)
 
 			closure.UseGas(closure.Gas)
 
-			return closure.Return(nil), err
+			return closure.Return(nil), OOG(gas, tmp)
 		}
 
 		mem.Resize(newMemSize.Uint64())
-- 
GitLab