mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
Merge 71cef7ad21 into e50a5b7771
This commit is contained in:
commit
2d1ab662eb
6 changed files with 39 additions and 22 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ func create() (*ManagedState, *account) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb, _ := New(common.Hash{}, db)
|
statedb, _ := New(common.Hash{}, db)
|
||||||
ms := ManageState(statedb)
|
ms := ManageState(statedb)
|
||||||
|
ms.StateDB.createObject(addr)
|
||||||
ms.StateDB.SetNonce(addr, 100)
|
ms.StateDB.SetNonce(addr, 100)
|
||||||
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
|
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
|
||||||
return ms, ms.accounts[addr]
|
return ms, ms.accounts[addr]
|
||||||
|
|
@ -116,6 +117,7 @@ func TestSetNonce(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addr[0] = 1
|
addr[0] = 1
|
||||||
|
ms.StateDB.createObject(addr)
|
||||||
ms.StateDB.SetNonce(addr, 1)
|
ms.StateDB.SetNonce(addr, 1)
|
||||||
|
|
||||||
if ms.GetNonce(addr) != 1 {
|
if ms.GetNonce(addr) != 1 {
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
|
||||||
data1 := common.BytesToHash([]byte{42})
|
data1 := common.BytesToHash([]byte{42})
|
||||||
data2 := common.BytesToHash([]byte{43})
|
data2 := common.BytesToHash([]byte{43})
|
||||||
|
|
||||||
|
s.state.createObject(stateobjaddr)
|
||||||
// set initial state object value
|
// set initial state object value
|
||||||
s.state.SetState(stateobjaddr, storageaddr, data1)
|
s.state.SetState(stateobjaddr, storageaddr, data1)
|
||||||
// get snapshot of current state
|
// get snapshot of current state
|
||||||
|
|
@ -143,6 +144,8 @@ func TestSnapshot2(t *testing.T) {
|
||||||
|
|
||||||
stateobjaddr0 := toAddr([]byte("so0"))
|
stateobjaddr0 := toAddr([]byte("so0"))
|
||||||
stateobjaddr1 := toAddr([]byte("so1"))
|
stateobjaddr1 := toAddr([]byte("so1"))
|
||||||
|
state.createObject(stateobjaddr0)
|
||||||
|
state.createObject(stateobjaddr1)
|
||||||
var storageaddr common.Hash
|
var storageaddr common.Hash
|
||||||
|
|
||||||
data0 := common.BytesToHash([]byte{17})
|
data0 := common.BytesToHash([]byte{17})
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ func (self *StateDB) HasSuicided(addr common.Address) bool {
|
||||||
|
|
||||||
// AddBalance adds amount to the account associated with addr
|
// AddBalance adds amount to the account associated with addr
|
||||||
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.AddBalance(amount)
|
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
|
// SubBalance subtracts amount from the account associated with addr
|
||||||
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SubBalance(amount)
|
stateObject.SubBalance(amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
|
func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetBalance(amount)
|
stateObject.SetBalance(amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetNonce(nonce)
|
stateObject.SetNonce(nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) SetCode(addr common.Address, code []byte) {
|
func (self *StateDB) SetCode(addr common.Address, code []byte) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) SetState(addr common.Address, key common.Hash, value common.Hash) {
|
func (self *StateDB) SetState(addr common.Address, key common.Hash, value common.Hash) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetState(self.db, key, value)
|
stateObject.SetState(self.db, key, value)
|
||||||
}
|
}
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -397,7 +398,7 @@ func (self *StateDB) deleteStateObject(stateObject *stateObject) {
|
||||||
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
|
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
|
||||||
// Prefer 'live' objects.
|
// Prefer 'live' objects.
|
||||||
if obj := self.stateObjects[addr]; obj != nil {
|
if obj := self.stateObjects[addr]; obj != nil {
|
||||||
if obj.deleted {
|
if obj.suicided {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnapshotRandom(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}
|
config := &quick.Config{MaxCount: 1000}
|
||||||
err := quick.Check((*snapshotTest).run, config)
|
err := quick.Check((*snapshotTest).run, config)
|
||||||
if cerr, ok := err.(*quick.CheckError); ok {
|
if cerr, ok := err.(*quick.CheckError); ok {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue