|
|
@@ -466,6 +466,14 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
|
|
|
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
|
|
|
}
|
|
|
s.setError(s.trie.TryUpdate(addr[:], data))
|
|
|
+
|
|
|
+ // If state snapshotting is active, cache the data til commit. Note, this
|
|
|
+ // update mechanism is not symmetric to the deletion, because whereas it is
|
|
|
+ // enough to track account updates at commit time, deletions need tracking
|
|
|
+ // at transaction boundary level to ensure we capture state clearing.
|
|
|
+ if s.snap != nil {
|
|
|
+ s.snapAccounts[obj.addrHash] = snapshot.AccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// deleteStateObject removes the given object from the state trie.
|
|
|
@@ -729,7 +737,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
|
|
// If state snapshotting is active, also mark the destruction there.
|
|
|
// Note, we can't do this only at the end of a block because multiple
|
|
|
// transactions within the same block might self destruct and then
|
|
|
- // ressurrect an account and the snapshotter needs both events.
|
|
|
+ // ressurrect an account; but the snapshotter needs both events.
|
|
|
if s.snap != nil {
|
|
|
s.snapDestructs[obj.addrHash] = struct{}{} // We need to maintain account deletions explicitly (will remain set indefinitely)
|
|
|
delete(s.snapAccounts, obj.addrHash) // Clear out any previously updated account data (may be recreated via a ressurrect)
|
|
|
@@ -737,11 +745,6 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
|
|
}
|
|
|
} else {
|
|
|
obj.finalise()
|
|
|
-
|
|
|
- // If state snapshotting is active, cache the data til commit
|
|
|
- if s.snap != nil {
|
|
|
- s.snapAccounts[obj.addrHash] = snapshot.AccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash)
|
|
|
- }
|
|
|
}
|
|
|
s.stateObjectsPending[addr] = struct{}{}
|
|
|
s.stateObjectsDirty[addr] = struct{}{}
|