From feef194829b07570e91873ed5d1e8cc51e8fa430 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Oct 2014 14:04:00 +0200 Subject: Chnged to use GetOp instead & added error + checking --- vm/errors.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ vm/execution.go | 4 ++-- vm/vm_debug.go | 6 +++--- 3 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 vm/errors.go (limited to 'vm') 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()) -- cgit v1.2.3