core/state: keeping track of written state

This commit is contained in:
Jeffrey Wilcke 2016-09-22 21:12:51 +02:00
parent 0768a8bc6b
commit 91ecef628a
2 changed files with 11 additions and 2 deletions

View file

@ -80,6 +80,7 @@ type StateObject struct {
remove bool remove bool
deleted bool deleted bool
dirty bool dirty bool
written bool
} }
func NewStateObject(address common.Address, db trie.Database) *StateObject { func NewStateObject(address common.Address, db trie.Database) *StateObject {
@ -98,6 +99,7 @@ func NewStateObject(address common.Address, db trie.Database) *StateObject {
func (self *StateObject) MarkForDeletion() { func (self *StateObject) MarkForDeletion() {
self.remove = true self.remove = true
self.dirty = true self.dirty = true
self.written = false
if glog.V(logger.Core) { if glog.V(logger.Core) {
glog.Infof("%x: #%d %v X\n", self.Address(), self.nonce, self.balance) glog.Infof("%x: #%d %v X\n", self.Address(), self.nonce, self.balance)
@ -138,6 +140,7 @@ func (self *StateObject) GetState(key common.Hash) common.Hash {
func (self *StateObject) SetState(key, value common.Hash) { func (self *StateObject) SetState(key, value common.Hash) {
self.storage[key] = value self.storage[key] = value
self.dirty = true self.dirty = true
self.written = false
} }
// Update updates the current cached storage to the trie // Update updates the current cached storage to the trie
@ -157,6 +160,7 @@ func (c *StateObject) AddBalance(amount *big.Int) {
if glog.V(logger.Core) { if glog.V(logger.Core) {
glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount) glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount)
} }
c.written = false
} }
func (c *StateObject) SubBalance(amount *big.Int) { func (c *StateObject) SubBalance(amount *big.Int) {
@ -165,11 +169,13 @@ func (c *StateObject) SubBalance(amount *big.Int) {
if glog.V(logger.Core) { if glog.V(logger.Core) {
glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount) glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount)
} }
c.written = false
} }
func (c *StateObject) SetBalance(amount *big.Int) { func (c *StateObject) SetBalance(amount *big.Int) {
c.balance = amount c.balance = amount
c.dirty = true c.dirty = true
c.written = false
} }
func (c *StateObject) St() Storage { func (c *StateObject) St() Storage {
@ -223,11 +229,13 @@ func (self *StateObject) SetCode(code []byte) {
self.code = code self.code = code
self.codeHash = crypto.Keccak256(code) self.codeHash = crypto.Keccak256(code)
self.dirty = true self.dirty = true
self.written = false
} }
func (self *StateObject) SetNonce(nonce uint64) { func (self *StateObject) SetNonce(nonce uint64) {
self.nonce = nonce self.nonce = nonce
self.dirty = true self.dirty = true
self.written = false
} }
func (self *StateObject) Nonce() uint64 { func (self *StateObject) Nonce() uint64 {

View file

@ -27,13 +27,13 @@ func CommitBatch(state *State) (common.Hash, ethdb.Batch) {
func stateCommit(state *State, db trie.DatabaseWriter) (common.Hash, error) { func stateCommit(state *State, db trie.DatabaseWriter) (common.Hash, error) {
// make sure the state is flattened before committing // make sure the state is flattened before committing
state = Flatten(state) state = Flatten(state)
for address, stateObject := range state.StateObjects { for _, stateObject := range state.StateObjects {
if stateObject.remove { if stateObject.remove {
// If the object has been removed, don't bother syncing it // If the object has been removed, don't bother syncing it
// and just mark it for deletion in the trie. // and just mark it for deletion in the trie.
stateObject.deleted = true stateObject.deleted = true
state.Trie.Delete(stateObject.Address().Bytes()[:]) state.Trie.Delete(stateObject.Address().Bytes()[:])
} else if state.ownedStateObjects[address] { } else if !stateObject.written {
// Write any contract code associated with the state object // Write any contract code associated with the state object
if len(stateObject.code) > 0 { if len(stateObject.code) > 0 {
if err := db.Put(stateObject.codeHash, stateObject.code); err != nil { if err := db.Put(stateObject.codeHash, stateObject.code); err != nil {
@ -60,6 +60,7 @@ func stateCommit(state *State, db trie.DatabaseWriter) (common.Hash, error) {
} }
stateObject.dirty = false stateObject.dirty = false
stateObject.written = true
} }
return state.Trie.CommitTo(db) return state.Trie.CommitTo(db)
} }