|
|
@@ -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)
|
|
|
+}
|
|
|
+
|
|
|
+// 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
|
|
|
+}
|
|
|
|
|
|
- self.refund = new(big.Int)
|
|
|
+func (s *StateDB) commit(db trie.DatabaseWriter) (common.Hash, error) {
|
|
|
+ s.refund = new(big.Int)
|
|
|
|
|
|
- for _, stateObject := range self.stateObjects {
|
|
|
+ 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
|