Skip to content

Commit eb83e7c

Browse files
core/state/snapshot: check difflayer staleness early (#27255)
This PR adds a staleness-check to AccountRLP, before checking the bloom-filter and potentially going directly into the disklayer. --------- Co-authored-by: rjl493456442 <[email protected]>
1 parent d46f69d commit eb83e7c

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

core/state/snapshot/difflayer.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,14 @@ func (dl *diffLayer) Account(hash common.Hash) (*Account, error) {
292292
//
293293
// Note the returned account is not a copy, please don't modify it.
294294
func (dl *diffLayer) AccountRLP(hash common.Hash) ([]byte, error) {
295+
dl.lock.RLock()
296+
// Check staleness before reaching further.
297+
if dl.Stale() {
298+
dl.lock.RUnlock()
299+
return nil, ErrSnapshotStale
300+
}
295301
// Check the bloom filter first whether there's even a point in reaching into
296302
// all the maps in all the layers below
297-
dl.lock.RLock()
298303
hit := dl.diffed.Contains(accountBloomHasher(hash))
299304
if !hit {
300305
hit = dl.diffed.Contains(destructBloomHasher(hash))
@@ -361,6 +366,11 @@ func (dl *diffLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
361366
// Check the bloom filter first whether there's even a point in reaching into
362367
// all the maps in all the layers below
363368
dl.lock.RLock()
369+
// Check staleness before reaching further.
370+
if dl.Stale() {
371+
dl.lock.RUnlock()
372+
return nil, ErrSnapshotStale
373+
}
364374
hit := dl.diffed.Contains(storageBloomHasher{accountHash, storageHash})
365375
if !hit {
366376
hit = dl.diffed.Contains(destructBloomHasher(accountHash))

core/state/snapshot/snapshot_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
185185
// be returned with junk data. This version of the test retains the bottom diff
186186
// layer to check the usual mode of operation where the accumulator is retained.
187187
func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
188+
// Un-commenting this triggers the bloom set to be deterministic. The values below
189+
// were used to trigger the flaw described in https://github.com/ethereum/go-ethereum/issues/27254.
190+
// bloomDestructHasherOffset, bloomAccountHasherOffset, bloomStorageHasherOffset = 14, 24, 5
191+
188192
// Create an empty base layer and a snapshot tree out of it
189193
base := &diskLayer{
190194
diskdb: rawdb.NewMemoryDatabase(),

0 commit comments

Comments
 (0)