core/state: fix resurrection state clearing and access

This commit is contained in:
Péter Szilágyi 2020-03-04 10:19:53 +02:00
parent dcb22a9f99
commit 328de180a7
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
2 changed files with 13 additions and 1 deletions

View File

@ -204,6 +204,15 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
if metrics.EnabledExpensive {
defer func(start time.Time) { s.db.SnapshotStorageReads += time.Since(start) }(time.Now())
}
// If the object was destructed in *this* block (and potentially resurrected),
// the storage has been cleared out, and we should *not* consult the previous
// snapshot about any storage values. The only possible alternatives are:
// 1) resurrect happened, and new slot values were set -- those should
// have been handles via pendingStorage above.
// 2) we don't have new values, and can deliver empty response back
if _, destructed := s.db.snapDestructs[s.addrHash]; destructed {
return common.Hash{}
}
enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key[:]))
}
// If snapshot unavailable or reading from it failed, load from the database

View File

@ -595,6 +595,9 @@ func (s *StateDB) CreateAccount(addr common.Address) {
if prev != nil {
newObj.setBalance(prev.data.Balance)
}
if s.snap != nil && prev != nil {
s.snapDestructs[prev.addrHash] = struct{}{}
}
}
func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
@ -855,7 +858,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
log.Warn("Failed to cap snapshot tree", "root", root, "layers", 127, "err", err)
}
}
s.snap, s.snapAccounts, s.snapStorage = nil, nil, nil
s.snap, s.snapDestructs, s.snapAccounts, s.snapStorage = nil, nil, nil, nil
}
return root, err
}