aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/ethtest/main.go3
-rw-r--r--vm/errors.go51
-rw-r--r--vm/execution.go4
-rw-r--r--vm/vm_debug.go6
4 files changed, 58 insertions, 6 deletions
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())