Skip to content
Open
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
2 changes: 0 additions & 2 deletions src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Consensus;
using Nethermind.Core;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Modules;
Expand All @@ -19,7 +18,6 @@ public interface IApiWithNetwork : IApiWithBlockchain

IIPResolver IpResolver { get; }
IMessageSerializationService MessageSerializationService { get; }
IGossipPolicy GossipPolicy { get; set; }
IPeerManager? PeerManager { get; }
IProtocolsManager? ProtocolsManager { get; set; }
IProtocolValidator ProtocolValidator { get; }
Expand Down
1 change: 0 additions & 1 deletion src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ ILifetimeScope Context
public IKeyStore? KeyStore { get; set; }
public ILogManager LogManager => _dependencies.LogManager;
public IMessageSerializationService MessageSerializationService => Context.Resolve<IMessageSerializationService>();
public IGossipPolicy GossipPolicy { get; set; } = Policy.FullGossip;
public IPeerManager? PeerManager => Context.Resolve<IPeerManager>();
public IProtocolsManager? ProtocolsManager { get; set; }
public IProtocolValidator ProtocolValidator => Context.Resolve<IProtocolValidator>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ protected override void Load(ContainerBuilder builder)

.AddDecorator<IRewardCalculatorSource, MergeRewardCalculatorSource>()

// Validators
.AddDecorator<IGossipPolicy, MergeGossipPolicy>()
.AddSingleton<IBlockPreprocessorStep, MergeProcessingRecoveryStep>()

.AddDecorator<IBlockProductionPolicy, MergeBlockProductionPolicy>()
Expand Down
2 changes: 2 additions & 0 deletions src/Nethermind/Nethermind.Init/Modules/NetworkModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Autofac;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Config;
using Nethermind.Consensus;
using Nethermind.Core;
using Nethermind.Core.Container;
using Nethermind.Core.Crypto;
Expand Down Expand Up @@ -47,6 +48,7 @@ protected override void Load(ContainerBuilder builder)
.AddCompositeOrderedComponents<ITxGossipPolicy, CompositeTxGossipPolicy>(singleInstance: true)
.AddSingleton<IIPResolver, IPResolver>()
.AddSingleton<IForkInfo, ForkInfo>()
.AddSingleton<IGossipPolicy>(Policy.FullGossip)

// Rlpxhost
.AddSingleton<IDisconnectsAnalyzer, MetricsDisconnectsAnalyzer>()
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ protected override void Load(ContainerBuilder builder) => builder
.AddDecorator<IUnclesValidator, MergeUnclesValidator>()
.AddDecorator<ISealValidator, MergeSealValidator>()
.AddDecorator<ISealer, MergeSealer>()
.AddDecorator<IGossipPolicy, MergeGossipPolicy>()

// Merge-aware override: skips wiring the branch processor on post-merge chains so
// the AuRa finalization manager's startup catch-up walk never runs.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
using Nethermind.Crypto;
using Nethermind.Merge.Plugin.Handlers;
using Nethermind.Synchronization;
using NSubstitute;
using NUnit.Framework;

namespace Nethermind.Merge.Plugin.Test;
Expand Down Expand Up @@ -37,15 +40,13 @@ public void prunes_highest_unprotected_block_and_returns_false_when_added_block_
[Test]
public void preserves_head_and_finalized_blocks_when_pruning()
{
BlockCacheService blockCacheService = new(2);
Block finalizedBlock = Build.A.Block.WithNumber(1).TestObject;
Block block2 = Build.A.Block.WithNumber(2).TestObject;
Block headBlock = Build.A.Block.WithNumber(3).TestObject;
Hash256 finalizedHash = finalizedBlock.GetOrCalculateHash();
Hash256 block2Hash = block2.GetOrCalculateHash();
Hash256 headHash = headBlock.GetOrCalculateHash();
blockCacheService.FinalizedHash = finalizedHash;
blockCacheService.HeadBlockHash = headHash;
BlockCacheService blockCacheService = new(2, ProtectingStrategy(finalizedHash, headHash));

Assert.That(blockCacheService.TryAddBlock(finalizedBlock), Is.True);
Assert.That(blockCacheService.TryAddBlock(block2), Is.True);
Expand All @@ -60,13 +61,11 @@ public void preserves_head_and_finalized_blocks_when_pruning()
[Test]
public void preserves_protected_blocks_when_all_candidates_are_protected()
{
BlockCacheService blockCacheService = new(1);
Block finalizedBlock = Build.A.Block.WithNumber(1).TestObject;
Block headBlock = Build.A.Block.WithNumber(2).TestObject;
Hash256 finalizedHash = finalizedBlock.GetOrCalculateHash();
Hash256 headHash = headBlock.GetOrCalculateHash();
blockCacheService.FinalizedHash = finalizedHash;
blockCacheService.HeadBlockHash = headHash;
BlockCacheService blockCacheService = new(1, ProtectingStrategy(finalizedHash, headHash));

Assert.That(blockCacheService.TryAddBlock(finalizedBlock), Is.True);
Assert.That(blockCacheService.TryAddBlock(headBlock), Is.True);
Expand All @@ -75,4 +74,26 @@ public void preserves_protected_blocks_when_all_candidates_are_protected()
Assert.That(blockCacheService.BlockCache.ContainsKey(finalizedHash), Is.True);
Assert.That(blockCacheService.BlockCache.ContainsKey(headHash), Is.True);
}

[Test]
public void clears_cache_when_beacon_sync_stops()
{
IBeaconSyncStrategy beaconSyncStrategy = Substitute.For<IBeaconSyncStrategy>();
BlockCacheService blockCacheService = new(4, beaconSyncStrategy);
blockCacheService.TryAddBlock(Build.A.Block.WithNumber(1).TestObject);
blockCacheService.TryAddBlock(Build.A.Block.WithNumber(2).TestObject);
Assert.That(blockCacheService.BlockCache, Has.Count.EqualTo(2));

beaconSyncStrategy.BeaconSyncStopped += Raise.Event<Action>();

Assert.That(blockCacheService.BlockCache, Is.Empty);
}

private static IBeaconSyncStrategy ProtectingStrategy(Hash256 finalizedHash, Hash256 headHash)
{
IBeaconSyncStrategy beaconSyncStrategy = Substitute.For<IBeaconSyncStrategy>();
beaconSyncStrategy.GetFinalizedHash().Returns(finalizedHash);
beaconSyncStrategy.GetHeadBlockHash().Returns(headHash);
return beaconSyncStrategy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
using Nethermind.Merge.Plugin.Handlers;
using Nethermind.Synchronization;
using Nethermind.Trie.Pruning;
using NSubstitute;
using NUnit.Framework;
Expand All @@ -22,16 +22,16 @@ public class MergeFinalizedStateProviderTests
private IBlockTree _blockTree = null!;
private IFinalizedStateProvider _baseFinalizedStateProvider = null!;
private MergeFinalizedStateProvider _provider = null!;
private IBlockCacheService _blockCacheService;
private IBeaconSyncStrategy _beaconSyncStrategy;

[SetUp]
public void Setup()
{
_poSSwitcher = Substitute.For<IPoSSwitcher>();
_blockTree = Substitute.For<IBlockTree>();
_baseFinalizedStateProvider = Substitute.For<IFinalizedStateProvider>();
_blockCacheService = Substitute.For<IBlockCacheService>();
_provider = new MergeFinalizedStateProvider(_poSSwitcher, _blockCacheService, _blockTree, _baseFinalizedStateProvider);
_beaconSyncStrategy = Substitute.For<IBeaconSyncStrategy>();
_provider = new MergeFinalizedStateProvider(_poSSwitcher, _beaconSyncStrategy, _blockTree, _baseFinalizedStateProvider);
}

[Test]
Expand Down Expand Up @@ -79,7 +79,7 @@ public void FinalizedBlockNumber_AfterTransition_WithBlockCacheFinalizedHash_Ret
BlockHeader finalizedHeader = Build.A.BlockHeader.WithNumber(expectedBlockNumber).WithHash(finalizedHash).TestObject;
_poSSwitcher.TransitionFinished.Returns(true);
_blockTree.FinalizedHash.Returns((Hash256?)null);
_blockCacheService.FinalizedHash.Returns(finalizedHash);
_beaconSyncStrategy.GetFinalizedHash().Returns(finalizedHash);
_blockTree.FindHeader(finalizedHash).Returns(finalizedHeader);

// Act
Expand All @@ -104,7 +104,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHasHigherNumber_Retur
_poSSwitcher.TransitionFinished.Returns(true);
_blockTree.FinalizedHash.Returns(blockTreeHash);
_blockTree.FindHeader(blockTreeHash, BlockTreeLookupOptions.None).Returns(blockTreeHeader);
_blockCacheService.FinalizedHash.Returns(blockCacheHash);
_beaconSyncStrategy.GetFinalizedHash().Returns(blockCacheHash);
_blockTree.FindHeader(blockCacheHash).Returns(blockCacheHeader);

// Act
Expand All @@ -128,7 +128,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockTreeHasHigherNumber_Return
_poSSwitcher.TransitionFinished.Returns(true);
_blockTree.FinalizedHash.Returns(blockTreeHash);
_blockTree.FindHeader(blockTreeHash, BlockTreeLookupOptions.None).Returns(blockTreeHeader);
_blockCacheService.FinalizedHash.Returns(blockCacheHash);
_beaconSyncStrategy.GetFinalizedHash().Returns(blockCacheHash);
_blockTree.FindHeader(blockCacheHash).Returns(blockCacheHeader);

// Act
Expand All @@ -150,7 +150,7 @@ public void FinalizedBlockNumber_AfterTransition_BlockCacheHeaderNotFound_UsesOn
_poSSwitcher.TransitionFinished.Returns(true);
_blockTree.FinalizedHash.Returns(blockTreeHash);
_blockTree.FindHeader(blockTreeHash, BlockTreeLookupOptions.None).Returns(blockTreeHeader);
_blockCacheService.FinalizedHash.Returns(blockCacheHash);
_beaconSyncStrategy.GetFinalizedHash().Returns(blockCacheHash);
_blockTree.FindHeader(blockCacheHash).Returns((BlockHeader?)null);

// Act
Expand All @@ -167,7 +167,7 @@ public void FinalizedBlockNumber_AfterTransition_NoFinalizedHeaders_DelegatesToB
long expectedBlockNumber = 150;
_poSSwitcher.TransitionFinished.Returns(true);
_blockTree.FinalizedHash.Returns((Hash256?)null);
_blockCacheService.FinalizedHash.Returns((Hash256?)null);
_beaconSyncStrategy.GetFinalizedHash().Returns((Hash256?)null);
_baseFinalizedStateProvider.FinalizedBlockNumber.Returns(expectedBlockNumber);

// Act
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public async Task Initializes_correctly()
await _plugin.InitNetworkProtocol();
ISyncConfig syncConfig = api.Config<ISyncConfig>();
Assert.That(syncConfig.NetworkingEnabled, Is.True);
Assert.That(api.GossipPolicy.CanGossipBlocks, Is.True);
Assert.That(container.Resolve<IGossipPolicy>().CanGossipBlocks, Is.True);
IBlockProducer blockProducer = container.Resolve<IBlockProducerFactory>().InitBlockProducer();
Assert.That(blockProducer, Is.InstanceOf<MergeBlockProducer>());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public IBeaconPivot BeaconPivot
}

private BeaconSync? _beaconSync;
public BeaconSync BeaconSync => _beaconSync ??= new(BeaconPivot, BlockTree, SyncConfig, BlockCacheService, PoSSwitcher, LimboLogs.Instance);
public BeaconSync BeaconSync => _beaconSync ??= new(BeaconPivot, BlockTree, SyncConfig, PoSSwitcher, LimboLogs.Instance);

private IDb? _metadataDb;
public IDb MetadataDb => _metadataDb ??= new MemDb();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Crypto;
using Nethermind.Synchronization;

namespace Nethermind.Merge.Plugin.Handlers;

Expand All @@ -16,35 +17,34 @@ namespace Nethermind.Merge.Plugin.Handlers;
public class BlockCacheService : IBlockCacheService
{
private readonly int _maxCachedBlocks;
private readonly IBeaconSyncStrategy _beaconSyncStrategy;
private readonly ConcurrentDictionary<Hash256AsKey, Block> _blockCache = new();

/// <summary>
/// Initializes a block cache with the default merge sync bound.
/// </summary>
public BlockCacheService()
: this((int)(Reorganization.MaxDepth * 2 + 16))
/// <param name="beaconSyncStrategy">Source of the finalized/head hashes protected from pruning. Defaults to <see cref="No.BeaconSync"/>.</param>
public BlockCacheService(IBeaconSyncStrategy? beaconSyncStrategy = null)
: this((int)(Reorganization.MaxDepth * 2 + 16), beaconSyncStrategy)
{
}

/// <summary>
/// Initializes a block cache with the provided maximum number of cached blocks.
/// </summary>
/// <param name="maxCachedBlocks">Maximum number of cached blocks before pruning unprotected entries.</param>
public BlockCacheService(int maxCachedBlocks)
/// <param name="beaconSyncStrategy">Source of the finalized/head hashes protected from pruning. Defaults to <see cref="No.BeaconSync"/>.</param>
public BlockCacheService(int maxCachedBlocks, IBeaconSyncStrategy? beaconSyncStrategy = null)
{
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maxCachedBlocks);
_maxCachedBlocks = maxCachedBlocks;
_beaconSyncStrategy = beaconSyncStrategy ?? No.BeaconSync;
_beaconSyncStrategy.BeaconSyncStopped += Clear;
}

/// <inheritdoc />
public IReadOnlyDictionary<Hash256AsKey, Block> BlockCache => _blockCache;

/// <inheritdoc />
public Hash256? FinalizedHash { get; set; }

/// <inheritdoc />
public Hash256? HeadBlockHash { get; set; }

/// <inheritdoc />
public bool TryAddBlock(Block block)
{
Expand Down Expand Up @@ -101,5 +101,5 @@ private bool TryGetHighestNumberedUnprotectedBlock(out Hash256AsKey blockHash)
}

private bool IsProtected(Hash256AsKey blockHash) =>
Equals(blockHash.Value, FinalizedHash) || Equals(blockHash.Value, HeadBlockHash);
Equals(blockHash.Value, _beaconSyncStrategy.GetFinalizedHash()) || Equals(blockHash.Value, _beaconSyncStrategy.GetHeadBlockHash());
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ protected virtual bool IsOnMainChainBehindFinalized(BlockHeader newHeadHeader, F
if (processingQueueCount == 0)
{
peerRefresher.RefreshPeers(newHeadHeader.Hash!, newHeadHeader.ParentHash!, finalizedBlockHash);
blockCacheService.FinalizedHash = finalizedBlockHash;
blockCacheService.HeadBlockHash = forkchoiceState.HeadBlockHash;
mergeSyncController.SetForkchoiceHashes(finalizedBlockHash, forkchoiceState.HeadBlockHash);
mergeSyncController.StopBeaconModeControl();

// Debug as already output in Received ForkChoice
Expand Down Expand Up @@ -336,8 +335,7 @@ private void StartNewBeaconHeaderSync(ForkchoiceStateV1 forkchoiceState, BlockHe
mergeSyncController.InitBeaconHeaderSync(blockHeader);
beaconPivot.ProcessDestination = blockHeader;
peerRefresher.RefreshPeers(blockHeader.Hash!, blockHeader.ParentHash!, forkchoiceState.FinalizedBlockHash);
blockCacheService.FinalizedHash = forkchoiceState.FinalizedBlockHash;
blockCacheService.HeadBlockHash = forkchoiceState.HeadBlockHash;
mergeSyncController.SetForkchoiceHashes(forkchoiceState.FinalizedBlockHash, forkchoiceState.HeadBlockHash);

if (_logger.IsInfo) _logger.Info($"Start a new sync process, Request: {requestStr}.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@ public interface IBlockCacheService
/// </summary>
public IReadOnlyDictionary<Hash256AsKey, Block> BlockCache { get; }

/// <summary>
/// Finalized block hash protected from cache pruning.
/// </summary>
Hash256? FinalizedHash { get; set; }

/// <summary>
/// Head block hash protected from cache pruning.
/// </summary>
Hash256? HeadBlockHash { get; set; }

/// <summary>
/// Adds a block to the bounded cache.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
using Nethermind.Consensus;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Merge.Plugin.Handlers;
using Nethermind.Synchronization;
using Nethermind.Trie.Pruning;

namespace Nethermind.Merge.Plugin;

public class MergeFinalizedStateProvider(IPoSSwitcher poSSwitcher, IBlockCacheService blockCacheService, IBlockTree blockTree, IFinalizedStateProvider baseFinalizedStateProvider) : IFinalizedStateProvider
public class MergeFinalizedStateProvider(IPoSSwitcher poSSwitcher, IBeaconSyncStrategy beaconSyncStrategy, IBlockTree blockTree, IFinalizedStateProvider baseFinalizedStateProvider) : IFinalizedStateProvider
{
public long FinalizedBlockNumber
{
Expand All @@ -25,10 +25,10 @@ public long FinalizedBlockNumber
}

// Finalized hash from blocktree is not updated until it is processed, which is a problem for long
// catchup. So we use from blockCacheService as a backup.
if (blockCacheService.FinalizedHash is { } blockCacheFinalizedHash)
// catchup. So we use the beacon sync strategy's finalized hash as a backup.
if (beaconSyncStrategy.GetFinalizedHash() is { } beaconFinalizedHash)
{
BlockHeader? fromBlockCache = blockTree.FindHeader(blockCacheFinalizedHash);
BlockHeader? fromBlockCache = blockTree.FindHeader(beaconFinalizedHash);
if (fromBlockCache is not null)
{
if (currentFinalized is null || fromBlockCache.Number > currentFinalized.Number)
Expand Down
Loading
Loading