diff --git a/core/error.go b/core/error.go index e86bacb2d..fb1eaed84 100644 --- a/core/error.go +++ b/core/error.go @@ -87,6 +87,24 @@ func IsNonceErr(err error) bool { return ok } +type InvalidTxErr struct { + Message string +} + +func (err *InvalidTxErr) Error() string { + return err.Message +} + +func InvalidTxError(err error) *InvalidTxErr { + return &InvalidTxErr{fmt.Sprintf("%v", err)} +} + +func IsInvalidTxErr(err error) bool { + _, ok := err.(*InvalidTxErr) + + return ok +} + type OutOfGasErr struct { Message string } diff --git a/core/state_transition.go b/core/state_transition.go index 751806843..00e383f3f 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -3,7 +3,6 @@ package core import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" @@ -146,7 +145,7 @@ func (self *StateTransition) preCheck() (err error) { // Pre-pay gas / Buy gas of the coinbase account if err = self.BuyGas(); err != nil { - return err + return InvalidTxError(err) } return nil @@ -167,15 +166,15 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { defer self.RefundGas() + // Transaction gas + if err = self.UseGas(vm.GasTx); err != nil { + return nil, InvalidTxError(err) + } + // Increment the nonce for the next transaction self.state.SetNonce(sender.Address(), sender.Nonce()+1) //sender.Nonce += 1 - // Transaction gas - if err = self.UseGas(vm.GasTx); err != nil { - return - } - // Pay data gas var dgas int64 for _, byt := range self.data { diff --git a/tests/helper/vm.go b/tests/helper/vm.go index 8811936fa..9ebf8f8b6 100644 --- a/tests/helper/vm.go +++ b/tests/helper/vm.go @@ -167,6 +167,7 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state. // Set pre compiled contracts vm.Precompiled = vm.PrecompiledContracts() + snapshot := statedb.Copy() coinbase := statedb.GetOrNewStateObject(caddr) coinbase.SetGasPool(ethutil.Big(env["currentGasLimit"])) @@ -175,6 +176,9 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state. st := core.NewStateTransition(vmenv, message, coinbase) vmenv.origin = keyPair.Address() ret, err := st.TransitionState() + if core.IsNonceErr(err) || core.IsInvalidTxErr(err) { + statedb.Set(snapshot) + } statedb.Update(vmenv.Gas) return ret, vmenv.logs, vmenv.Gas, err diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go index 64e858280..a3eb93616 100644 --- a/tests/vm/gh_test.go +++ b/tests/vm/gh_test.go @@ -79,10 +79,6 @@ func RunVmTest(p string, t *testing.T) { helper.CreateFileTests(t, p, &tests) for name, test := range tests { - helper.Logger.SetLogLevel(4) - if name != "callcodeToNameRegistratorAddresTooBigRight" { - continue - } db, _ := ethdb.NewMemDatabase() statedb := state.New(nil, db) for addr, account := range test.Pre { @@ -161,7 +157,7 @@ func RunVmTest(p string, t *testing.T) { if !isVmTest { if !bytes.Equal(ethutil.Hex2Bytes(test.PostStateRoot), statedb.Root()) { - //t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) + t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) } }