core, core/state: batch-based state sync

This commit is contained in:
Felix Lange
2015-08-18 14:14:45 +02:00
parent 565d9f2306
commit a2d5a60418
10 changed files with 90 additions and 90 deletions

View File

@ -35,7 +35,6 @@ import (
type StateDB struct {
db ethdb.Database
trie *trie.SecureTrie
root common.Hash
stateObjects map[string]*StateObject
@ -56,7 +55,6 @@ func New(root common.Hash, db ethdb.Database) *StateDB {
glog.Errorf("can't create state trie with root %x: %v", root[:], err)
}
return &StateDB{
root: root,
db: db,
trie: tr,
stateObjects: make(map[string]*StateObject),
@ -204,7 +202,6 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
if len(stateObject.CodeHash()) > 0 {
self.db.Put(stateObject.CodeHash(), stateObject.code)
}
addr := stateObject.Address()
self.trie.Update(addr[:], stateObject.RlpEncode())
}
@ -215,6 +212,7 @@ func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
addr := stateObject.Address()
self.trie.Delete(addr[:])
//delete(self.stateObjects, addr.Str())
}
// Retrieve a state object given my the address. Nil if not found
@ -311,65 +309,67 @@ func (self *StateDB) Set(state *StateDB) {
self.logSize = state.logSize
}
func (s *StateDB) Root() common.Hash {
return s.trie.Hash()
}
// Syncs the trie and all siblings
func (s *StateDB) Sync() {
// Sync all nested states
// IntermediateRoot computes the current root hash of the state trie.
// It is called in between transactions to get the root hash that
// goes into transaction receipts.
func (s *StateDB) IntermediateRoot() common.Hash {
s.refund = new(big.Int)
for _, stateObject := range s.stateObjects {
stateObject.trie.Commit()
}
s.trie.Commit()
s.Empty()
}
func (self *StateDB) Empty() {
self.stateObjects = make(map[string]*StateObject)
self.refund = new(big.Int)
}
func (self *StateDB) Refunds() *big.Int {
return self.refund
}
// SyncIntermediate updates the intermediate state and all mid steps
func (self *StateDB) SyncIntermediate() {
self.refund = new(big.Int)
for _, stateObject := range self.stateObjects {
if stateObject.dirty {
if stateObject.remove {
self.DeleteStateObject(stateObject)
s.DeleteStateObject(stateObject)
} else {
stateObject.Update()
self.UpdateStateObject(stateObject)
s.UpdateStateObject(stateObject)
}
stateObject.dirty = false
}
}
return s.trie.Hash()
}
// SyncObjects syncs the changed objects to the trie
func (self *StateDB) SyncObjects() {
self.trie, _ = trie.NewSecure(self.root, self.db)
// Commit commits all state changes to the database.
func (s *StateDB) Commit() (root common.Hash, err error) {
return s.commit(s.db)
}
self.refund = new(big.Int)
// CommitBatch commits all state changes to a write batch but does not
// execute the batch. It is used to validate state changes against
// the root hash stored in a block.
func (s *StateDB) CommitBatch() (root common.Hash, batch ethdb.Batch) {
batch = s.db.NewBatch()
root, _ = s.commit(batch)
return root, batch
}
for _, stateObject := range self.stateObjects {
func (s *StateDB) commit(db trie.DatabaseWriter) (common.Hash, error) {
s.refund = new(big.Int)
for _, stateObject := range s.stateObjects {
if stateObject.remove {
self.DeleteStateObject(stateObject)
// If the object has been removed, don't bother syncing it
// and just mark it for deletion in the trie.
s.DeleteStateObject(stateObject)
} else {
// Write any storage changes in the state object to its trie.
stateObject.Update()
self.UpdateStateObject(stateObject)
// Commit the trie of the object to the batch.
// This updates the trie root internally, so
// getting the root hash of the storage trie
// through UpdateStateObject is fast.
if _, err := stateObject.trie.CommitTo(db); err != nil {
return common.Hash{}, err
}
// Update the object in the account trie.
s.UpdateStateObject(stateObject)
}
stateObject.dirty = false
}
return s.trie.CommitTo(db)
}
func (self *StateDB) Refunds() *big.Int {
return self.refund
}
// Debug stuff