diff --git a/core/state/state_object.go b/core/state/state_object.go index 538d5e5da8..b454de272d 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -18,6 +18,7 @@ package state import ( "bytes" + "errors" "fmt" "io" "math/big" @@ -25,6 +26,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" @@ -274,6 +276,10 @@ func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Has } enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) } + // ErrSnapshotStale may occur due to diff layers in the update, so we should try again in noTrie mode. + if s.db.NoTrie() && err != nil && errors.Is(err, snapshot.ErrSnapshotStale) { + return s.GetCommittedState(db, key) + } // If snapshot unavailable or reading from it failed, load from the database if s.db.snap == nil || err != nil { if meter != nil { diff --git a/core/state/statedb.go b/core/state/statedb.go index b82a8ae0a3..7ceb8e0e47 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -674,6 +674,12 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject { } } } + + // ErrSnapshotStale may occur due to diff layers in the update, so we should try again in noTrie mode. + if s.NoTrie() && err != nil && errors.Is(err, snapshot.ErrSnapshotStale) { + return s.getDeletedStateObject(addr) + } + // If snapshot unavailable or reading from it failed, load from the database if s.snap == nil || err != nil { if s.trie == nil { @@ -1517,9 +1523,11 @@ func (s *StateDB) Commit(failPostCommitFunc func(), postCommitFuncs ...func() er // - head layer is paired with HEAD state // - head-1 layer is paired with HEAD-1 state // - head-(n-1) layer(bottom-most diff layer) is paired with HEAD-(n-1)state - if err := s.snaps.Cap(s.expectedRoot, s.snaps.CapLimit()); err != nil { - log.Warn("Failed to cap snapshot tree", "root", s.expectedRoot, "layers", s.snaps.CapLimit(), "err", err) - } + go func() { + if err := s.snaps.Cap(s.expectedRoot, s.snaps.CapLimit()); err != nil { + log.Warn("Failed to cap snapshot tree", "root", s.expectedRoot, "layers", s.snaps.CapLimit(), "err", err) + } + }() } } return nil