diff --git a/core/error.go b/core/error.go index 514cd076b..04e40646c 100644 --- a/core/error.go +++ b/core/error.go @@ -146,3 +146,19 @@ func IsKnownBlockErr(e error) bool { _, ok := e.(*KnownBlockError) return ok } + +type ValueTransferError struct { + message string +} + +func ValueTransferErr(str string, v ...interface{}) *ValueTransferError { + return &ValueTransferError{fmt.Sprintf(str, v...)} +} + +func (self *ValueTransferError) Error() string { + return self.message +} +func IsValueTransferErr(e error) bool { + _, ok := e.(*ValueTransferError) + return ok +} diff --git a/core/execution.go b/core/execution.go index f7d5a8945..4a69cce09 100644 --- a/core/execution.go +++ b/core/execution.go @@ -1,7 +1,6 @@ package core import ( - "fmt" "math/big" "time" @@ -26,7 +25,10 @@ func (self *Execution) Addr() []byte { func (self *Execution) Call(codeAddr []byte, caller vm.ContextRef) ([]byte, error) { // Retrieve the executing code - code := self.env.State().GetCode(codeAddr) + var code []byte + if self.env.State().GetStateObject(codeAddr) != nil { + code = self.env.State().GetCode(codeAddr) + } return self.exec(code, codeAddr, caller) } @@ -55,7 +57,7 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret caller.ReturnGas(self.Gas, self.price) - return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance()) + return nil, ValueTransferErr("insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance()) } snapshot := env.State().Copy() diff --git a/core/state_transition.go b/core/state_transition.go index 00e383f3f..f54acd6ee 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -3,6 +3,7 @@ package core import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" @@ -185,7 +186,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { } } if err = self.UseGas(big.NewInt(dgas)); err != nil { - return + return nil, InvalidTxError(err) } //stateCopy := self.env.State().Copy() @@ -231,10 +232,16 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { */ } - if err != nil { - self.UseGas(self.gas) + if err != nil && IsValueTransferErr(err) { + return nil, InvalidTxError(err) } + /* + if err != nil { + self.UseGas(self.gas) + } + */ + return } diff --git a/vm/vm.go b/vm/vm.go index bce8088ef..ff4692ec8 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -408,7 +408,12 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I case BALANCE: addr := stack.Pop().Bytes() - balance := statedb.GetBalance(addr) + var balance *big.Int + if statedb.GetStateObject(addr) != nil { + balance = statedb.GetBalance(addr) + } else { + balance = base + } stack.Push(balance)