diff --git a/src/Nethermind/Nethermind.Blockchain/FullPruning/PruningTriggerPersistenceStrategy.cs b/src/Nethermind/Nethermind.Blockchain/FullPruning/PruningTriggerPersistenceStrategy.cs
index b2d88f9ef7a..6118fc4188a 100644
--- a/src/Nethermind/Nethermind.Blockchain/FullPruning/PruningTriggerPersistenceStrategy.cs
+++ b/src/Nethermind/Nethermind.Blockchain/FullPruning/PruningTriggerPersistenceStrategy.cs
@@ -67,6 +67,8 @@ public bool ShouldPersist(long blockNumber)
return inPruning;
}
+ public bool IsFullPruning => _inPruning != 0;
+
///
public void Dispose()
{
diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs
index 35c20ecf02b..b36f35af072 100644
--- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs
+++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs
@@ -16,6 +16,7 @@
using Nethermind.State;
using Nethermind.State.Witnesses;
using Nethermind.Trie.Pruning;
+using NSubstitute;
using NUnit.Framework;
namespace Nethermind.Trie.Test.Pruning
@@ -822,6 +823,7 @@ public void After_commit_should_have_has_root()
trieStore.HasRoot(stateTree.RootHash).Should().BeTrue();
}
+ [Test]
public async Task Will_RemovePastKeys_OnSnapshot()
{
MemDb memDb = new();
@@ -854,6 +856,35 @@ public async Task Will_RemovePastKeys_OnSnapshot()
}
}
+ [Test]
+ public async Task Will_Not_RemovePastKeys_OnSnapshot_DuringFullPruning()
+ {
+ MemDb memDb = new();
+
+ IPersistenceStrategy isPruningPersistenceStrategy = Substitute.For();
+ isPruningPersistenceStrategy.IsFullPruning.Returns(true);
+
+ using TrieStore fullTrieStore = CreateTrieStore(
+ kvStore: memDb,
+ pruningStrategy: new TestPruningStrategy(true, true, 100000),
+ persistenceStrategy: isPruningPersistenceStrategy,
+ reorgDepthOverride: 2);
+
+ IScopedTrieStore trieStore = fullTrieStore.GetTrieStore(null);
+
+ for (int i = 0; i < 64; i++)
+ {
+ TrieNode node = new(NodeType.Leaf, TestItem.Keccaks[i], new byte[2]);
+ trieStore.CommitNode(i, new NodeCommitInfo(node, TreePath.Empty));
+ trieStore.FinishBlockCommit(TrieType.State, i, node);
+
+ // Pruning is done in background
+ await Task.Delay(TimeSpan.FromMilliseconds(10));
+ }
+
+ memDb.Count.Should().Be(61);
+ }
+
[Test]
public async Task Will_NotRemove_ReCommittedNode()
{
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs b/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs
index 8e534c70c68..1b70bec140d 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/Archive.cs
@@ -13,5 +13,7 @@ public bool ShouldPersist(long blockNumber)
{
return true;
}
+
+ public bool IsFullPruning => false;
}
}
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs
index 25fdd5e4ed8..25653237786 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/CompositePersistenceStrategy.cs
@@ -22,4 +22,5 @@ public IPersistenceStrategy AddStrategy(IPersistenceStrategy strategy)
}
public bool ShouldPersist(long blockNumber) => _strategies.Any(strategy => strategy.ShouldPersist(blockNumber));
+ public bool IsFullPruning => _strategies.Any(strategy => strategy.IsFullPruning);
}
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs b/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs
index 69ce05438ca..671663d2aec 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/IPersistenceStrategy.cs
@@ -6,5 +6,6 @@ namespace Nethermind.Trie.Pruning
public interface IPersistenceStrategy
{
bool ShouldPersist(long blockNumber);
+ bool IsFullPruning { get; }
}
}
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/IntervalSnapshotting.cs b/src/Nethermind/Nethermind.Trie/Pruning/IntervalSnapshotting.cs
index cff18422c7b..a1440f92b50 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/IntervalSnapshotting.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/IntervalSnapshotting.cs
@@ -16,5 +16,7 @@ public bool ShouldPersist(long blockNumber)
{
return blockNumber % _snapshotInterval == 0;
}
+
+ public bool IsFullPruning => false;
}
}
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs b/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs
index 41f788f3996..4d6d560cec4 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/NoPersistence.cs
@@ -13,5 +13,7 @@ public bool ShouldPersist(long blockNumber)
{
return false;
}
+
+ public bool IsFullPruning => false;
}
}
diff --git a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs
index 2343bd85bbf..dfcc38a20a4 100644
--- a/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs
+++ b/src/Nethermind/Nethermind.Trie/Pruning/TrieStore.cs
@@ -636,9 +636,16 @@ private bool CanPruneCacheFurther()
_commitSetQueue.Enqueue(toAddBack[index]);
}
+ bool shouldDeletePersistedNode =
+ // Its disabled
+ _pastPathHash != null &&
+ // Full pruning need to visit all node, so can't delete anything.
+ !_persistenceStrategy.IsFullPruning &&
+ // If more than one candidate set, its a reorg, we can't remove node as persisted node may not be canonical
+ candidateSets.Count == 1;
+
Dictionary<(Hash256?, TinyTreePath), Hash256?>? persistedHashes =
- // If its a reorg, we can't remove node as persisted node may not be canonical
- _pastPathHash != null && candidateSets.Count == 1
+ shouldDeletePersistedNode
? new Dictionary<(Hash256?, TinyTreePath), Hash256?>()
: null;