From bd6181e6c8fa3279a030c6a4bf746357e555ace4 Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Thu, 24 Apr 2025 16:55:31 +0200 Subject: [PATCH] core/filtermaps: fix range delete deadlock --- core/filtermaps/filtermaps.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index 920167ca8d..a93c7bbdf0 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -762,7 +762,11 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { return false, errors.New("invalid tail epoch number") } // remove index data - if err := f.safeDeleteWithLogs(func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error { + f.indexLock.Unlock() + // Note: indexLock should not be held while deleting data because the callback + // might want to acquire it. The epoch has been marked unindexed already so + // this is just dirty data that should not affect any concurrent search process. + err = f.safeDeleteWithLogs(func(db ethdb.KeyValueStore, hashScheme bool, stopCb func(bool) bool) error { first := f.mapRowIndex(firstMap, 0) count := f.mapRowIndex(firstMap+f.mapsPerEpoch, 0) - first if err := rawdb.DeleteFilterMapRows(f.db, common.NewRange(first, count), hashScheme, stopCb); err != nil { @@ -789,7 +793,9 @@ func (f *FilterMaps) deleteTailEpoch(epoch uint32) (bool, error) { }, fmt.Sprintf("Deleting tail epoch #%d", epoch), func() bool { f.processEvents() return f.stop || !f.targetHeadIndexed() - }); err == nil { + }) + f.indexLock.Lock() + if err == nil { // everything removed; mark as cleaned and report success if f.cleanedEpochsBefore == epoch { f.cleanedEpochsBefore = epoch + 1