diff --git a/state/state_object.go b/state/state_object.go index 51ec95efa..ccbfea391 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -111,7 +111,7 @@ func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateOb func (self *StateObject) MarkForDeletion() { self.remove = true self.dirty = true - statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.nonce, self.balance) + statelogger.Debugf("%x: #%d %v X\n", self.Address(), self.nonce, self.balance) } func (c *StateObject) getAddr(addr []byte) *ethutil.Value { diff --git a/state/statedb.go b/state/statedb.go index 1231b4c1d..0a4156461 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -121,6 +121,7 @@ func (self *StateDB) Delete(addr []byte) bool { stateObject := self.GetOrNewStateObject(addr) if stateObject != nil { stateObject.MarkForDeletion() + stateObject.balance = new(big.Int) return true } @@ -128,6 +129,14 @@ func (self *StateDB) Delete(addr []byte) bool { return false } +func (self *StateDB) IsDeleted(addr []byte) bool { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + return stateObject.remove + } + return false +} + // // Setting, updating & deleting state object methods // diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go index cf4b018f7..2db7a0fd0 100644 --- a/tests/vm/gh_test.go +++ b/tests/vm/gh_test.go @@ -75,10 +75,18 @@ type VmTest struct { } func RunVmTest(p string, t *testing.T) { + tests := make(map[string]VmTest) helper.CreateFileTests(t, p, &tests) for name, test := range tests { + /* + vm.Debug = true + helper.Logger.SetLogLevel(4) + if name != "refund_CallToSuicideTwice" { + continue + } + */ db, _ := ethdb.NewMemDatabase() statedb := state.New(nil, db) for addr, account := range test.Pre { diff --git a/vm/vm.go b/vm/vm.go index 890a7dd2c..3647d7a5e 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -736,6 +736,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I self.Printf(" => (%x) %v", receiver.Address()[:4], balance) receiver.AddBalance(balance) + statedb.Delete(context.Address()) fallthrough @@ -905,6 +906,10 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo g = GasStorageMod } gas.Set(g) + case SUICIDE: + if !statedb.IsDeleted(context.Address()) { + statedb.Refund(self.env.Origin(), RefundSuicide) + } case MLOAD: newMemSize = calcMemSize(stack.Peek(), u256(32)) case MSTORE8: