diff --git a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs index 8e78cbf7f73..499a60f3984 100644 --- a/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs +++ b/src/Nethermind/Nethermind.State.Test/StorageProviderTests.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Resettables; +using Nethermind.Core.Test.Builders; using Nethermind.Db; using Nethermind.Specs.Forks; using Nethermind.Logging; @@ -409,6 +410,23 @@ public void Persistent_state_restores_independent_of_transient_state(int snapsho _values[snapshot + 1].Should().BeEquivalentTo(provider.Get(new StorageCell(ctx.Address1, 1)).ToArray()); } + /// + /// Reset will reset transient state + /// + [Test] + public void Selfdestruct_clears_cache() + { + PreBlockCaches preBlockCaches = new PreBlockCaches(); + Context ctx = new(preBlockCaches); + WorldState provider = BuildStorageProvider(ctx); + StorageCell storageCell = new StorageCell(TestItem.AddressA, 1); + preBlockCaches.StorageCache[storageCell] = [1, 2, 3]; + provider.Get(storageCell); + provider.Commit(Paris.Instance); + provider.ClearStorage(TestItem.AddressA); + provider.Get(storageCell).ToArray().Should().BeEquivalentTo(StorageTree.EmptyBytes); + } + private class Context { public WorldState StateProvider { get; } @@ -416,9 +434,9 @@ private class Context public readonly Address Address1 = new(Keccak.Compute("1")); public readonly Address Address2 = new(Keccak.Compute("2")); - public Context() + public Context(PreBlockCaches preBlockCaches = null) { - StateProvider = new WorldState(new TrieStore(new MemDb(), LimboLogs.Instance), Substitute.For(), LogManager); + StateProvider = new WorldState(new TrieStore(new MemDb(), LimboLogs.Instance), Substitute.For(), LogManager, preBlockCaches); StateProvider.CreateAccount(Address1, 0); StateProvider.CreateAccount(Address2, 0); StateProvider.Commit(Frontier.Instance); diff --git a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs index a43b892466b..c9c0b8d032a 100644 --- a/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs +++ b/src/Nethermind/Nethermind.State/PersistentStorageProvider.cs @@ -428,7 +428,13 @@ public override void ClearStorage(Address address) base.ClearStorage(address); // Bit heavy-handed, but we need to clear all the cache for that address - _blockCache.Remove(address); + if (_blockCache.TryGetValue(address, out Dictionary values)) + { + foreach (UInt256 storageSlot in values.Keys) + { + values[storageSlot] = StorageTree.EmptyBytes; + } + } // here it is important to make sure that we will not reuse the same tree when the contract is revived // by means of CREATE 2 - notice that the cached trie may carry information about items that were not