Skip to content

Commit 5a7010a

Browse files
authored
Merge pull request #399 from OffchainLabs/opt-destroy-no-storage
Optimize destroying an account with no storage in snapshot diffToDisk
2 parents 95d405a + ca7d82f commit 5a7010a

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

core/state/snapshot/disklayer.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,28 @@ func (dl *diskLayer) Stale() bool {
7676

7777
// Account directly retrieves the account associated with a particular hash in
7878
// the snapshot slim data format.
79-
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
80-
data, err := dl.AccountRLP(hash)
79+
func (dl *diskLayer) account(hash common.Hash, evenIfStale bool) (*types.SlimAccount, error) {
80+
data, err := dl.accountRLP(hash, evenIfStale)
8181
if err != nil {
8282
return nil, err
8383
}
8484
if len(data) == 0 { // can be both nil and []byte{}
8585
return nil, nil
8686
}
8787
account := new(types.SlimAccount)
88-
if err := rlp.DecodeBytes(data, account); err != nil {
89-
panic(err)
90-
}
91-
return account, nil
88+
err = rlp.DecodeBytes(data, account)
89+
return account, err
9290
}
9391

9492
// AccountRLP directly retrieves the account RLP associated with a particular
9593
// hash in the snapshot slim data format.
96-
func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
94+
func (dl *diskLayer) accountRLP(hash common.Hash, evenIfStale bool) ([]byte, error) {
9795
dl.lock.RLock()
9896
defer dl.lock.RUnlock()
9997

10098
// If the layer was flattened into, consider it invalid (any live reference to
10199
// the original should be marked as unusable).
102-
if dl.stale {
100+
if dl.stale && !evenIfStale {
103101
return nil, ErrSnapshotStale
104102
}
105103
// If the layer is being generated, ensure the requested hash has already been
@@ -121,7 +119,9 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
121119
if err != nil {
122120
return nil, err
123121
}
124-
dl.cache.Set(hash[:], blob)
122+
if !dl.stale {
123+
dl.cache.Set(hash[:], blob)
124+
}
125125

126126
snapshotCleanAccountMissMeter.Mark(1)
127127
if n := len(blob); n > 0 {
@@ -132,6 +132,14 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
132132
return blob, nil
133133
}
134134

135+
func (dl *diskLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
136+
return dl.account(hash, false)
137+
}
138+
139+
func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
140+
return dl.accountRLP(hash, false)
141+
}
142+
135143
// Storage directly retrieves the storage data associated with a particular hash,
136144
// within a particular account.
137145
func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, error) {

core/state/snapshot/snapshot.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,23 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
564564
if base.genMarker != nil && bytes.Compare(hash[:], base.genMarker) > 0 {
565565
continue
566566
}
567-
// Remove all storage slots
567+
568+
oldAccount, err := base.account(hash, true)
569+
570+
// Delete the account snapshot
568571
rawdb.DeleteAccountSnapshot(batch, hash)
569572
base.cache.Set(hash[:], nil)
570573

574+
// Try to check if there's any associated storage to delete from the snapshot
575+
if err != nil {
576+
log.Warn("Failed to get destructed account from snapshot", "err", err)
577+
// Fall through to deleting storage in case this account has any
578+
} else if oldAccount == nil || oldAccount.Root == nil {
579+
// There's no storage associated with this account to delete
580+
continue
581+
}
582+
583+
// Remove all storage slots
571584
it := rawdb.IterateStorageSnapshots(base.diskdb, hash)
572585
for it.Next() {
573586
key := it.Key()

0 commit comments

Comments
 (0)