aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-10-23 20:04:00 +0800
committerobscuren <geffobscura@gmail.com>2014-10-23 20:04:00 +0800
commitfeef194829b07570e91873ed5d1e8cc51e8fa430 (patch)
tree7ccb57a57bc538c8ae242fcad95f96218b21862e /vm
parent91c876831a3b616beb759c30d705407845ffc3ee (diff)
downloaddexon-feef194829b07570e91873ed5d1e8cc51e8fa430.tar.gz
dexon-feef194829b07570e91873ed5d1e8cc51e8fa430.tar.zst
dexon-feef194829b07570e91873ed5d1e8cc51e8fa430.zip
Chnged to use GetOp instead & added error + checking
Diffstat (limited to 'vm')
-rw-r--r--vm/errors.go51
-rw-r--r--vm/execution.go4
-rw-r--r--vm/vm_debug.go6
3 files changed, 56 insertions, 5 deletions
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())