From 022b11eef6d666f899b1010246cbc824472d23e1 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Sun, 19 Mar 2017 15:27:31 +0800 Subject: [PATCH] core/state: change suicide and touch journal --- core/state/journal.go | 33 +++++++++++++++++++++------------ core/state/state_object.go | 6 ++++-- core/state/statedb.go | 1 + 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 5cd41477d9..591ee05fff 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -40,6 +40,7 @@ type ( account *common.Address prev bool // whether account had already suicided prevbalance *big.Int + prevObj *stateObject } // Changes to individual accounts. @@ -71,8 +72,9 @@ type ( hash common.Hash } touchChange struct { - account *common.Address - prev bool + account *common.Address + prev bool + prevDirty bool } ) @@ -86,36 +88,43 @@ func (ch resetObjectChange) undo(s *StateDB) { } func (ch suicideChange) undo(s *StateDB) { - obj := s.getStateObject(*ch.account) - if obj != nil { - obj.suicided = ch.prev - obj.setBalance(ch.prevbalance) + if !ch.prev { + ch.prevObj.suicided = ch.prev + ch.prevObj.setBalance(ch.prevbalance) + s.setStateObject(ch.prevObj) } } var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") func (ch touchChange) undo(s *StateDB) { - if !ch.prev && *ch.account != ripemd { - delete(s.stateObjects, *ch.account) + if !ch.prev && !ch.prevDirty && *ch.account != ripemd { delete(s.stateObjectsDirty, *ch.account) } } func (ch balanceChange) undo(s *StateDB) { - s.getStateObject(*ch.account).setBalance(ch.prev) + if obj := s.getStateObject(*ch.account); obj != nil { + obj.setBalance(ch.prev) + } } func (ch nonceChange) undo(s *StateDB) { - s.getStateObject(*ch.account).setNonce(ch.prev) + if obj := s.getStateObject(*ch.account); obj != nil { + obj.setNonce(ch.prev) + } } func (ch codeChange) undo(s *StateDB) { - s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) + if obj := s.getStateObject(*ch.account); obj != nil { + obj.setCode(common.BytesToHash(ch.prevhash), ch.prevcode) + } } func (ch storageChange) undo(s *StateDB) { - s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) + if obj := s.getStateObject(*ch.account); obj != nil { + obj.setState(ch.key, ch.prevalue) + } } func (ch refundChange) undo(s *StateDB) { diff --git a/core/state/state_object.go b/core/state/state_object.go index 7f994ee6d6..9c9b1e9164 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -136,9 +136,11 @@ func (self *stateObject) markSuicided() { } func (c *stateObject) touch() { + prevDirty := c.onDirty == nil c.db.journal = append(c.db.journal, touchChange{ - account: &c.address, - prev: c.touched, + account: &c.address, + prev: c.touched, + prevDirty: prevDirty, }) if c.onDirty != nil { c.onDirty(c.Address()) diff --git a/core/state/statedb.go b/core/state/statedb.go index a21922fb59..e9ebfedea1 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -366,6 +366,7 @@ func (self *StateDB) Suicide(addr common.Address) bool { account: &addr, prev: stateObject.suicided, prevbalance: new(big.Int).Set(stateObject.Balance()), + prevObj: stateObject, }) stateObject.markSuicided() stateObject.data.Balance = new(big.Int)