Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,31 @@ public void Test_OnReorg_RebuildSet()

tracker.HasStateRoot(Keccak.Compute(100.ToBigEndianByteArray())).Should().BeTrue();
}

[Test]
public void Test_TrackLastN_WithCustomDepth()
{
System.Collections.Generic.List<Block> blocks = new();
Block currentBlock = Build.A.Block.Genesis.TestObject;
blocks.Add(currentBlock);
for (int i = 0; i < 300; i++)
{
currentBlock = Build.A.Block
.WithParent(currentBlock)
.WithStateRoot(Keccak.Compute(i.ToBigEndianByteArray()))
.TestObject;
blocks.Add(currentBlock);
}

BlockTree tree = Build.A.BlockTree().WithBlocks(blocks.ToArray()).TestObject;

// Test with a custom depth of 256 blocks (useful for networks with fast block times like Arbitrum)
LastNStateRootTracker tracker = new LastNStateRootTracker(tree, 256);

for (int i = 0; i < 320; i++)
{
tracker.HasStateRoot(Keccak.Compute(i.ToBigEndianByteArray()))
.Should().Be(i is >= 44 and < 300);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public interface ISyncConfig : IConfig
[ConfigItem(Description = "_Technical._ Whether to enable snap serving. WARNING: Very slow on hash db layout. Default is to enable on halfpath layout.", DefaultValue = "null", HiddenFromDocs = true)]
bool? SnapServingEnabled { get; set; }

[ConfigItem(Description = "The maximum depth (in blocks) for serving snap sync requests. Higher values allow serving requests for older blocks, useful for networks with fast block times like Arbitrum.", DefaultValue = "128")]
int SnapServingMaxDepth { get; set; }

[ConfigItem(Description = "_Technical._ MultiSyncModeSelector sync mode timer loop interval. Used for testing.", DefaultValue = "1000", HiddenFromDocs = true)]
int MultiSyncModeSelectorLoopTimerMs { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public string? PivotHash
public int ExitOnSyncedWaitTimeSec { get; set; } = 60;
public int MallocTrimIntervalSec { get; set; } = 300;
public bool? SnapServingEnabled { get; set; } = null;
public int SnapServingMaxDepth { get; set; } = 128;
public int MultiSyncModeSelectorLoopTimerMs { get; set; } = 1000;
public int SyncDispatcherEmptyRequestDelayMs { get; set; } = 10;
public int SyncDispatcherAllocateTimeoutMs { get; set; } = 1000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

namespace Nethermind.Blockchain.Utils;

// TODO: Move responsibility to IWorldStateManager? Could be, but if IWorldStateManager store more than 128 blocks
// of state, that would be out of spec for snap and it would fail hive test.
// TODO: Move responsibility to IWorldStateManager? Could be, but if IWorldStateManager stores more blocks
// of state than configured, that would require updating the snap serving configuration (ISyncConfig.SnapServingMaxDepth).
public class LastNStateRootTracker : ILastNStateRootTracker, IDisposable
{
private readonly IBlockTree _blockTree;
Expand Down
8 changes: 4 additions & 4 deletions src/Nethermind/Nethermind.Init/PruningTrieStateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ILogManager logManager
trieStore,
dbProvider,
logManager,
new LastNStateRootTracker(blockTree, 128));
new LastNStateRootTracker(blockTree, syncConfig.SnapServingMaxDepth));

// NOTE: Don't forget this! Very important!
TrieStoreBoundaryWatcher trieStoreBoundaryWatcher = new(stateManager, blockTree!, logManager);
Expand Down Expand Up @@ -190,10 +190,10 @@ ILogManager logManager

AdviseConfig(pruningConfig, dbConfig, hardwareInfo);

if (syncConfig.SnapServingEnabled == true && pruningConfig.PruningBoundary < 128)
if (syncConfig.SnapServingEnabled == true && pruningConfig.PruningBoundary < syncConfig.SnapServingMaxDepth)
{
if (_logger.IsInfo) _logger.Info($"Snap serving enabled, but {nameof(pruningConfig.PruningBoundary)} is less than 128. Setting to 128.");
pruningConfig.PruningBoundary = 128;
if (_logger.IsInfo) _logger.Info($"Snap serving enabled, but {nameof(pruningConfig.PruningBoundary)} is less than {syncConfig.SnapServingMaxDepth}. Setting to {syncConfig.SnapServingMaxDepth}.");
pruningConfig.PruningBoundary = syncConfig.SnapServingMaxDepth;
}

if (pruningConfig.PruningBoundary < 64)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Autofac;
using FluentAssertions;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Config;
using Nethermind.Core;
using Nethermind.Core.Crypto;
Expand Down Expand Up @@ -76,10 +77,10 @@ public void ShouldNotSupportHashLookupOnHalfpath(INodeStorage.KeyScheme keySchem
public void ShouldAnnounceReorgOnDispose()
{
int lastBlock = 256;
int reorgDepth = 128; // Default reorg depth with snap serving

IBlockTree blockTree = Substitute.For<IBlockTree>();
IConfigProvider configProvider = new ConfigProvider();
int reorgDepth = configProvider.GetConfig<ISyncConfig>().SnapServingMaxDepth;

{
using IContainer ctx = new ContainerBuilder()
Expand Down
4 changes: 4 additions & 0 deletions src/Nethermind/Nethermind.State/Snap/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ namespace Nethermind.State.Snap
{
public class Constants
{
/// <summary>
/// Maximum distance from head for pivot block validation in merge/beacon chain sync.
/// Note: For snap serving depth configuration, use ISyncConfig.SnapServingMaxDepth instead.
/// </summary>
public const int MaxDistanceFromHead = 128;
}
}
Loading