From 56c00211a89989ff515a60f319e2d8cddf8c978a Mon Sep 17 00:00:00 2001 From: Mayveskii Date: Thu, 26 Mar 2026 20:24:41 +0300 Subject: [PATCH] core/state/snapshot: handle bloom filter errors in rebloom The diffLayer.rebloom method silently discards errors from both bloomfilter.New and parent.diffed.Copy. If either fails (e.g. due to memory pressure or corrupted parent bloom), dl.diffed remains nil, which causes a nil pointer dereference in subsequent snapshot lookups via accountBloomHash. Handle errors explicitly: fall back to a fresh bloom on copy failure, and return early on allocation failure with a logged error. --- core/state/snapshot/difflayer.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index 1286ded7e1..f811faafbe 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" bloomfilter "github.com/holiman/bloomfilter/v2" ) @@ -173,10 +174,20 @@ func (dl *diffLayer) rebloom(origin *diskLayer) { // Retrieve the parent bloom or create a fresh empty one if parent, ok := dl.parent.(*diffLayer); ok { parent.lock.RLock() - dl.diffed, _ = parent.diffed.Copy() + bloom, err := parent.diffed.Copy() parent.lock.RUnlock() + if err != nil { + log.Error("Failed to copy parent bloom filter", "err", err) + bloom, _ = bloomfilter.New(uint64(bloomSize), uint64(bloomFuncs)) + } + dl.diffed = bloom } else { - dl.diffed, _ = bloomfilter.New(uint64(bloomSize), uint64(bloomFuncs)) + bloom, err := bloomfilter.New(uint64(bloomSize), uint64(bloomFuncs)) + if err != nil { + log.Error("Failed to create bloom filter", "err", err) + return + } + dl.diffed = bloom } for hash := range dl.accountData { dl.diffed.AddHash(accountBloomHash(hash))