core/state: change suicide and touch journal

This commit is contained in:
rjl493456442 2017-03-19 15:27:31 +08:00
parent e69534984a
commit 022b11eef6
3 changed files with 26 additions and 14 deletions

View file

@ -40,6 +40,7 @@ type (
account *common.Address account *common.Address
prev bool // whether account had already suicided prev bool // whether account had already suicided
prevbalance *big.Int prevbalance *big.Int
prevObj *stateObject
} }
// Changes to individual accounts. // Changes to individual accounts.
@ -71,8 +72,9 @@ type (
hash common.Hash hash common.Hash
} }
touchChange struct { touchChange struct {
account *common.Address account *common.Address
prev bool prev bool
prevDirty bool
} }
) )
@ -86,36 +88,43 @@ func (ch resetObjectChange) undo(s *StateDB) {
} }
func (ch suicideChange) undo(s *StateDB) { func (ch suicideChange) undo(s *StateDB) {
obj := s.getStateObject(*ch.account) if !ch.prev {
if obj != nil { ch.prevObj.suicided = ch.prev
obj.suicided = ch.prev ch.prevObj.setBalance(ch.prevbalance)
obj.setBalance(ch.prevbalance) s.setStateObject(ch.prevObj)
} }
} }
var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") var ripemd = common.HexToAddress("0000000000000000000000000000000000000003")
func (ch touchChange) undo(s *StateDB) { func (ch touchChange) undo(s *StateDB) {
if !ch.prev && *ch.account != ripemd { if !ch.prev && !ch.prevDirty && *ch.account != ripemd {
delete(s.stateObjects, *ch.account)
delete(s.stateObjectsDirty, *ch.account) delete(s.stateObjectsDirty, *ch.account)
} }
} }
func (ch balanceChange) undo(s *StateDB) { 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) { 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) { 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) { 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) { func (ch refundChange) undo(s *StateDB) {

View file

@ -136,9 +136,11 @@ func (self *stateObject) markSuicided() {
} }
func (c *stateObject) touch() { func (c *stateObject) touch() {
prevDirty := c.onDirty == nil
c.db.journal = append(c.db.journal, touchChange{ c.db.journal = append(c.db.journal, touchChange{
account: &c.address, account: &c.address,
prev: c.touched, prev: c.touched,
prevDirty: prevDirty,
}) })
if c.onDirty != nil { if c.onDirty != nil {
c.onDirty(c.Address()) c.onDirty(c.Address())

View file

@ -366,6 +366,7 @@ func (self *StateDB) Suicide(addr common.Address) bool {
account: &addr, account: &addr,
prev: stateObject.suicided, prev: stateObject.suicided,
prevbalance: new(big.Int).Set(stateObject.Balance()), prevbalance: new(big.Int).Set(stateObject.Balance()),
prevObj: stateObject,
}) })
stateObject.markSuicided() stateObject.markSuicided()
stateObject.data.Balance = new(big.Int) stateObject.data.Balance = new(big.Int)