diff --git a/core/state/journal.go b/core/state/journal.go index 540ade6fb..720c821b9 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -36,7 +36,7 @@ type ( resetObjectChange struct { prev *StateObject } - deleteAccountChange struct { + suicideChange struct { account *common.Address prev bool // whether account had already suicided prevbalance *big.Int @@ -79,10 +79,10 @@ func (ch resetObjectChange) undo(s *StateDB) { s.setStateObject(ch.prev) } -func (ch deleteAccountChange) undo(s *StateDB) { +func (ch suicideChange) undo(s *StateDB) { obj := s.GetStateObject(*ch.account) if obj != nil { - obj.remove = ch.prev + obj.suicided = ch.prev obj.setBalance(ch.prevbalance) } } diff --git a/core/state/state_object.go b/core/state/state_object.go index 31ff9bcd8..a6b6028bc 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -83,10 +83,10 @@ type StateObject struct { dirtyStorage Storage // Storage entries that need to be flushed to disk // Cache flags. - // When an object is marked for deletion it will be delete from the trie - // during the "update" phase of the state transition + // When an object is marked suicided it will be delete from the trie + // during the "update" phase of the state transition. dirtyCode bool // true if the code was updated - remove bool + suicided bool deleted bool onDirty func(addr common.Address) // Callback method to mark a state object newly dirty } @@ -123,8 +123,8 @@ func (self *StateObject) setError(err error) { } } -func (self *StateObject) markForDeletion() { - self.remove = true +func (self *StateObject) markSuicided() { + self.suicided = true if self.onDirty != nil { self.onDirty(self.Address()) self.onDirty = nil @@ -266,7 +266,7 @@ func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address) stateObject.code = self.code stateObject.dirtyStorage = self.dirtyStorage.Copy() stateObject.cachedStorage = self.dirtyStorage.Copy() - stateObject.remove = self.remove + stateObject.suicided = self.suicided stateObject.dirtyCode = self.dirtyCode stateObject.deleted = self.deleted return stateObject diff --git a/core/state/state_test.go b/core/state/state_test.go index b86d8b140..f188bc271 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -156,7 +156,7 @@ func TestSnapshot2(t *testing.T) { so0.SetBalance(big.NewInt(42)) so0.SetNonce(43) so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) - so0.remove = false + so0.suicided = false so0.deleted = false state.setStateObject(so0) @@ -168,7 +168,7 @@ func TestSnapshot2(t *testing.T) { so1.SetBalance(big.NewInt(52)) so1.SetNonce(53) so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) - so1.remove = true + so1.suicided = true so1.deleted = true state.setStateObject(so1) @@ -228,8 +228,8 @@ func compareStateObjects(so0, so1 *StateObject, t *testing.T) { } } - if so0.remove != so1.remove { - t.Fatalf("Remove mismatch: have %v, want %v", so0.remove, so1.remove) + if so0.suicided != so1.suicided { + t.Fatalf("suicided mismatch: have %v, want %v", so0.suicided, so1.suicided) } if so0.deleted != so1.deleted { t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted) diff --git a/core/state/statedb.go b/core/state/statedb.go index 4f74302c3..ec9e9392f 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -275,10 +275,10 @@ func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash { return common.Hash{} } -func (self *StateDB) IsDeleted(addr common.Address) bool { +func (self *StateDB) HasSuicided(addr common.Address) bool { stateObject := self.GetStateObject(addr) if stateObject != nil { - return stateObject.remove + return stateObject.suicided } return false } @@ -322,22 +322,22 @@ func (self *StateDB) SetState(addr common.Address, key common.Hash, value common } } -// Delete marks the given account as suicided. +// Suicide marks the given account as suicided. // This clears the account balance. // // The account's state object is still available until the state is committed, -// GetStateObject will return a non-nil account after Delete. -func (self *StateDB) Delete(addr common.Address) bool { +// GetStateObject will return a non-nil account after Suicide. +func (self *StateDB) Suicide(addr common.Address) bool { stateObject := self.GetStateObject(addr) if stateObject == nil { return false } - self.journal = append(self.journal, deleteAccountChange{ + self.journal = append(self.journal, suicideChange{ account: &addr, - prev: stateObject.remove, + prev: stateObject.suicided, prevbalance: new(big.Int).Set(stateObject.Balance()), }) - stateObject.markForDeletion() + stateObject.markSuicided() stateObject.data.Balance = new(big.Int) return true } @@ -516,7 +516,7 @@ func (self *StateDB) GetRefund() *big.Int { func (s *StateDB) IntermediateRoot() common.Hash { for addr, _ := range s.stateObjectsDirty { stateObject := s.stateObjects[addr] - if stateObject.remove { + if stateObject.suicided { s.deleteStateObject(stateObject) } else { stateObject.updateRoot(s.db) @@ -542,7 +542,7 @@ func (s *StateDB) DeleteSuicides() { // If the object has been removed by a suicide // flag the object as deleted. - if stateObject.remove { + if stateObject.suicided { stateObject.deleted = true } delete(s.stateObjectsDirty, addr) @@ -575,7 +575,7 @@ func (s *StateDB) commit(dbw trie.DatabaseWriter) (root common.Hash, err error) // Commit objects to the trie. for addr, stateObject := range s.stateObjects { - if stateObject.remove { + if stateObject.suicided { // If the object has been removed, don't bother syncing it // and just mark it for deletion in the trie. s.deleteStateObject(stateObject) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e236cb8f3..5d041c740 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -202,9 +202,9 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { }, }, { - name: "Delete", + name: "Suicide", fn: func(a testAction, s *StateDB) { - s.Delete(addr) + s.Suicide(addr) }, }, { @@ -323,7 +323,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { } // Check basic accessor methods. checkeq("Exist", state.Exist(addr), checkstate.Exist(addr)) - checkeq("IsDeleted", state.IsDeleted(addr), checkstate.IsDeleted(addr)) + checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr)) checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr)) checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr)) checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) diff --git a/core/vm/environment.go b/core/vm/environment.go index 1038e69d5..a4b2ac196 100644 --- a/core/vm/environment.go +++ b/core/vm/environment.go @@ -105,9 +105,12 @@ type Database interface { GetState(common.Address, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) - Delete(common.Address) bool + Suicide(common.Address) bool + HasSuicided(common.Address) bool + + // Exist reports whether the given account exists in state. + // Notably this should also return true for suicided accounts. Exist(common.Address) bool - IsDeleted(common.Address) bool } // Account represents a contract or basic ethereum account. diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 849a8463c..79aee60d2 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -614,7 +614,7 @@ func opSuicide(instr instruction, pc *uint64, env Environment, contract *Contrac balance := env.Db().GetBalance(contract.Address()) env.Db().AddBalance(common.BigToAddress(stack.pop()), balance) - env.Db().Delete(contract.Address()) + env.Db().Suicide(contract.Address()) } // following functions are used by the instruction jump table diff --git a/core/vm/jit.go b/core/vm/jit.go index 460a68ddd..55d2e0477 100644 --- a/core/vm/jit.go +++ b/core/vm/jit.go @@ -425,7 +425,7 @@ func jitCalculateGasAndSize(env Environment, contract *Contract, instr instructi } gas.Set(g) case SUICIDE: - if !statedb.IsDeleted(contract.Address()) { + if !statedb.HasSuicided(contract.Address()) { statedb.AddRefund(params.SuicideRefundGas) } case MLOAD: diff --git a/core/vm/vm.go b/core/vm/vm.go index 5d78b4a2a..033ada21c 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -303,7 +303,7 @@ func calculateGasAndSize(env Environment, contract *Contract, caller ContractRef } gas.Set(g) case SUICIDE: - if !statedb.IsDeleted(contract.Address()) { + if !statedb.HasSuicided(contract.Address()) { statedb.AddRefund(params.SuicideRefundGas) } case MLOAD: