From 6d21b8ed2e1d32a9da9d14e7cfa9f7cc1a06c12e Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 26 Mar 2026 11:09:23 +0200 Subject: [PATCH 1/3] add Reset() for spm and ewl --- state/interface.go | 2 ++ .../disabled/disabledStoragePruningManager.go | 3 ++ .../memoryEvictionWaitingList.go | 13 +++++++ .../storagePruningManager.go | 6 ++++ .../storagePruningManager_test.go | 34 +++++++++++++++++++ testscommon/state/evictionWaitingListMock.go | 7 ++++ .../state/storagePruningManagerStub.go | 7 ++++ 7 files changed, 72 insertions(+) diff --git a/state/interface.go b/state/interface.go index 2e9893f1cc6..93d09ff9d0b 100644 --- a/state/interface.go +++ b/state/interface.go @@ -178,6 +178,7 @@ type DBRemoveCacher interface { Put([]byte, common.ModifiedHashes) error Evict([]byte) (common.ModifiedHashes, error) ShouldKeepHash(hash string, identifier TriePruningIdentifier) (bool, error) + Reset() IsInterfaceNil() bool Close() error } @@ -194,6 +195,7 @@ type StoragePruningManager interface { MarkForEviction([]byte, []byte, common.ModifiedHashes, common.ModifiedHashes) error PruneTrie(rootHash []byte, identifier TriePruningIdentifier, tsm common.StorageManager, handler PruningHandler) CancelPrune(rootHash []byte, identifier TriePruningIdentifier, tsm common.StorageManager) + Reset() Close() error IsInterfaceNil() bool } diff --git a/state/storagePruningManager/disabled/disabledStoragePruningManager.go b/state/storagePruningManager/disabled/disabledStoragePruningManager.go index 6de7e2b0845..2e10c84a7f3 100644 --- a/state/storagePruningManager/disabled/disabledStoragePruningManager.go +++ b/state/storagePruningManager/disabled/disabledStoragePruningManager.go @@ -26,6 +26,9 @@ func (i *disabledStoragePruningManager) PruneTrie(_ []byte, _ state.TriePruningI func (i *disabledStoragePruningManager) CancelPrune(_ []byte, _ state.TriePruningIdentifier, _ common.StorageManager) { } +// Reset does nothing for this implementation +func (i *disabledStoragePruningManager) Reset() {} + // Close does nothing for this implementation func (i *disabledStoragePruningManager) Close() error { return nil diff --git a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go index 52aa401c5ba..df91bfcc525 100644 --- a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go +++ b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList.go @@ -205,6 +205,19 @@ func (mewl *memoryEvictionWaitingList) ShouldKeepHash(hash string, identifier st return false, nil } +// Reset will reinitialize the eviction waiting list, by emptying the cache and reversed cache. It will not change the sizes of the caches. +func (mewl *memoryEvictionWaitingList) Reset() { + mewl.opMutex.Lock() + + for key := range mewl.cache { + log.Debug("trie nodes eviction waiting list reset", "rootHash", []byte(key)) + } + + mewl.cache = make(map[string]*rootHashData) + mewl.reversedCache = make(map[string]*hashInfo) + mewl.opMutex.Unlock() +} + // Close returns nil func (mewl *memoryEvictionWaitingList) Close() error { return nil diff --git a/state/storagePruningManager/storagePruningManager.go b/state/storagePruningManager/storagePruningManager.go index 757d04cc9ed..958de885b2f 100644 --- a/state/storagePruningManager/storagePruningManager.go +++ b/state/storagePruningManager/storagePruningManager.go @@ -234,6 +234,12 @@ func (spm *storagePruningManager) removeFromDb( return nil } +func (spm *storagePruningManager) Reset() { + log.Debug("storage pruning manager reset") + _ = spm.pruningBuffer.RemoveAll() + spm.dbEvictionWaitingList.Reset() +} + // Close will handle the closing of the underlying components func (spm *storagePruningManager) Close() error { return spm.dbEvictionWaitingList.Close() diff --git a/state/storagePruningManager/storagePruningManager_test.go b/state/storagePruningManager/storagePruningManager_test.go index 006a88e4d70..e8c1ba25328 100644 --- a/state/storagePruningManager/storagePruningManager_test.go +++ b/state/storagePruningManager/storagePruningManager_test.go @@ -260,3 +260,37 @@ func TestStoragePruningManager_MarkForEviction_removeDuplicatedKeys(t *testing.T _, ok = map2["hash4"] assert.False(t, ok) } + +func TestStoreagePruningManager_Reset(t *testing.T) { + t.Parallel() + + args := storage.GetStorageManagerArgs() + trieStorage, _ := trie.NewTrieStorageManager(args) + ewlArgs := evictionWaitingList.MemoryEvictionWaitingListArgs{ + RootHashesSize: 100, + HashesSize: 10000, + } + ewl, _ := evictionWaitingList.NewMemoryEvictionWaitingList(ewlArgs) + spm, _ := NewStoragePruningManager(ewl, 1000) + + err := spm.MarkForEviction([]byte("rootHash"), []byte("newRootHash"), map[string]struct{}{"hash1": {}, "hash2": {}}, map[string]struct{}{"hash3": {}, "hash4": {}}) + assert.Nil(t, err) + err = spm.markForEviction([]byte("rootHash2"), map[string]struct{}{"hash5": {}, "hash6": {}}, state.NewRoot) + assert.Nil(t, err) + + trieStorage.EnterPruningBufferingMode() + spm.PruneTrie([]byte("rootHash"), state.OldRoot, trieStorage, state.NewPruningHandler(state.EnableDataRemoval)) + spm.CancelPrune([]byte("newRootHash"), state.NewRoot, trieStorage) + trieStorage.ExitPruningBufferingMode() + + assert.Equal(t, 2, spm.pruningBuffer.Len()) + + spm.Reset() + assert.Equal(t, 0, spm.pruningBuffer.Len()) + + // rootHash2 will should not be added to the pruning buffer because ewl was also reset when spm.Reset() was called + trieStorage.EnterPruningBufferingMode() + spm.PruneTrie([]byte("rootHash2"), state.NewRoot, trieStorage, state.NewPruningHandler(state.EnableDataRemoval)) + trieStorage.ExitPruningBufferingMode() + assert.Equal(t, 0, spm.pruningBuffer.Len()) +} diff --git a/testscommon/state/evictionWaitingListMock.go b/testscommon/state/evictionWaitingListMock.go index c071440d7b1..84d0e31e9e7 100644 --- a/testscommon/state/evictionWaitingListMock.go +++ b/testscommon/state/evictionWaitingListMock.go @@ -81,6 +81,13 @@ func (ewl *EvictionWaitingListMock) ShouldKeepHash(hash string, identifier state return false, nil } +// Reset will reinitialize the cache +func (ewl *EvictionWaitingListMock) Reset() { + ewl.OpMutex.Lock() + ewl.Cache = make(map[string]common.ModifiedHashes) + ewl.OpMutex.Unlock() +} + // Close - func (ewl *EvictionWaitingListMock) Close() error { return nil diff --git a/testscommon/state/storagePruningManagerStub.go b/testscommon/state/storagePruningManagerStub.go index 92c697c5224..20105a5b1b4 100644 --- a/testscommon/state/storagePruningManagerStub.go +++ b/testscommon/state/storagePruningManagerStub.go @@ -10,6 +10,7 @@ type StoragePruningManagerStub struct { MarkForEvictionCalled func(bytes []byte, bytes2 []byte, hashes common.ModifiedHashes, hashes2 common.ModifiedHashes) error PruneTrieCalled func(rootHash []byte, identifier state.TriePruningIdentifier, tsm common.StorageManager, handler state.PruningHandler) CancelPruneCalled func(rootHash []byte, identifier state.TriePruningIdentifier, tsm common.StorageManager) + ResetCalled func() CloseCalled func() error } @@ -36,6 +37,12 @@ func (stub *StoragePruningManagerStub) CancelPrune(rootHash []byte, identifier s } } +func (stub *StoragePruningManagerStub) Reset() { + if stub.ResetCalled != nil { + stub.ResetCalled() + } +} + // Close - func (stub *StoragePruningManagerStub) Close() error { if stub.CloseCalled != nil { From 587f961f2e0c586e4238805459965287d86e1c85 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 26 Mar 2026 11:10:46 +0200 Subject: [PATCH 2/3] add missing comment --- testscommon/state/storagePruningManagerStub.go | 1 + 1 file changed, 1 insertion(+) diff --git a/testscommon/state/storagePruningManagerStub.go b/testscommon/state/storagePruningManagerStub.go index 20105a5b1b4..5b91046909c 100644 --- a/testscommon/state/storagePruningManagerStub.go +++ b/testscommon/state/storagePruningManagerStub.go @@ -37,6 +37,7 @@ func (stub *StoragePruningManagerStub) CancelPrune(rootHash []byte, identifier s } } +// Reset - func (stub *StoragePruningManagerStub) Reset() { if stub.ResetCalled != nil { stub.ResetCalled() From 75a6db210f3b6003bd77cb22c77bc1733cca21c6 Mon Sep 17 00:00:00 2001 From: BeniaminDrasovean Date: Thu, 26 Mar 2026 11:23:07 +0200 Subject: [PATCH 3/3] export pruning reset on accountsDB --- .../bootstrap/disabled/disabledAccountsAdapter.go | 4 ++++ .../transactionEvaluator/simulationAccountsDB.go | 4 ++++ state/accountsDB.go | 8 ++++++++ state/accountsDBApi.go | 4 ++++ state/accountsDBApiWithHistory.go | 4 ++++ state/interface.go | 1 + .../memoryEvictionWaitingList_test.go | 15 +++++++++++++++ .../storagePruningManager.go | 6 ++++-- .../storagePruningManager_test.go | 4 ++-- testscommon/state/accountsAdapterStub.go | 8 ++++++++ 10 files changed, 54 insertions(+), 4 deletions(-) diff --git a/epochStart/bootstrap/disabled/disabledAccountsAdapter.go b/epochStart/bootstrap/disabled/disabledAccountsAdapter.go index ce928b21fca..d6ace804ff9 100644 --- a/epochStart/bootstrap/disabled/disabledAccountsAdapter.go +++ b/epochStart/bootstrap/disabled/disabledAccountsAdapter.go @@ -99,6 +99,10 @@ func (a *accountsAdapter) RecreateTrieIfNeeded(_ common.RootHashHolder) error { func (a *accountsAdapter) CancelPrune(_ []byte, _ state.TriePruningIdentifier) { } +// ResetPruning - +func (a *accountsAdapter) ResetPruning() { +} + // SnapshotState - func (a *accountsAdapter) SnapshotState(_ []byte, _ uint32) { } diff --git a/process/transactionEvaluator/simulationAccountsDB.go b/process/transactionEvaluator/simulationAccountsDB.go index edad278c798..835a64252e5 100644 --- a/process/transactionEvaluator/simulationAccountsDB.go +++ b/process/transactionEvaluator/simulationAccountsDB.go @@ -145,6 +145,10 @@ func (r *simulationAccountsDB) PruneTrie(_ []byte, _ state.TriePruningIdentifier func (r *simulationAccountsDB) CancelPrune(_ []byte, _ state.TriePruningIdentifier) { } +// ResetPruning won't do anything as write operations are disabled on this component +func (r *simulationAccountsDB) ResetPruning() { +} + // SnapshotState won't do anything as write operations are disabled on this component func (r *simulationAccountsDB) SnapshotState(_ []byte, _ uint32) { } diff --git a/state/accountsDB.go b/state/accountsDB.go index b412bac97d6..52dcb16be87 100644 --- a/state/accountsDB.go +++ b/state/accountsDB.go @@ -1230,6 +1230,14 @@ func (adb *AccountsDB) CancelPrune(rootHash []byte, identifier TriePruningIdenti adb.storagePruningManager.CancelPrune(rootHash, identifier, adb.mainTrie.GetStorageManager()) } +// ResetPruning will reset all collected data needed for pruning +func (adb *AccountsDB) ResetPruning() { + adb.mutOp.Lock() + defer adb.mutOp.Unlock() + + adb.storagePruningManager.Reset() +} + // SnapshotState triggers the snapshotting process of the state trie func (adb *AccountsDB) SnapshotState(rootHash []byte, epoch uint32) { adb.snapshotsManger.SnapshotState(rootHash, epoch, adb.getMainTrie().GetStorageManager()) diff --git a/state/accountsDBApi.go b/state/accountsDBApi.go index 76ee0d506d8..915a9e9bea5 100644 --- a/state/accountsDBApi.go +++ b/state/accountsDBApi.go @@ -224,6 +224,10 @@ func (accountsDB *accountsDBApi) PruneTrie(_ []byte, _ TriePruningIdentifier, _ func (accountsDB *accountsDBApi) CancelPrune(_ []byte, _ TriePruningIdentifier) { } +// ResetPruning is a not permitted operation in this implementation and thus, does nothing +func (accountsDB *accountsDBApi) ResetPruning() { +} + // SnapshotState is a not permitted operation in this implementation and thus, does nothing func (accountsDB *accountsDBApi) SnapshotState(_ []byte, _ uint32) { } diff --git a/state/accountsDBApiWithHistory.go b/state/accountsDBApiWithHistory.go index e39a24ea7c7..048fbd44bbe 100644 --- a/state/accountsDBApiWithHistory.go +++ b/state/accountsDBApiWithHistory.go @@ -112,6 +112,10 @@ func (accountsDB *accountsDBApiWithHistory) PruneTrie(_ []byte, _ TriePruningIde func (accountsDB *accountsDBApiWithHistory) CancelPrune(_ []byte, _ TriePruningIdentifier) { } +// ResetPruning is a not permitted operation in this implementation and thus, does nothing +func (accountsDB *accountsDBApiWithHistory) ResetPruning() { +} + // SnapshotState is a not permitted operation in this implementation and thus, does nothing func (accountsDB *accountsDBApiWithHistory) SnapshotState(_ []byte, _ uint32) { } diff --git a/state/interface.go b/state/interface.go index 93d09ff9d0b..254c68ddd44 100644 --- a/state/interface.go +++ b/state/interface.go @@ -84,6 +84,7 @@ type AccountsAdapter interface { RecreateTrieIfNeeded(options common.RootHashHolder) error PruneTrie(rootHash []byte, identifier TriePruningIdentifier, handler PruningHandler) CancelPrune(rootHash []byte, identifier TriePruningIdentifier) + ResetPruning() SnapshotState(rootHash []byte, epoch uint32) IsPruningEnabled() bool GetAllLeaves(leavesChannels *common.TrieIteratorChannels, ctx context.Context, rootHash []byte, trieLeafParser common.TrieLeafParser) error diff --git a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList_test.go b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList_test.go index 21099502f93..69ef10606d3 100644 --- a/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList_test.go +++ b/state/storagePruningManager/evictionWaitingList/memoryEvictionWaitingList_test.go @@ -359,3 +359,18 @@ func TestMemoryEvictionWaitingList_RemoveFromInversedCache(t *testing.T) { assert.Nil(t, info) assert.False(t, exists) } + +func TestMemoryEvictionWaitingList_Reset(t *testing.T) { + t.Parallel() + + mewl, _ := NewMemoryEvictionWaitingList(getDefaultArgsForMemoryEvictionWaitingList()) + + _ = mewl.Put([]byte("root1"), common.ModifiedHashes{"hash1": {}, "hash2": {}}) + _ = mewl.Put([]byte("root2"), common.ModifiedHashes{"hash3": {}, "hash4": {}}) + + assert.Equal(t, 2, len(mewl.cache)) + assert.Equal(t, 4, len(mewl.reversedCache)) + mewl.Reset() + assert.Equal(t, 0, len(mewl.cache)) + assert.Equal(t, 0, len(mewl.reversedCache)) +} diff --git a/state/storagePruningManager/storagePruningManager.go b/state/storagePruningManager/storagePruningManager.go index 958de885b2f..2478316a02a 100644 --- a/state/storagePruningManager/storagePruningManager.go +++ b/state/storagePruningManager/storagePruningManager.go @@ -235,8 +235,10 @@ func (spm *storagePruningManager) removeFromDb( } func (spm *storagePruningManager) Reset() { - log.Debug("storage pruning manager reset") - _ = spm.pruningBuffer.RemoveAll() + bufferedHashes := spm.pruningBuffer.RemoveAll() + for _, hash := range bufferedHashes { + log.Trace("trie storage manager reset", "hash", hash) + } spm.dbEvictionWaitingList.Reset() } diff --git a/state/storagePruningManager/storagePruningManager_test.go b/state/storagePruningManager/storagePruningManager_test.go index e8c1ba25328..2f656e6b556 100644 --- a/state/storagePruningManager/storagePruningManager_test.go +++ b/state/storagePruningManager/storagePruningManager_test.go @@ -261,7 +261,7 @@ func TestStoragePruningManager_MarkForEviction_removeDuplicatedKeys(t *testing.T assert.False(t, ok) } -func TestStoreagePruningManager_Reset(t *testing.T) { +func TestStoragePruningManager_Reset(t *testing.T) { t.Parallel() args := storage.GetStorageManagerArgs() @@ -288,7 +288,7 @@ func TestStoreagePruningManager_Reset(t *testing.T) { spm.Reset() assert.Equal(t, 0, spm.pruningBuffer.Len()) - // rootHash2 will should not be added to the pruning buffer because ewl was also reset when spm.Reset() was called + // rootHash2 should not be added to the pruning buffer because ewl was also reset when spm.Reset() was called trieStorage.EnterPruningBufferingMode() spm.PruneTrie([]byte("rootHash2"), state.NewRoot, trieStorage, state.NewPruningHandler(state.EnableDataRemoval)) trieStorage.ExitPruningBufferingMode() diff --git a/testscommon/state/accountsAdapterStub.go b/testscommon/state/accountsAdapterStub.go index aa3d41e1355..04608b50045 100644 --- a/testscommon/state/accountsAdapterStub.go +++ b/testscommon/state/accountsAdapterStub.go @@ -29,6 +29,7 @@ type AccountsStub struct { RecreateTrieIfNeededCalled func(options common.RootHashHolder) error PruneTrieCalled func(rootHash []byte, identifier state.TriePruningIdentifier, handler state.PruningHandler) CancelPruneCalled func(rootHash []byte, identifier state.TriePruningIdentifier) + ResetPruningCalled func() SnapshotStateCalled func(rootHash []byte, epoch uint32) IsPruningEnabledCalled func() bool GetAllLeavesCalled func(leavesChannels *common.TrieIteratorChannels, ctx context.Context, rootHash []byte, trieLeafParser common.TrieLeafParser) error @@ -208,6 +209,13 @@ func (as *AccountsStub) CancelPrune(rootHash []byte, identifier state.TriePrunin } } +// ResetPruning - +func (as *AccountsStub) ResetPruning() { + if as.ResetPruningCalled != nil { + as.ResetPruningCalled() + } +} + // SnapshotState - func (as *AccountsStub) SnapshotState(rootHash []byte, epoch uint32) { if as.SnapshotStateCalled != nil {