Skip to content

Commit 5a254c4

Browse files
committed
add interval when getting ErrSnapshotStale
1 parent b56c19c commit 5a254c4

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

core/state/state_object.go

+8
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,14 @@ func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Has
278278
}
279279
// ErrSnapshotStale may occur due to diff layers in the update, so we should try again in noTrie mode.
280280
if s.db.NoTrie() && err != nil && errors.Is(err, snapshot.ErrSnapshotStale) {
281+
// This error occurs when statedb.snaps.Cap changes the state of the merged difflayer
282+
// to stale during the refresh of the difflayer, indicating that it is about to be discarded.
283+
// Since the difflayer is refreshed in parallel,
284+
// there is a small chance that the difflayer of the stale will be read while reading,
285+
// resulting in an empty array being returned here.
286+
// Therefore, noTrie mode must retry here,
287+
// and add a time interval when retrying to avoid stacking too much and causing OOM.
288+
time.Sleep(snapshotStaleRetryInterval)
281289
return s.GetCommittedState(db, key)
282290
}
283291
// If snapshot unavailable or reading from it failed, load from the database

core/state/statedb.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ import (
3939
"github.com/ethereum/go-ethereum/trie"
4040
)
4141

42-
const defaultNumOfSlots = 100
42+
const (
43+
defaultNumOfSlots = 100
44+
snapshotStaleRetryInterval = time.Millisecond * 100
45+
)
4346

4447
type revision struct {
4548
id int
@@ -677,6 +680,14 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject {
677680

678681
// ErrSnapshotStale may occur due to diff layers in the update, so we should try again in noTrie mode.
679682
if s.NoTrie() && err != nil && errors.Is(err, snapshot.ErrSnapshotStale) {
683+
// This error occurs when statedb.snaps.Cap changes the state of the merged difflayer
684+
// to stale during the refresh of the difflayer, indicating that it is about to be discarded.
685+
// Since the difflayer is refreshed in parallel,
686+
// there is a small chance that the difflayer of the stale will be read while reading,
687+
// resulting in an empty array being returned here.
688+
// Therefore, noTrie mode must retry here,
689+
// and add a time interval when retrying to avoid stacking too much and causing OOM.
690+
time.Sleep(snapshotStaleRetryInterval)
680691
return s.getDeletedStateObject(addr)
681692
}
682693

0 commit comments

Comments
 (0)