This commit is contained in:
gary rong 2017-04-04 11:37:39 +00:00 committed by GitHub
commit 2d1ab662eb
6 changed files with 39 additions and 22 deletions

View file

@ -40,6 +40,7 @@ type (
account *common.Address
prev bool // whether account had already suicided
prevbalance *big.Int
prevObj *stateObject
}
// Changes to individual accounts.
@ -73,6 +74,7 @@ type (
touchChange struct {
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) {

View file

@ -29,6 +29,7 @@ func create() (*ManagedState, *account) {
db, _ := ethdb.NewMemDatabase()
statedb, _ := New(common.Hash{}, db)
ms := ManageState(statedb)
ms.StateDB.createObject(addr)
ms.StateDB.SetNonce(addr, 100)
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
return ms, ms.accounts[addr]
@ -116,6 +117,7 @@ func TestSetNonce(t *testing.T) {
}
addr[0] = 1
ms.StateDB.createObject(addr)
ms.StateDB.SetNonce(addr, 1)
if ms.GetNonce(addr) != 1 {

View file

@ -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,
prevDirty: prevDirty,
})
if c.onDirty != nil {
c.onDirty(c.Address())

View file

@ -113,6 +113,7 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
data1 := common.BytesToHash([]byte{42})
data2 := common.BytesToHash([]byte{43})
s.state.createObject(stateobjaddr)
// set initial state object value
s.state.SetState(stateobjaddr, storageaddr, data1)
// get snapshot of current state
@ -143,6 +144,8 @@ func TestSnapshot2(t *testing.T) {
stateobjaddr0 := toAddr([]byte("so0"))
stateobjaddr1 := toAddr([]byte("so1"))
state.createObject(stateobjaddr0)
state.createObject(stateobjaddr1)
var storageaddr common.Hash
data0 := common.BytesToHash([]byte{17})

View file

@ -310,7 +310,7 @@ func (self *StateDB) HasSuicided(addr common.Address) bool {
// AddBalance adds amount to the account associated with addr
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.AddBalance(amount)
}
@ -318,35 +318,35 @@ func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
// SubBalance subtracts amount from the account associated with addr
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.SubBalance(amount)
}
}
func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.SetBalance(amount)
}
}
func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.SetNonce(nonce)
}
}
func (self *StateDB) SetCode(addr common.Address, code []byte) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.SetCode(crypto.Keccak256Hash(code), code)
}
}
func (self *StateDB) SetState(addr common.Address, key common.Hash, value common.Hash) {
stateObject := self.GetOrNewStateObject(addr)
stateObject := self.getStateObject(addr)
if stateObject != nil {
stateObject.SetState(self.db, key, value)
}
@ -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)
@ -397,7 +398,7 @@ func (self *StateDB) deleteStateObject(stateObject *stateObject) {
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
// Prefer 'live' objects.
if obj := self.stateObjects[addr]; obj != nil {
if obj.deleted {
if obj.suicided {
return nil
}
return obj

View file

@ -116,7 +116,7 @@ func TestIntermediateLeaks(t *testing.T) {
}
func TestSnapshotRandom(t *testing.T) {
t.Skip("@fjl fix me please")
//t.Skip("@fjl fix me please")
config := &quick.Config{MaxCount: 1000}
err := quick.Check((*snapshotTest).run, config)
if cerr, ok := err.(*quick.CheckError); ok {