diff --git a/src/Nethermind/Directory.Packages.props b/src/Nethermind/Directory.Packages.props
index 253c598a39d..b7fae1de28d 100644
--- a/src/Nethermind/Directory.Packages.props
+++ b/src/Nethermind/Directory.Packages.props
@@ -6,6 +6,8 @@
+
+
@@ -36,6 +38,7 @@
+
diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
index 61bceb25ae4..da24eaa918b 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
#nullable enable
+using Autofac;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.FullPruning;
@@ -100,5 +101,12 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
INodeStorageFactory NodeStorageFactory { get; set; }
BackgroundTaskScheduler BackgroundTaskScheduler { get; set; }
CensorshipDetector CensorshipDetector { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromApiWithStores(builder)
+ .AddPropertiesFrom(this)
+ .AddSingleton(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb));
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
index 0f5d2262535..0b0e05e2a6d 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
using System.Collections.Generic;
+using Autofac;
using Nethermind.Consensus;
+using Nethermind.Core;
using Nethermind.Core.PubSub;
using Nethermind.Grpc;
using Nethermind.JsonRpc;
@@ -16,6 +18,7 @@
using Nethermind.Synchronization;
using Nethermind.Synchronization.Peers;
using Nethermind.Sockets;
+using Nethermind.Synchronization.ParallelSync;
namespace Nethermind.Api
{
@@ -41,12 +44,22 @@ public interface IApiWithNetwork : IApiWithBlockchain
IJsonRpcLocalStats? JsonRpcLocalStats { get; set; }
ISessionMonitor? SessionMonitor { get; set; }
IStaticNodesManager? StaticNodesManager { get; set; }
- ISynchronizer? Synchronizer { get; set; }
+ ISynchronizer? Synchronizer { get; }
+ ISyncModeSelector SyncModeSelector { get; }
+ ISyncProgressResolver? SyncProgressResolver { get; }
IPivot? Pivot { get; set; }
ISyncPeerPool? SyncPeerPool { get; set; }
IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; set; }
ISyncServer? SyncServer { get; set; }
IWebSocketsManager WebSocketsManager { get; set; }
ISubscriptionFactory? SubscriptionFactory { get; set; }
+
+ IContainer? ApiWithNetworkServiceContainer { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithNetwork(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromApiWithBlockchain(builder)
+ .AddPropertiesFrom(this);
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs
index fa2911c2ebe..eed8ed62430 100644
--- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs
+++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs
@@ -1,11 +1,13 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
+using Autofac;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Consensus;
+using Nethermind.Core;
using Nethermind.Crypto;
using Nethermind.Db.Blooms;
using Nethermind.Facade.Find;
@@ -30,5 +32,11 @@ public interface IApiWithStores : IBasicApi
IReceiptMonitor? ReceiptMonitor { get; set; }
IWallet? Wallet { get; set; }
IBlockStore? BadBlocksStore { get; set; }
+
+ public ContainerBuilder ConfigureContainerBuilderFromApiWithStores(ContainerBuilder builder)
+ {
+ return ConfigureContainerBuilderFromBasicApi(builder)
+ .AddPropertiesFrom(this);
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs
index 3b78f16a865..1ba0adb91f9 100644
--- a/src/Nethermind/Nethermind.Api/IBasicApi.cs
+++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs
@@ -1,11 +1,14 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
+using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
+using Autofac;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
+using Nethermind.Blockchain.Synchronization;
using Nethermind.Config;
using Nethermind.Core;
using Nethermind.Core.Specs;
@@ -17,7 +20,6 @@
using Nethermind.Serialization.Json;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Synchronization;
-using Nethermind.Synchronization.ParallelSync;
namespace Nethermind.Api
{
@@ -38,10 +40,9 @@ public interface IBasicApi
ILogManager LogManager { get; set; }
ProtectedPrivateKey? OriginalSignerKey { get; set; }
IReadOnlyList Plugins { get; }
+ [SkipServiceCollection]
string SealEngineType { get; set; }
ISpecProvider? SpecProvider { get; set; }
- ISyncModeSelector SyncModeSelector { get; set; }
- ISyncProgressResolver? SyncProgressResolver { get; set; }
IBetterPeerStrategy? BetterPeerStrategy { get; set; }
ITimestamper Timestamper { get; }
ITimerFactory TimerFactory { get; }
@@ -57,5 +58,16 @@ public IEnumerable GetConsensusWrapperPlugins() =>
public IEnumerable GetSynchronizationPlugins() =>
Plugins.OfType();
+
+ public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder builder)
+ {
+ builder
+ .AddPropertiesFrom(this)
+ .AddSingleton(ConfigProvider.GetConfig());
+
+ DbProvider!.ConfigureServiceCollection(builder);
+
+ return builder;
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs
index 56193492d01..566a094eaa0 100644
--- a/src/Nethermind/Nethermind.Api/NethermindApi.cs
+++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO.Abstractions;
+using Autofac;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
using Nethermind.Blockchain;
@@ -186,14 +187,14 @@ public ISealEngine SealEngine
public ISessionMonitor? SessionMonitor { get; set; }
public ISpecProvider? SpecProvider { get; set; }
public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance;
- public ISyncModeSelector SyncModeSelector { get; set; } = null!;
+ public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.Resolve()!;
- public ISyncProgressResolver? SyncProgressResolver { get; set; }
+ public ISyncProgressResolver? SyncProgressResolver => ApiWithNetworkServiceContainer?.Resolve();
public IBetterPeerStrategy? BetterPeerStrategy { get; set; }
public IPivot? Pivot { get; set; }
public ISyncPeerPool? SyncPeerPool { get; set; }
public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; set; }
- public ISynchronizer? Synchronizer { get; set; }
+ public ISynchronizer? Synchronizer => ApiWithNetworkServiceContainer?.Resolve();
public ISyncServer? SyncServer { get; set; }
public IWorldState? WorldState { get; set; }
public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
@@ -243,5 +244,7 @@ public ISealEngine SealEngine
public CompositePruningTrigger PruningTrigger { get; } = new();
public IProcessExitSource? ProcessExit { get; set; }
public CompositeTxGossipPolicy TxGossipPolicy { get; } = new();
+
+ public IContainer? ApiWithNetworkServiceContainer { get; set; }
}
}
diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
index 35c6c3fc1ac..cfee2a225fd 100644
--- a/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
+++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/ISyncConfig.cs
@@ -143,4 +143,7 @@ public interface ISyncConfig : IConfig
[ConfigItem(Description = "_Technical._ MultiSyncModeSelector sync mode timer loop interval. Used for testing.", DefaultValue = "1000", HiddenFromDocs = true)]
int MultiSyncModeSelectorLoopTimerMs { get; set; }
+
+ [ConfigItem(Description = "_Technical._ MultiSyncModeSelector will wait for header to completely sync first.", DefaultValue = "false", HiddenFromDocs = true)]
+ bool NeedToWaitForHeader { get; set; }
}
diff --git a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
index d2645336586..c467650ca7a 100644
--- a/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
+++ b/src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs
@@ -65,6 +65,7 @@ public string? PivotHash
public int MallocTrimIntervalSec { get; set; } = 300;
public bool? SnapServingEnabled { get; set; } = null;
public int MultiSyncModeSelectorLoopTimerMs { get; set; } = 1000;
+ public bool NeedToWaitForHeader { get; set; }
public bool TrieHealing { get; set; } = true;
public override string ToString()
diff --git a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs
new file mode 100644
index 00000000000..28e890c8499
--- /dev/null
+++ b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs
@@ -0,0 +1,113 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using Autofac;
+using FluentAssertions;
+using NUnit.Framework;
+
+namespace Nethermind.Core.Test;
+
+public class ContainerBuilderExtensionsTests
+{
+ [Test]
+ public void AddPropertiesFrom_CanAddProperties()
+ {
+ ITestInterface interfaceImplementation = new InterfaceImplementation();
+ IContainer sp = new ContainerBuilder()
+ .AddPropertiesFrom(interfaceImplementation)
+ .Build();
+
+ sp.ResolveOptional().Should().NotBeNull();
+ sp.ResolveOptional().Should().BeNull();
+ sp.ResolveOptional().Should().BeNull();
+ sp.ResolveOptional().Should().BeNull();
+ }
+
+ [Test]
+ public void TestRegisterNamedComponent()
+ {
+ IContainer sp = new ContainerBuilder()
+ .AddScoped()
+ .AddScoped()
+ .RegisterNamedComponentInItsOwnLifetime("custom", cfg =>
+ {
+ // Override it in custom
+ cfg.AddScoped();
+ })
+ .Build();
+
+ using (ILifetimeScope scope = sp.BeginLifetimeScope())
+ {
+ scope.Resolve().Property.Should().BeOfType();
+ }
+
+ MainComponentDependency customMainComponentDependency = sp.ResolveNamed("custom").Property;
+ sp.ResolveNamed("custom").Property.Should().BeOfType();
+
+ sp.Dispose();
+
+ customMainComponentDependency.WasDisposed.Should().BeTrue();
+ }
+
+ private class MainComponent(MainComponentDependency mainComponentDependency, ILifetimeScope scope) : IDisposable
+ {
+ public MainComponentDependency Property => mainComponentDependency;
+
+ public void Dispose()
+ {
+ scope.Dispose();
+ }
+ }
+
+ private class MainComponentDependency : IDisposable
+ {
+ public bool WasDisposed { get; set; }
+
+ public void Dispose()
+ {
+ WasDisposed = true;
+ }
+ }
+
+ private class MainComponentDependencySubClass : MainComponentDependency
+ {
+ }
+
+ private class InterfaceImplementation : ITestInterface
+ {
+ public DeclaredService TheService { get; set; } = new DeclaredService();
+ public DeclaredButNullService? NullService { get; set; } = null;
+ public Ignored IgnoredService { get; set; } = new Ignored();
+ public DeclaredInBase BaseService { get; set; } = new DeclaredInBase();
+ }
+
+ private interface ITestInterface : ITestInterfaceBase
+ {
+ DeclaredService TheService { get; set; }
+ DeclaredButNullService? NullService { get; set; }
+
+ [SkipServiceCollection]
+ Ignored IgnoredService { get; set; }
+ }
+
+ private interface ITestInterfaceBase
+ {
+ DeclaredInBase BaseService { get; set; }
+ }
+
+ private class DeclaredInBase { }
+ private class DeclaredService { }
+ private class DeclaredButNullService { }
+ private class Ignored { }
+
+ private class DisposableService : IDisposable
+ {
+ public bool WasDisposed { get; set; } = false;
+
+ public void Dispose()
+ {
+ WasDisposed = true;
+ }
+ }
+}
diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs
new file mode 100644
index 00000000000..1c30a830b55
--- /dev/null
+++ b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs
@@ -0,0 +1,125 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Autofac;
+using Autofac.Features.AttributeFilters;
+
+namespace Nethermind.Core;
+
+public static class ContainerBuilderExtensions
+{
+ ///
+ /// Add all properties as singleton. It get them ahead of time instead of lazily to prevent the final service provider
+ /// from disposing it. To prevent a property from being included, use .
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static ContainerBuilder AddPropertiesFrom(this ContainerBuilder configuration, T source) where T : class
+ {
+ Type t = typeof(T);
+
+ IEnumerable properties = t
+ .GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
+ .Where(p => p.GetCustomAttribute() == null);
+
+ foreach (PropertyInfo propertyInfo in properties)
+ {
+ object? val = propertyInfo.GetValue(source);
+ if (val != null)
+ {
+ configuration.RegisterInstance(val).As(propertyInfo.PropertyType);
+ }
+ }
+
+ return configuration;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .WithAttributeFiltering()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder, T instance) where T : class
+ {
+ builder.RegisterInstance(instance)
+ .As()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) where TImpl : notnull where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .AsSelf()
+ .WithAttributeFiltering()
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddKeyedSingleton(this ContainerBuilder builder, string key, T instance) where T : class
+ {
+ builder.RegisterInstance(instance)
+ .Named(key)
+ .SingleInstance();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddScoped(this ContainerBuilder builder) where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .AsSelf()
+ .WithAttributeFiltering()
+ .InstancePerLifetimeScope();
+
+ return builder;
+ }
+
+ public static ContainerBuilder AddScoped(this ContainerBuilder builder) where TImpl : notnull where T : notnull
+ {
+ builder.RegisterType()
+ .As()
+ .WithAttributeFiltering()
+ .InstancePerLifetimeScope();
+
+ return builder;
+ }
+
+ ///
+ /// A convenient way of creating a service whose member can be configured indipendent of other instance of the same
+ /// type (assuming the type is of lifetime scope). This is useful for same type with multiple configuration
+ /// or a graph of multiple same type. The T is expected to be of a main container of sort that contains the
+ /// main service of interest.
+ /// Note: The T should dispose an injected ILifetimeScope on dispose as ILifetimeScope is not automatically disposed
+ /// when parent scope is disposed.
+ ///
+ public static ContainerBuilder RegisterNamedComponentInItsOwnLifetime(this ContainerBuilder builder, string name, Action configurator) where T : notnull
+ {
+ builder.Register(ctx => ctx.BeginLifetimeScope(configurator).Resolve())
+ .Named(name);
+
+ return builder;
+ }
+}
+
+///
+/// Mark a property so that it is not picked up by `AddPropertiesFrom`.
+///
+public class SkipServiceCollectionAttribute : Attribute
+{
+}
diff --git a/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj b/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
index de2832e6ea5..930e96abe48 100644
--- a/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
+++ b/src/Nethermind/Nethermind.Core/Nethermind.Core.csproj
@@ -5,7 +5,10 @@
+
+
+
diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs
index 7786271bc74..6a0380b0446 100644
--- a/src/Nethermind/Nethermind.Db/IDbProvider.cs
+++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs
@@ -3,6 +3,9 @@
using System;
using System.Collections.Generic;
+using Autofac;
+using Microsoft.Extensions.DependencyInjection;
+using Nethermind.Core;
namespace Nethermind.Db
{
@@ -30,5 +33,34 @@ public interface IDbProvider : IDisposable
void RegisterDb(string dbName, T db) where T : class, IDb;
void RegisterColumnDb(string dbName, IColumnsDb db);
IEnumerable> GetAllDbMeta();
+
+ void ConfigureServiceCollection(ContainerBuilder sc)
+ {
+ sc.AddSingleton(this);
+
+ // TODO: Have hooks that automatically get these
+ string[] dbNames = [
+ DbNames.State,
+ DbNames.Code,
+ DbNames.Metadata,
+ DbNames.Blocks,
+ DbNames.Headers,
+ DbNames.BlockInfos,
+ DbNames.BadBlocks,
+ DbNames.Bloom,
+ DbNames.Metadata,
+ ];
+ foreach (string dbName in dbNames)
+ {
+ var db = GetDb(dbName);
+ sc.AddKeyedSingleton(dbName, db);
+ sc.AddKeyedSingleton(dbName, db);
+ sc.AddKeyedSingleton(dbName, db as ITunableDb ?? new NoopTunableDb());
+ }
+
+ IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts);
+ sc.AddSingleton>(receiptColumnDb);
+ sc.AddKeyedSingleton(DbNames.Receipts, receiptColumnDb as ITunableDb ?? new NoopTunableDb());
+ }
}
}
diff --git a/src/Nethermind/Nethermind.Db/ITunableDb.cs b/src/Nethermind/Nethermind.Db/ITunableDb.cs
index 7584364badd..00b0edf0f0c 100644
--- a/src/Nethermind/Nethermind.Db/ITunableDb.cs
+++ b/src/Nethermind/Nethermind.Db/ITunableDb.cs
@@ -3,7 +3,7 @@
namespace Nethermind.Db;
-public interface ITunableDb : IDb
+public interface ITunableDb
{
public void Tune(TuneType type);
@@ -18,3 +18,10 @@ enum TuneType
HashDb
}
}
+
+public class NoopTunableDb : ITunableDb
+{
+ public void Tune(ITunableDb.TuneType type)
+ {
+ }
+}
diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs
index 7f4636d56be..db2854c0003 100644
--- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs
+++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs
@@ -3,9 +3,13 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Api;
using Nethermind.Api.Extensions;
using Nethermind.Blockchain.Synchronization;
@@ -126,39 +130,22 @@ private async Task Initialize(CancellationToken cancellationToken)
if (_api.Synchronizer is null)
{
- BlockDownloaderFactory blockDownloaderFactory = new BlockDownloaderFactory(
- _api.SpecProvider!,
- _api.BlockValidator!,
- _api.SealValidator!,
- _api.BetterPeerStrategy!,
- _api.LogManager);
+ if (_api.ChainSpec.SealEngineType == SealEngineType.Clique)
+ _syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself?
- _api.Synchronizer ??= new Synchronizer(
- _api.DbProvider,
- _api.NodeStorageFactory.WrapKeyValueStore(_api.DbProvider.StateDb),
- _api.SpecProvider!,
- _api.BlockTree,
- _api.ReceiptStorage!,
- _api.SyncPeerPool,
- _api.NodeStatsManager!,
- _syncConfig,
- blockDownloaderFactory,
- _api.Pivot,
- _api.ProcessExit!,
- _api.BetterPeerStrategy,
- _api.ChainSpec,
- _api.StateReader!,
- _api.LogManager);
- }
+ ContainerBuilder builder = new ContainerBuilder();
+ _api.ConfigureContainerBuilderFromApiWithNetwork(builder)
+ .AddSingleton(No.BeaconSync);
+ builder.RegisterModule(new SynchronizerModule(_syncConfig));
+ IContainer container = builder.Build();
- _api.SyncModeSelector = _api.Synchronizer.SyncModeSelector;
- _api.SyncProgressResolver = _api.Synchronizer.SyncProgressResolver;
+ _api.ApiWithNetworkServiceContainer = container;
+ _api.DisposeStack.Append(container);
+ }
_api.EthSyncingInfo = new EthSyncingInfo(_api.BlockTree, _api.ReceiptStorage!, _syncConfig,
- _api.SyncModeSelector, _api.SyncProgressResolver, _api.LogManager);
+ _api.SyncModeSelector!, _api.SyncProgressResolver!, _api.LogManager);
_api.TxGossipPolicy.Policies.Add(new SyncedTxGossipPolicy(_api.SyncModeSelector));
- _api.DisposeStack.Push(_api.SyncModeSelector);
- _api.DisposeStack.Push(_api.Synchronizer);
ISyncServer syncServer = _api.SyncServer = new SyncServer(
_api.TrieStore!.TrieNodeRlpStore,
diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs
index 9d387b5d200..81b83425ace 100644
--- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs
+++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs
@@ -6,6 +6,10 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using Autofac;
+using Autofac.Core;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Api;
using Nethermind.Api.Extensions;
using Nethermind.Blockchain;
@@ -30,6 +34,8 @@
using Nethermind.Merge.Plugin.Handlers;
using Nethermind.Merge.Plugin.InvalidChainTracker;
using Nethermind.Merge.Plugin.Synchronization;
+using Nethermind.Synchronization;
+using Nethermind.Synchronization.Blocks;
using Nethermind.Synchronization.ParallelSync;
using Nethermind.TxPool;
@@ -436,43 +442,24 @@ public Task InitSynchronization()
_api.Pivot = _beaconPivot;
- MergeBlockDownloaderFactory blockDownloaderFactory = new MergeBlockDownloaderFactory(
- _poSSwitcher,
- _beaconPivot,
- _api.SpecProvider,
- _api.BlockValidator!,
- _api.SealValidator!,
- _syncConfig,
- _api.BetterPeerStrategy!,
- new FullStateFinder(_api.BlockTree, _api.StateReader),
- _api.LogManager);
+ ContainerBuilder builder = new ContainerBuilder();
- MergeSynchronizer synchronizer = new MergeSynchronizer(
- _api.DbProvider,
- _api.NodeStorageFactory.WrapKeyValueStore(_api.DbProvider.StateDb),
- _api.SpecProvider!,
- _api.BlockTree!,
- _api.ReceiptStorage!,
- _api.SyncPeerPool,
- _api.NodeStatsManager!,
- _syncConfig,
- blockDownloaderFactory,
- _beaconPivot,
- _poSSwitcher,
- _mergeConfig,
- _invalidChainTracker,
- _api.ProcessExit!,
- _api.BetterPeerStrategy,
- _api.ChainSpec,
- _beaconSync,
- _api.StateReader,
- _api.LogManager
- );
- _api.Synchronizer = synchronizer;
+ _api.ConfigureContainerBuilderFromApiWithNetwork(builder)
+ .AddSingleton(_beaconSync)
+ .AddSingleton(_beaconPivot)
+ .AddSingleton(_mergeConfig)
+ .AddSingleton(_invalidChainTracker);
+
+ builder.RegisterModule(new SynchronizerModule(_syncConfig));
+ builder.RegisterModule(new MergeSynchronizerModule());
+
+ IContainer container = builder.Build();
+ _api.ApiWithNetworkServiceContainer = container;
+ _api.DisposeStack.Append(container);
PivotUpdator pivotUpdator = new(
_api.BlockTree,
- synchronizer.SyncModeSelector,
+ _api.SyncModeSelector,
_api.SyncPeerPool,
_syncConfig,
_blockCacheService,
diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeBlockDownloaderFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeBlockDownloaderFactory.cs
deleted file mode 100644
index 8c3b99555bf..00000000000
--- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeBlockDownloaderFactory.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
-// SPDX-License-Identifier: LGPL-3.0-only
-
-using System;
-using Nethermind.Blockchain;
-using Nethermind.Blockchain.Receipts;
-using Nethermind.Blockchain.Synchronization;
-using Nethermind.Consensus;
-using Nethermind.Consensus.Validators;
-using Nethermind.Core.Specs;
-using Nethermind.Logging;
-using Nethermind.Synchronization;
-using Nethermind.Synchronization.Blocks;
-using Nethermind.Synchronization.ParallelSync;
-using Nethermind.Synchronization.Peers;
-using Nethermind.Synchronization.Reporting;
-
-
-namespace Nethermind.Merge.Plugin.Synchronization
-{
- public class MergeBlockDownloaderFactory : IBlockDownloaderFactory
- {
- private readonly IPoSSwitcher _poSSwitcher;
- private readonly IBeaconPivot _beaconPivot;
- private readonly ISpecProvider _specProvider;
- private readonly IBlockValidator _blockValidator;
- private readonly ISealValidator _sealValidator;
- private readonly IBetterPeerStrategy _betterPeerStrategy;
- private readonly ILogManager _logManager;
- private readonly IFullStateFinder _fullStateFinder;
- private readonly ISyncConfig _syncConfig;
-
- public MergeBlockDownloaderFactory(
- IPoSSwitcher poSSwitcher,
- IBeaconPivot beaconPivot,
- ISpecProvider specProvider,
- IBlockValidator blockValidator,
- ISealValidator sealValidator,
- ISyncConfig syncConfig,
- IBetterPeerStrategy betterPeerStrategy,
- IFullStateFinder fullStateFinder,
- ILogManager logManager)
- {
- _poSSwitcher = poSSwitcher ?? throw new ArgumentNullException(nameof(poSSwitcher));
- _beaconPivot = beaconPivot ?? throw new ArgumentNullException(nameof(beaconPivot));
- _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
- _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
- _sealValidator = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
- _betterPeerStrategy = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
- _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager));
- _fullStateFinder = fullStateFinder ?? throw new ArgumentNullException(nameof(fullStateFinder)); ;
- _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); ;
- }
-
- public BlockDownloader Create(ISyncFeed syncFeed, IBlockTree blockTree, IReceiptStorage receiptStorage,
- ISyncPeerPool syncPeerPool, ISyncReport syncReport)
- {
- ChainLevelHelper chainLevelHelper = new ChainLevelHelper(blockTree, _beaconPivot, _syncConfig, _logManager);
- return new MergeBlockDownloader(
- _poSSwitcher,
- _beaconPivot,
- syncFeed,
- syncPeerPool,
- blockTree,
- _blockValidator,
- _sealValidator,
- syncReport,
- receiptStorage,
- _specProvider,
- _betterPeerStrategy,
- chainLevelHelper,
- _fullStateFinder,
- _logManager);
- }
-
- public IPeerAllocationStrategyFactory CreateAllocationStrategyFactory()
- {
- return new MergeBlocksSyncPeerAllocationStrategyFactory(_poSSwitcher, _beaconPivot, _logManager);
- }
- }
-}
diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs
index 38e65be39e7..ac3ad98313f 100644
--- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs
+++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs
@@ -1,113 +1,58 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
-using Nethermind.Blockchain;
-using Nethermind.Blockchain.Receipts;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Autofac;
+using Autofac.Features.AttributeFilters;
using Nethermind.Blockchain.Synchronization;
-using Nethermind.Config;
-using Nethermind.Consensus;
-using Nethermind.Core.Specs;
-using Nethermind.Db;
+using Nethermind.Core;
using Nethermind.Logging;
-using Nethermind.Merge.Plugin.InvalidChainTracker;
-using Nethermind.Specs.ChainSpecStyle;
-using Nethermind.State;
-using Nethermind.Stats;
using Nethermind.Synchronization;
using Nethermind.Synchronization.Blocks;
using Nethermind.Synchronization.FastBlocks;
using Nethermind.Synchronization.ParallelSync;
-using Nethermind.Synchronization.Peers;
-using Nethermind.Trie;
-using Nethermind.Trie.Pruning;
namespace Nethermind.Merge.Plugin.Synchronization;
-public class MergeSynchronizer : Synchronizer
+public class MergeSynchronizer(
+ [KeyFilter(nameof(BeaconHeadersSyncFeed))] SyncFeedComponent beaconHeaderComponent,
+ ISyncConfig syncConfig,
+ Synchronizer baseSynchronizer,
+ ILogManager logManager)
+ : ISynchronizer
{
- private readonly IPoSSwitcher _poSSwitcher;
- private readonly IMergeConfig _mergeConfig;
- private readonly IInvalidChainTracker _invalidChainTracker;
- private BeaconHeadersSyncFeed _beaconHeadersFeed = null!;
- private readonly IBeaconSyncStrategy _beaconSync;
+ private readonly CancellationTokenSource? _syncCancellation = new();
+ private readonly ILogger _logger = logManager.GetClassLogger();
- public override ISyncModeSelector SyncModeSelector => _syncModeSelector ??= new MultiSyncModeSelector(
- SyncProgressResolver,
- _syncPeerPool,
- _syncConfig,
- _beaconSync,
- _betterPeerStrategy!,
- _logManager);
-
- public MergeSynchronizer(
- IDbProvider dbProvider,
- INodeStorage nodeStorage,
- ISpecProvider specProvider,
- IBlockTree blockTree,
- IReceiptStorage receiptStorage,
- ISyncPeerPool peerPool,
- INodeStatsManager nodeStatsManager,
- ISyncConfig syncConfig,
- IBlockDownloaderFactory blockDownloaderFactory,
- IPivot pivot,
- IPoSSwitcher poSSwitcher,
- IMergeConfig mergeConfig,
- IInvalidChainTracker invalidChainTracker,
- IProcessExitSource exitSource,
- IBetterPeerStrategy betterPeerStrategy,
- ChainSpec chainSpec,
- IBeaconSyncStrategy beaconSync,
- IStateReader stateReader,
- ILogManager logManager)
- : base(
- dbProvider,
- nodeStorage,
- specProvider,
- blockTree,
- receiptStorage,
- peerPool,
- nodeStatsManager,
- syncConfig,
- blockDownloaderFactory,
- pivot,
- exitSource,
- betterPeerStrategy,
- chainSpec,
- stateReader,
- logManager)
+ public event EventHandler? SyncEvent
{
- _invalidChainTracker = invalidChainTracker;
- _poSSwitcher = poSSwitcher;
- _mergeConfig = mergeConfig;
- _beaconSync = beaconSync;
+ add => baseSynchronizer.SyncEvent += value;
+ remove => baseSynchronizer.SyncEvent -= value;
}
- public override void Start()
+ public void Start()
{
- if (!_syncConfig.SynchronizationEnabled)
+ if (!syncConfig.SynchronizationEnabled)
{
return;
}
- base.Start();
+ baseSynchronizer.Start();
StartBeaconHeadersComponents();
WireMultiSyncModeSelector();
}
- private void StartBeaconHeadersComponents()
+ public Task StopAsync()
{
- FastBlocksPeerAllocationStrategyFactory fastFactory = new();
- _beaconHeadersFeed =
- new(_poSSwitcher, _blockTree, _syncPeerPool, _syncConfig, _syncReport, _pivot, _mergeConfig, _invalidChainTracker, _logManager);
- BeaconHeadersSyncDownloader beaconHeadersDownloader = new(_logManager);
-
- SyncDispatcher dispatcher = CreateDispatcher(
- _beaconHeadersFeed!,
- beaconHeadersDownloader,
- fastFactory
- );
+ _syncCancellation?.Cancel();
+ return baseSynchronizer.StopAsync();
+ }
- dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
+ private void StartBeaconHeadersComponents()
+ {
+ beaconHeaderComponent.Dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -122,6 +67,36 @@ private void StartBeaconHeadersComponents()
private void WireMultiSyncModeSelector()
{
- WireFeedWithModeSelector(_beaconHeadersFeed);
+ baseSynchronizer.WireFeedWithModeSelector(beaconHeaderComponent.Feed);
+ }
+
+ public void Dispose()
+ {
+ baseSynchronizer.Dispose();
+ }
+}
+
+public class MergeSynchronizerModule : Module
+{
+ protected override void Load(ContainerBuilder builder)
+ {
+ builder
+ .RegisterType()
+ .As()
+ .As>()
+ .InstancePerLifetimeScope();
+
+ builder
+ .AddSingleton()
+ .AddSingleton()
+ .AddScoped, MergeBlocksSyncPeerAllocationStrategyFactory>()
+
+ .RegisterNamedComponentInItsOwnLifetime>(nameof(BeaconHeadersSyncFeed), ConfigureBeaconHeader);
+ }
+
+ private void ConfigureBeaconHeader(ContainerBuilder scopeConfig)
+ {
+ scopeConfig.AddScoped, BeaconHeadersSyncFeed>()
+ .AddScoped, BeaconHeadersSyncDownloader>();
}
}
diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs
index 5bbd22e36be..76633fbf876 100644
--- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs
+++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
using System;
+using System.Linq;
using System.Threading.Tasks;
+using Autofac;
using Nethermind.Api;
using Nethermind.Api.Extensions;
using Nethermind.Consensus;
@@ -23,13 +25,12 @@
using Nethermind.Consensus.Validators;
using Nethermind.Core;
using Nethermind.Merge.Plugin.Synchronization;
-using Nethermind.Synchronization.ParallelSync;
using Nethermind.HealthChecks;
using Nethermind.Serialization.Json;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Serialization.Rlp;
using Nethermind.Optimism.Rpc;
-using Nethermind.Db;
+using Nethermind.Synchronization;
namespace Nethermind.Optimism;
@@ -151,42 +152,25 @@ public Task InitSynchronization()
_api.BetterPeerStrategy = new MergeBetterPeerStrategy(_api.BetterPeerStrategy, _api.PoSSwitcher, _beaconPivot, _api.LogManager);
_api.Pivot = _beaconPivot;
- MergeBlockDownloaderFactory blockDownloaderFactory = new MergeBlockDownloaderFactory(
- _api.PoSSwitcher,
- _beaconPivot,
- _api.SpecProvider,
- _api.BlockValidator!,
- _api.SealValidator!,
- _syncConfig,
- _api.BetterPeerStrategy!,
- new FullStateFinder(_api.BlockTree, _api.StateReader!),
- _api.LogManager);
+ ContainerBuilder builder = new ContainerBuilder();
+ ((INethermindApi)_api).ConfigureContainerBuilderFromApiWithNetwork(builder)
+ .AddSingleton(_beaconSync)
+ .AddSingleton(_beaconPivot)
+ .AddSingleton(_api.PoSSwitcher)
+ .AddSingleton(_mergeConfig)
+ .AddSingleton(_invalidChainTracker);
- _api.Synchronizer = new MergeSynchronizer(
- _api.DbProvider,
- _api.NodeStorageFactory.WrapKeyValueStore(_api.DbProvider.StateDb),
- _api.SpecProvider!,
- _api.BlockTree!,
- _api.ReceiptStorage!,
- _api.SyncPeerPool,
- _api.NodeStatsManager!,
- _syncConfig,
- blockDownloaderFactory,
- _beaconPivot,
- _api.PoSSwitcher,
- _mergeConfig,
- _invalidChainTracker,
- _api.ProcessExit!,
- _api.BetterPeerStrategy,
- _api.ChainSpec,
- _beaconSync,
- _api.StateReader!,
- _api.LogManager
- );
+ builder.RegisterModule(new SynchronizerModule(_syncConfig));
+ builder.RegisterModule(new MergeSynchronizerModule());
+
+ IContainer container = builder.Build();
+
+ _api.ApiWithNetworkServiceContainer = container;
+ _api.DisposeStack.Append(container);
_ = new PivotUpdator(
_api.BlockTree,
- _api.Synchronizer.SyncModeSelector,
+ _api.SyncModeSelector,
_api.SyncPeerPool,
_syncConfig,
_blockCacheService,
diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs
index ef3c4c9a68a..9b0a4f49d77 100644
--- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs
+++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
using System.IO.Abstractions;
+using Autofac;
using Nethermind.Api;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
@@ -46,6 +47,7 @@
using Nethermind.Trie;
using NSubstitute;
using Nethermind.Blockchain.Blocks;
+using Nethermind.Core;
using Nethermind.Facade.Find;
namespace Nethermind.Runner.Test.Ethereum
@@ -76,7 +78,6 @@ public static NethermindApi ContextWithMocks()
StaticNodesManager = Substitute.For(),
BloomStorage = Substitute.For(),
Sealer = Substitute.For(),
- Synchronizer = Substitute.For(),
BlockchainProcessor = Substitute.For(),
BlockProducer = Substitute.For(),
DiscoveryApp = Substitute.For(),
@@ -103,7 +104,6 @@ public static NethermindApi ContextWithMocks()
EngineSignerStore = Substitute.For(),
NodeStatsManager = Substitute.For(),
RpcModuleProvider = Substitute.For(),
- SyncModeSelector = Substitute.For(),
SyncPeerPool = Substitute.For(),
PeerDifficultyRefreshPool = Substitute.For(),
WebSocketsManager = Substitute.For(),
@@ -117,10 +117,15 @@ public static NethermindApi ContextWithMocks()
TxValidator = new TxValidator(MainnetSpecProvider.Instance.ChainId),
UnclesValidator = Substitute.For(),
BlockProductionPolicy = Substitute.For(),
- SyncProgressResolver = Substitute.For(),
BetterPeerStrategy = Substitute.For(),
ReceiptMonitor = Substitute.For(),
- BadBlocksStore = Substitute.For()
+ BadBlocksStore = Substitute.For(),
+
+ ApiWithNetworkServiceContainer = new ContainerBuilder()
+ .AddSingleton(Substitute.For())
+ .AddSingleton(Substitute.For())
+ .AddSingleton(Substitute.For())
+ .Build(),
};
api.WorldStateManager = new ReadOnlyWorldStateManager(api.DbProvider, Substitute.For(), LimboLogs.Instance);
diff --git a/src/Nethermind/Nethermind.Synchronization.Test/DbTuner/SyncDbTunerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/DbTuner/SyncDbTunerTests.cs
index 8c7954d8b92..ffc2251face 100644
--- a/src/Nethermind/Nethermind.Synchronization.Test/DbTuner/SyncDbTunerTests.cs
+++ b/src/Nethermind/Nethermind.Synchronization.Test/DbTuner/SyncDbTunerTests.cs
@@ -53,15 +53,6 @@ public void Setup()
_receiptDb);
}
- [TearDown]
- public void TearDown()
- {
- _blockDb?.Dispose();
- _codeDb?.Dispose();
- _receiptDb?.Dispose();
- _stateDb?.Dispose();
- }
-
[Test]
public void WhenSnapIsOn_TriggerStateDbTune()
{
diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs
index d5e3adcbeae..89bd50a3ca4 100644
--- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs
+++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs
@@ -4,7 +4,10 @@
using System;
using System.Threading;
using System.Threading.Tasks;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
using FluentAssertions;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
@@ -15,6 +18,7 @@
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
+using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Core.Timers;
using Nethermind.Db;
@@ -24,6 +28,7 @@
using Nethermind.State;
using Nethermind.Stats;
using Nethermind.Synchronization.Blocks;
+using Nethermind.Synchronization.ParallelSync;
using Nethermind.Synchronization.Peers;
using Nethermind.Synchronization.Reporting;
using Nethermind.Synchronization.SnapSync;
@@ -61,31 +66,34 @@ public async Task Setup()
TrieStore trieStore = new(nodeStorage, LimboLogs.Instance);
TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance);
Pivot pivot = new(syncConfig);
- BlockDownloaderFactory blockDownloaderFactory = new(
- MainnetSpecProvider.Instance,
- Always.Valid,
- Always.Valid,
- new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance),
- LimboLogs.Instance);
IStateReader stateReader = new StateReader(trieStore, _codeDb, LimboLogs.Instance);
- _synchronizer = new Synchronizer(
- dbProvider,
- nodeStorage,
- MainnetSpecProvider.Instance,
- _blockTree,
- _receiptStorage,
- _pool,
- stats,
- syncConfig,
- blockDownloaderFactory,
- pivot,
- Substitute.For(),
- bestPeerStrategy,
- new ChainSpec(),
- stateReader,
- LimboLogs.Instance);
+ ContainerBuilder builder = new ContainerBuilder()
+ .AddSingleton(nodeStorage)
+ .AddSingleton(MainnetSpecProvider.Instance)
+ .AddSingleton(_blockTree)
+ .AddSingleton(_receiptStorage)
+ .AddSingleton(_pool)
+ .AddSingleton(stats)
+ .AddSingleton(syncConfig)
+ .AddSingleton(Always.Valid)
+ .AddSingleton(Always.Valid)
+ .AddSingleton(pivot)
+ .AddSingleton(Substitute.For())
+ .AddSingleton(bestPeerStrategy)
+ .AddSingleton(new ChainSpec())
+ .AddSingleton(stateReader)
+ .AddSingleton(No.BeaconSync)
+ .AddSingleton(LimboLogs.Instance);
+ dbProvider.ConfigureServiceCollection(builder);
+
+ builder.RegisterModule(new SynchronizerModule(syncConfig));
+
+ IContainer container = builder.Build();
+
+ _synchronizer = container.Resolve();
+
_syncServer = new SyncServer(
trieStore.TrieNodeRlpStore,
_codeDb,
@@ -94,7 +102,7 @@ public async Task Setup()
Always.Valid,
Always.Valid,
_pool,
- _synchronizer.SyncModeSelector,
+ container.Resolve(),
quickConfig,
Policy.FullGossip,
MainnetSpecProvider.Instance,
diff --git a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs
index f44d95d9c8c..87ab10fe7bd 100644
--- a/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs
+++ b/src/Nethermind/Nethermind.Synchronization.Test/ParallelSync/MultiSyncModeSelectorTests.Scenario.cs
@@ -145,7 +145,6 @@ public class ScenarioBuilder
private readonly List _overwrites = new();
private readonly List _peers = new();
- private bool _needToWaitForHeaders;
public ISyncPeerPool SyncPeerPool { get; set; } = null!;
@@ -812,7 +811,7 @@ void Test()
}
TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance);
- MultiSyncModeSelector selector = new(SyncProgressResolver, SyncPeerPool, SyncConfig, BeaconSyncStrategy, bestPeerStrategy, LimboLogs.Instance, _needToWaitForHeaders);
+ MultiSyncModeSelector selector = new(SyncProgressResolver, SyncPeerPool, SyncConfig, BeaconSyncStrategy, bestPeerStrategy, LimboLogs.Instance);
selector.Stop();
selector.Update();
selector.Current.Should().Be(syncMode);
@@ -840,7 +839,7 @@ void Test()
public ScenarioBuilder WhenConsensusRequiresToWaitForHeaders(bool needToWaitForHeaders)
{
- _needToWaitForHeaders = needToWaitForHeaders;
+ SyncConfig.NeedToWaitForHeader = needToWaitForHeaders;
return this;
}
diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs
index c86dfbb240b..33e43446a69 100644
--- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs
+++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs
@@ -5,6 +5,9 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.BeaconBlockRoot;
using Nethermind.Blockchain.Blocks;
@@ -42,6 +45,7 @@
using BlockTree = Nethermind.Blockchain.BlockTree;
using Nethermind.Synchronization.SnapSync;
using Nethermind.Config;
+using Nethermind.Core.Specs;
using Nethermind.Specs.ChainSpecStyle;
using Nethermind.Trie;
@@ -356,28 +360,32 @@ private SyncTestContext CreateSyncManager(int index)
TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance);
Pivot pivot = new(syncConfig);
- BlockDownloaderFactory blockDownloaderFactory = new(
- MainnetSpecProvider.Instance,
- blockValidator,
- sealValidator,
- new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance),
- logManager);
- Synchronizer synchronizer = new(
- dbProvider,
- new NodeStorage(dbProvider.StateDb),
- MainnetSpecProvider.Instance,
- tree,
- NullReceiptStorage.Instance,
- syncPeerPool,
- nodeStatsManager,
- syncConfig,
- blockDownloaderFactory,
- pivot,
- Substitute.For(),
- bestPeerStrategy,
- new ChainSpec(),
- stateReader,
- logManager);
+
+ ContainerBuilder builder = new ContainerBuilder();
+ builder
+ .AddSingleton(dbProvider)
+ .AddSingleton(new NodeStorage(dbProvider.StateDb))
+ .AddSingleton(MainnetSpecProvider.Instance)
+ .AddSingleton(tree)
+ .AddSingleton(NullReceiptStorage.Instance)
+ .AddSingleton(syncPeerPool)
+ .AddSingleton(nodeStatsManager)
+ .AddSingleton(syncConfig)
+ .AddSingleton(blockValidator)
+ .AddSingleton(sealValidator)
+ .AddSingleton(pivot)
+ .AddSingleton(Substitute.For())
+ .AddSingleton(bestPeerStrategy)
+ .AddSingleton(new ChainSpec())
+ .AddSingleton(stateReader)
+ .AddSingleton(receiptStorage)
+ .AddSingleton(No.BeaconSync)
+ .AddSingleton(logManager);
+ dbProvider.ConfigureServiceCollection(builder);
+ builder.RegisterModule(new SynchronizerModule(syncConfig));
+ IContainer container = builder.Build();
+
+ Synchronizer synchronizer = container.Resolve();
ISyncModeSelector selector = synchronizer.SyncModeSelector;
SyncServer syncServer = new(
diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs
index 872499cf73f..47c721d274c 100644
--- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs
+++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs
@@ -8,6 +8,9 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Receipts;
using Nethermind.Blockchain.Synchronization;
@@ -17,6 +20,7 @@
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
+using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Core.Timers;
using Nethermind.Db;
@@ -333,74 +337,48 @@ ISyncConfig GetSyncConfig() =>
: totalDifficultyBetterPeerStrategy;
StateReader reader = new StateReader(trieStore, codeDb, LimboLogs.Instance);
- FullStateFinder fullStateFinder = new FullStateFinder(BlockTree, reader);
INodeStorage nodeStorage = new NodeStorage(dbProvider.StateDb);
SyncPeerPool = new SyncPeerPool(BlockTree, stats, bestPeerStrategy, _logManager, 25);
Pivot pivot = new(syncConfig);
IInvalidChainTracker invalidChainTracker = new NoopInvalidChainTracker();
+
+ ContainerBuilder builder = new ContainerBuilder();
+ dbProvider.ConfigureServiceCollection(builder);
+
+ builder
+ .AddSingleton(dbProvider)
+ .AddSingleton(nodeStorage)
+ .AddSingleton(MainnetSpecProvider.Instance)
+ .AddSingleton(BlockTree)
+ .AddSingleton(NullReceiptStorage.Instance)
+ .AddSingleton(SyncPeerPool)
+ .AddSingleton(stats)
+ .AddSingleton(syncConfig)
+ .AddSingleton(pivot)
+ .AddSingleton(poSSwitcher)
+ .AddSingleton(mergeConfig)
+ .AddSingleton(invalidChainTracker)
+ .AddSingleton(Substitute.For())
+ .AddSingleton(bestPeerStrategy)
+ .AddSingleton(new ChainSpec())
+ .AddSingleton(No.BeaconSync)
+ .AddSingleton(reader)
+ .AddSingleton(Always.Valid)
+ .AddSingleton(Always.Valid)
+ .AddSingleton(beaconPivot)
+ .AddSingleton(_logManager);
+
+ builder.RegisterModule(new SynchronizerModule(syncConfig));
+
if (IsMerge(synchronizerType))
{
- IBlockDownloaderFactory blockDownloaderFactory = new MergeBlockDownloaderFactory(
- poSSwitcher,
- beaconPivot,
- MainnetSpecProvider.Instance,
- Always.Valid,
- Always.Valid,
- syncConfig,
- bestPeerStrategy,
- fullStateFinder,
- _logManager
- );
- Synchronizer = new MergeSynchronizer(
- dbProvider,
- nodeStorage,
- MainnetSpecProvider.Instance,
- BlockTree,
- NullReceiptStorage.Instance,
- SyncPeerPool,
- stats,
- syncConfig,
- blockDownloaderFactory,
- pivot,
- poSSwitcher,
- mergeConfig,
- invalidChainTracker,
- Substitute.For(),
- bestPeerStrategy,
- new ChainSpec(),
- No.BeaconSync,
- reader,
- _logManager);
- }
- else
- {
- IBlockDownloaderFactory blockDownloaderFactory = new BlockDownloaderFactory(
- MainnetSpecProvider.Instance,
- Always.Valid,
- Always.Valid,
- new TotalDifficultyBetterPeerStrategy(_logManager),
- _logManager);
-
- Synchronizer = new Synchronizer(
- dbProvider,
- nodeStorage,
- MainnetSpecProvider.Instance,
- BlockTree,
- NullReceiptStorage.Instance,
- SyncPeerPool,
- stats,
- syncConfig,
- blockDownloaderFactory,
- pivot,
- Substitute.For(),
- bestPeerStrategy,
- new ChainSpec(),
- reader,
- _logManager);
+ builder.RegisterModule(new MergeSynchronizerModule());
}
+ IContainer container = builder.Build();
+ Synchronizer = container.Resolve();
SyncServer = new SyncServer(
trieStore.TrieNodeRlpStore,
codeDb,
@@ -409,7 +387,7 @@ ISyncConfig GetSyncConfig() =>
Always.Valid,
Always.Valid,
SyncPeerPool,
- Synchronizer.SyncModeSelector,
+ container.Resolve(),
syncConfig,
Policy.FullGossip,
MainnetSpecProvider.Instance,
diff --git a/src/Nethermind/Nethermind.Synchronization/Blocks/IBlockDownloaderFactory.cs b/src/Nethermind/Nethermind.Synchronization/Blocks/IBlockDownloaderFactory.cs
deleted file mode 100644
index 64afb7b1061..00000000000
--- a/src/Nethermind/Nethermind.Synchronization/Blocks/IBlockDownloaderFactory.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
-// SPDX-License-Identifier: LGPL-3.0-only
-
-using System;
-using Nethermind.Blockchain;
-using Nethermind.Blockchain.Receipts;
-using Nethermind.Consensus;
-using Nethermind.Consensus.Validators;
-using Nethermind.Core.Specs;
-using Nethermind.Logging;
-using Nethermind.Synchronization.ParallelSync;
-using Nethermind.Synchronization.Peers;
-using Nethermind.Synchronization.Reporting;
-
-namespace Nethermind.Synchronization.Blocks
-{
- public class BlockDownloaderFactory : IBlockDownloaderFactory
- {
- private readonly ISpecProvider _specProvider;
- private readonly IBlockValidator _blockValidator;
- private readonly ISealValidator _sealValidator;
- private readonly IBetterPeerStrategy _betterPeerStrategy;
- private readonly ILogManager _logManager;
-
- public BlockDownloaderFactory(
- ISpecProvider specProvider,
- IBlockValidator blockValidator,
- ISealValidator sealValidator,
- IBetterPeerStrategy betterPeerStrategy,
- ILogManager logManager)
- {
- _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
- _blockValidator = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
- _sealValidator = sealValidator ?? throw new ArgumentNullException(nameof(sealValidator));
- _betterPeerStrategy = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
- _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager));
- }
-
- public BlockDownloader Create(ISyncFeed syncFeed, IBlockTree blockTree, IReceiptStorage receiptStorage, ISyncPeerPool peerPool, ISyncReport syncReport)
- {
- return new(
- syncFeed,
- peerPool,
- blockTree,
- _blockValidator,
- _sealValidator,
- syncReport,
- receiptStorage,
- _specProvider,
- _betterPeerStrategy,
- _logManager);
- }
-
- public IPeerAllocationStrategyFactory CreateAllocationStrategyFactory()
- {
- return new BlocksSyncPeerAllocationStrategyFactory();
- }
- }
-
- public interface IBlockDownloaderFactory
- {
- BlockDownloader Create(ISyncFeed syncFeed, IBlockTree blockTree, IReceiptStorage receiptStorage, ISyncPeerPool syncPeerPool, ISyncReport syncReport);
- IPeerAllocationStrategyFactory CreateAllocationStrategyFactory();
- }
-}
diff --git a/src/Nethermind/Nethermind.Synchronization/DbTuner/SyncDbOptimizer.cs b/src/Nethermind/Nethermind.Synchronization/DbTuner/SyncDbOptimizer.cs
index e9f5c7c10d5..13a8ecbb4a6 100644
--- a/src/Nethermind/Nethermind.Synchronization/DbTuner/SyncDbOptimizer.cs
+++ b/src/Nethermind/Nethermind.Synchronization/DbTuner/SyncDbOptimizer.cs
@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Db;
using Nethermind.Synchronization.FastBlocks;
@@ -24,26 +26,32 @@ public SyncDbTuner(
ISyncFeed? snapSyncFeed,
ISyncFeed? bodiesSyncFeed,
ISyncFeed? receiptSyncFeed,
- ITunableDb? stateDb,
- ITunableDb? codeDb,
- ITunableDb? blockDb,
- ITunableDb? receiptDb
+ [KeyFilter(DbNames.State)] ITunableDb? stateDb,
+ [KeyFilter(DbNames.Code)] ITunableDb? codeDb,
+ [KeyFilter(DbNames.Blocks)] ITunableDb? blockDb,
+ [KeyFilter(DbNames.Receipts)] ITunableDb? receiptDb
)
{
+ if (syncConfig.TuneDbMode == ITunableDb.TuneType.Default && syncConfig.BlocksDbTuneDbMode == ITunableDb.TuneType.Default)
+ {
+ // Do nothing.
+ return;
+ }
+
// Only these three make sense as they are write heavy
// Headers is used everywhere, so slowing read might slow the whole sync.
// Statesync is read heavy, Forward sync is just plain too slow to saturate IO.
- if (snapSyncFeed is not null)
+ if (snapSyncFeed is not NoopSyncFeed)
{
snapSyncFeed.StateChanged += SnapStateChanged;
}
- if (bodiesSyncFeed is not null)
+ if (bodiesSyncFeed is not NoopSyncFeed)
{
bodiesSyncFeed.StateChanged += BodiesStateChanged;
}
- if (receiptSyncFeed is not null)
+ if (receiptSyncFeed is not NoopSyncFeed)
{
receiptSyncFeed.StateChanged += ReceiptsStateChanged;
}
diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs
index 9b972b68d67..1152f416054 100644
--- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs
+++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs
@@ -4,6 +4,8 @@
using System;
using System.Threading;
using System.Threading.Tasks;
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Consensus.Validators;
@@ -50,8 +52,8 @@ public BodiesSyncFeed(
ISyncPeerPool syncPeerPool,
ISyncConfig syncConfig,
ISyncReport syncReport,
- IDbMeta blocksDb,
- IDb metadataDb,
+ [KeyFilter(DbNames.Blocks)] IDbMeta blocksDb,
+ [KeyFilter(DbNames.Metadata)] IDb metadataDb,
ILogManager logManager,
long flushDbInterval = DefaultFlushDbInterval)
: base(metadataDb, specProvider, logManager.GetClassLogger())
diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs
index e621dc56795..cbfce46215c 100644
--- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs
+++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/ReceiptsSyncFeed.cs
@@ -6,6 +6,8 @@
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Receipts;
using Nethermind.Blockchain.Synchronization;
@@ -57,7 +59,7 @@ public ReceiptsSyncFeed(
ISyncPeerPool syncPeerPool,
ISyncConfig syncConfig,
ISyncReport syncReport,
- IDb metadataDb,
+ [KeyFilter(DbNames.Metadata)] IDb metadataDb,
ILogManager logManager)
: base(metadataDb, specProvider, logManager?.GetClassLogger() ?? default)
{
diff --git a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs
index 0c4b7b35568..1abfe9643bb 100644
--- a/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs
+++ b/src/Nethermind/Nethermind.Synchronization/FastSync/TreeSync.cs
@@ -8,6 +8,8 @@
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Core;
using Nethermind.Core.Caching;
@@ -74,6 +76,12 @@ public class TreeSync
private long _blockNumber;
private readonly SyncMode _syncMode;
+ public TreeSync([KeyFilter(DbNames.Code)] IDb codeDb, INodeStorage nodeStorage, IBlockTree blockTree, ILogManager logManager)
+ : this(SyncMode.StateNodes, codeDb, nodeStorage, blockTree, logManager)
+ {
+
+ }
+
public TreeSync(SyncMode syncMode, IDb codeDb, INodeStorage nodeStorage, IBlockTree blockTree, ILogManager logManager)
{
_syncMode = syncMode;
diff --git a/src/Nethermind/Nethermind.Synchronization/ISynchronizer.cs b/src/Nethermind/Nethermind.Synchronization/ISynchronizer.cs
index 512b0a767a5..011659c5238 100644
--- a/src/Nethermind/Nethermind.Synchronization/ISynchronizer.cs
+++ b/src/Nethermind/Nethermind.Synchronization/ISynchronizer.cs
@@ -15,8 +15,5 @@ public interface ISynchronizer : IDisposable
void Start();
Task StopAsync();
-
- ISyncProgressResolver SyncProgressResolver { get; }
- ISyncModeSelector SyncModeSelector { get; }
}
}
diff --git a/src/Nethermind/Nethermind.Synchronization/MallocTrimmer.cs b/src/Nethermind/Nethermind.Synchronization/MallocTrimmer.cs
index 63c6e85e36c..0010bc111db 100644
--- a/src/Nethermind/Nethermind.Synchronization/MallocTrimmer.cs
+++ b/src/Nethermind/Nethermind.Synchronization/MallocTrimmer.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using Nethermind.Blockchain.Synchronization;
using Nethermind.Core.Extensions;
using Nethermind.Core.Memory;
using Nethermind.Logging;
@@ -16,6 +17,14 @@ public class MallocTrimmer
private readonly MallocHelper _mallocHelper;
private readonly ILogger _logger;
+ public MallocTrimmer(
+ ISyncModeSelector syncModeSelector,
+ ISyncConfig syncConfig,
+ ILogManager logManager
+ ) : this(syncModeSelector, TimeSpan.FromSeconds(syncConfig.MallocTrimIntervalSec), logManager)
+ {
+ }
+
public MallocTrimmer(
ISyncModeSelector syncModeSelector,
TimeSpan interval,
diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncFeed.cs
index 64ac3f4687e..1f87736fb08 100644
--- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncFeed.cs
+++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/ISyncFeed.cs
@@ -30,6 +30,6 @@ public interface ISyncFeed
/// Return true if not finished. May not run even if return true if MultiSyncModeSelector said no, probably
/// because it's waiting for other sync or something.
- bool IsFinished { get; }
+ bool IsFinished => false;
}
}
diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs
index e9eff01f553..7cfc08deca8 100644
--- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs
+++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs
@@ -8,8 +8,10 @@
using System.Threading;
using System.Threading.Tasks;
using Nethermind.Blockchain.Synchronization;
+using Nethermind.Core;
using Nethermind.Int256;
using Nethermind.Logging;
+using Nethermind.Specs.ChainSpecStyle;
using Nethermind.State.Snap;
using Nethermind.Synchronization.Peers;
@@ -80,8 +82,7 @@ public MultiSyncModeSelector(
ISyncConfig syncConfig,
IBeaconSyncStrategy beaconSyncStrategy,
IBetterPeerStrategy betterPeerStrategy,
- ILogManager logManager,
- bool needToWaitForHeaders = false)
+ ILogManager logManager)
{
_logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
_syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
@@ -89,7 +90,7 @@ public MultiSyncModeSelector(
_syncPeerPool = syncPeerPool ?? throw new ArgumentNullException(nameof(syncPeerPool));
_betterPeerStrategy = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
_syncProgressResolver = syncProgressResolver ?? throw new ArgumentNullException(nameof(syncProgressResolver));
- _needToWaitForHeaders = needToWaitForHeaders;
+ _needToWaitForHeaders = syncConfig.NeedToWaitForHeader;
if (syncConfig.FastSyncCatchUpHeightDelta <= FastSyncLag)
{
diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/NoopSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/NoopSyncFeed.cs
new file mode 100644
index 00000000000..f04f755c736
--- /dev/null
+++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/NoopSyncFeed.cs
@@ -0,0 +1,45 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Nethermind.Synchronization.Peers;
+
+namespace Nethermind.Synchronization.ParallelSync;
+
+public class NoopSyncFeed : ISyncFeed
+{
+ public SyncFeedState CurrentState { get; }
+
+#pragma warning disable CS0067
+ public event EventHandler? StateChanged;
+#pragma warning disable
+
+ public Task PrepareRequest(CancellationToken token = default)
+ {
+ return Task.FromResult(default);
+ }
+
+ public SyncResponseHandlingResult HandleResponse(T response, PeerInfo? peer = null)
+ {
+ return SyncResponseHandlingResult.NotAssigned;
+ }
+
+ public bool IsMultiFeed { get; }
+ public AllocationContexts Contexts { get; }
+ public void Activate()
+ {
+ }
+
+ public void Finish()
+ {
+ }
+
+ public Task FeedTask => Task.CompletedTask;
+ public void SyncModeSelectorOnChanged(SyncMode current)
+ {
+ }
+
+ public bool IsFinished { get; } = true;
+}
diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncDispatcher.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncDispatcher.cs
index 50c38f3384b..2bbdb3e50d4 100644
--- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncDispatcher.cs
+++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncDispatcher.cs
@@ -4,6 +4,8 @@
using System;
using System.Threading;
using System.Threading.Tasks;
+using Nethermind.Blockchain.Synchronization;
+using Nethermind.Core;
using Nethermind.Core.Exceptions;
using Nethermind.Core.Extensions;
using Nethermind.Logging;
@@ -25,6 +27,18 @@ public class SyncDispatcher
private readonly SemaphoreSlim _concurrentProcessingSemaphore;
+ public SyncDispatcher(
+ ISyncConfig syncConfig,
+ ISyncFeed? syncFeed,
+ ISyncDownloader? downloader,
+ ISyncPeerPool? syncPeerPool,
+ IPeerAllocationStrategyFactory? peerAllocationStrategy,
+ ILogManager? logManager)
+ : this(syncConfig.MaxProcessingThreads, syncFeed, downloader, syncPeerPool, peerAllocationStrategy, logManager)
+ {
+
+ }
+
public SyncDispatcher(
int maxNumberOfProcessingThread,
ISyncFeed? syncFeed,
diff --git a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs
index 73a325d3149..705611e0f79 100644
--- a/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs
+++ b/src/Nethermind/Nethermind.Synchronization/ParallelSync/SyncProgressResolver.cs
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
using System;
+using Autofac.Features.AttributeFilters;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Core;
@@ -23,19 +24,19 @@ public class SyncProgressResolver : ISyncProgressResolver
// ReSharper disable once NotAccessedField.Local
private readonly ILogger _logger;
- private readonly ISyncFeed? _headersSyncFeed;
- private readonly ISyncFeed? _bodiesSyncFeed;
- private readonly ISyncFeed? _receiptsSyncFeed;
- private readonly ISyncFeed? _snapSyncFeed;
+ private readonly ISyncFeed _headersSyncFeed;
+ private readonly ISyncFeed _bodiesSyncFeed;
+ private readonly ISyncFeed _receiptsSyncFeed;
+ private readonly ISyncFeed _snapSyncFeed;
public SyncProgressResolver(
IBlockTree blockTree,
IFullStateFinder fullStateFinder,
ISyncConfig syncConfig,
- ISyncFeed? headersSyncFeed,
- ISyncFeed? bodiesSyncFeed,
- ISyncFeed? receiptsSyncFeed,
- ISyncFeed? snapSyncFeed,
+ [KeyFilter(nameof(HeadersSyncFeed))] ISyncFeed headersSyncFeed,
+ ISyncFeed bodiesSyncFeed,
+ ISyncFeed receiptsSyncFeed,
+ ISyncFeed snapSyncFeed,
ILogManager logManager)
{
_logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
@@ -83,11 +84,11 @@ public long FindBestFullState()
return _blockTree.FindHeader(blockHash)?.TotalDifficulty == 0 ? null : _blockTree.FindHeader(blockHash)?.TotalDifficulty;
}
- public bool IsFastBlocksHeadersFinished() => !IsFastBlocks() || !_syncConfig.DownloadHeadersInFastSync || _headersSyncFeed?.IsFinished == true;
+ public bool IsFastBlocksHeadersFinished() => !IsFastBlocks() || !_syncConfig.DownloadHeadersInFastSync || _headersSyncFeed.IsFinished;
- public bool IsFastBlocksBodiesFinished() => !IsFastBlocks() || !_syncConfig.DownloadBodiesInFastSync || _bodiesSyncFeed?.IsFinished == true;
+ public bool IsFastBlocksBodiesFinished() => !IsFastBlocks() || !_syncConfig.DownloadBodiesInFastSync || _bodiesSyncFeed.IsFinished;
- public bool IsFastBlocksReceiptsFinished() => !IsFastBlocks() || !_syncConfig.DownloadReceiptsInFastSync || _receiptsSyncFeed?.IsFinished == true;
+ public bool IsFastBlocksReceiptsFinished() => !IsFastBlocks() || !_syncConfig.DownloadReceiptsInFastSync || _receiptsSyncFeed.IsFinished;
public bool IsSnapGetRangesFinished() => _snapSyncFeed?.IsFinished ?? true;
diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs
index eda6709e66e..b6dba820c0c 100644
--- a/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs
+++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/ProgressTracker.cs
@@ -8,7 +8,10 @@
using System.Linq;
using System.Text;
using System.Threading;
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
+using Nethermind.Blockchain.Synchronization;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
@@ -58,6 +61,11 @@ public class ProgressTracker : IDisposable
private readonly Pivot _pivot;
+ public ProgressTracker(IBlockTree blockTree, [KeyFilter(DbNames.State)] IDb db, ILogManager logManager, ISyncConfig syncConfig)
+ : this(blockTree, db, logManager, syncConfig.SnapSyncAccountRangePartitionCount)
+ {
+ }
+
public ProgressTracker(IBlockTree blockTree, IDb db, ILogManager logManager, int accountRangePartitionCount = 8)
{
_logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs
index afb19297673..51548bfa9f6 100644
--- a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs
+++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs
@@ -6,6 +6,8 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
+using Autofac.Features.AttributeFilters;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.ObjectPool;
using Nethermind.Core;
using Nethermind.Core.Caching;
@@ -33,7 +35,7 @@ public class SnapProvider : ISnapProvider
// This is actually close to 97% effective.
private readonly ClockKeyCache _codeExistKeyCache = new(1024 * 16);
- public SnapProvider(ProgressTracker progressTracker, IDb codeDb, INodeStorage nodeStorage, ILogManager logManager)
+ public SnapProvider(ProgressTracker progressTracker, [KeyFilter(DbNames.Code)] IDb codeDb, INodeStorage nodeStorage, ILogManager logManager)
{
_codeDb = codeDb ?? throw new ArgumentNullException(nameof(codeDb));
_progressTracker = progressTracker ?? throw new ArgumentNullException(nameof(progressTracker));
diff --git a/src/Nethermind/Nethermind.Synchronization/SyncFeedComponent.cs b/src/Nethermind/Nethermind.Synchronization/SyncFeedComponent.cs
new file mode 100644
index 00000000000..93b4fe0df45
--- /dev/null
+++ b/src/Nethermind/Nethermind.Synchronization/SyncFeedComponent.cs
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+using System;
+using System.Threading.Tasks;
+using Autofac;
+using Nethermind.Synchronization.Blocks;
+using Nethermind.Synchronization.ParallelSync;
+
+namespace Nethermind.Synchronization;
+
+///
+/// Container to make it simpler to get a bunch of components within a same named scoped.
+///
+public class SyncFeedComponent(Lazy> feed, Lazy> dispatcher, Lazy> blockDownloader, ILifetimeScope lifetimeScope) : IDisposable, IAsyncDisposable
+{
+ public ISyncFeed Feed => feed.Value;
+ public SyncDispatcher Dispatcher => dispatcher.Value;
+ public BlockDownloader BlockDownloader => (BlockDownloader)blockDownloader.Value;
+
+ public void Dispose()
+ {
+ lifetimeScope.Dispose();
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ await lifetimeScope.DisposeAsync();
+ }
+}
diff --git a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs
index ff69883e6f6..826406ca9de 100644
--- a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs
+++ b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs
@@ -4,165 +4,74 @@
using System;
using System.Threading;
using System.Threading.Tasks;
-using Nethermind.Blockchain;
-using Nethermind.Blockchain.Receipts;
+using Autofac;
+using Autofac.Features.AttributeFilters;
using Nethermind.Blockchain.Synchronization;
using Nethermind.Config;
using Nethermind.Core;
using Nethermind.Core.Extensions;
-using Nethermind.Core.Specs;
-using Nethermind.Db;
using Nethermind.Logging;
-using Nethermind.Specs.ChainSpecStyle;
-using Nethermind.State;
using Nethermind.Stats;
using Nethermind.Stats.Model;
+using Nethermind.Synchronization;
using Nethermind.Synchronization.Blocks;
using Nethermind.Synchronization.DbTuner;
-using Nethermind.Synchronization.FastBlocks
- ;
+using Nethermind.Synchronization.FastBlocks;
using Nethermind.Synchronization.FastSync;
using Nethermind.Synchronization.ParallelSync;
-using Nethermind.Synchronization.Peers;
using Nethermind.Synchronization.Reporting;
using Nethermind.Synchronization.SnapSync;
using Nethermind.Synchronization.StateSync;
-using Nethermind.Trie;
namespace Nethermind.Synchronization
{
- public class Synchronizer : ISynchronizer
+ public class Synchronizer(
+ ISyncModeSelector syncModeSelector,
+ ISyncReport syncReport,
+ ISyncConfig syncConfig,
+ ILogManager logManager,
+ INodeStatsManager nodeStatsManager,
+ [KeyFilter(nameof(FullSyncFeed))] SyncFeedComponent fullSyncComponent,
+ [KeyFilter(nameof(FastSyncFeed))] SyncFeedComponent fastSyncComponent,
+ SyncFeedComponent stateSyncComponent,
+ SyncFeedComponent snapSyncComponent,
+ [KeyFilter(nameof(HeadersSyncFeed))] SyncFeedComponent fastHeaderComponent,
+ SyncFeedComponent oldBodiesComponent,
+ SyncFeedComponent oldReceiptsComponent,
+#pragma warning disable CS9113 // Parameter is unread. But it need to be instantiated to function
+ SyncDbTuner syncDbTuner,
+ MallocTrimmer mallocTrimmer,
+#pragma warning restore CS9113 // Parameter is unread.
+ IProcessExitSource exitSource)
+ : ISynchronizer
{
private const int FeedsTerminationTimeout = 5_000;
- private static MallocTrimmer? s_trimmer;
- private static SyncDbTuner? s_dbTuner;
+ private readonly ILogger _logger = logManager.GetClassLogger();
- private readonly ISpecProvider _specProvider;
- private readonly IReceiptStorage _receiptStorage;
- private readonly IBlockDownloaderFactory _blockDownloaderFactory;
- private readonly INodeStatsManager _nodeStatsManager;
-
- protected readonly ILogger _logger;
- protected readonly IBlockTree _blockTree;
- protected readonly ISyncConfig _syncConfig;
- protected readonly ISyncPeerPool _syncPeerPool;
- protected readonly ILogManager _logManager;
- protected readonly ISyncReport _syncReport;
- protected readonly IPivot _pivot;
-
- protected CancellationTokenSource? _syncCancellation = new();
+ private CancellationTokenSource? _syncCancellation = new();
/* sync events are used mainly for managing sync peers reputation */
public event EventHandler? SyncEvent;
- private readonly IDbProvider _dbProvider;
- private FastSyncFeed? _fastSyncFeed;
- private StateSyncFeed? _stateSyncFeed;
- private FullSyncFeed? _fullSyncFeed;
- private readonly IProcessExitSource _exitSource;
- protected IBetterPeerStrategy _betterPeerStrategy;
- private readonly ChainSpec _chainSpec;
-
- public ISnapProvider SnapProvider { get; }
-
- private HeadersSyncFeed? _headersSyncFeed;
- private HeadersSyncFeed? HeadersSyncFeed => _headersSyncFeed ??= CreateHeadersSyncFeed();
-
- private ReceiptsSyncFeed? _receiptsSyncFeed;
- private ReceiptsSyncFeed? ReceiptsSyncFeed => _receiptsSyncFeed ??= CreateReceiptsSyncFeed();
-
- private BodiesSyncFeed? _bodiesSyncFeed;
- private BodiesSyncFeed? BodiesSyncFeed => _bodiesSyncFeed ??= CreateBodiesSyncFeed();
-
- private SnapSyncFeed? _snapSyncFeed;
- private SnapSyncFeed? SnapSyncFeed => _snapSyncFeed ??= CreateSnapSyncFeed();
-
- private ISyncProgressResolver? _syncProgressResolver;
- public ISyncProgressResolver SyncProgressResolver => _syncProgressResolver ??= new SyncProgressResolver(
- _blockTree,
- new FullStateFinder(_blockTree, _stateReader),
- _syncConfig,
- HeadersSyncFeed,
- BodiesSyncFeed,
- ReceiptsSyncFeed,
- SnapSyncFeed,
- _logManager);
-
- protected ISyncModeSelector? _syncModeSelector;
- private readonly IStateReader _stateReader;
- private readonly INodeStorage _nodeStorage;
- private readonly ProgressTracker _progressTracker;
-
- public virtual ISyncModeSelector SyncModeSelector => _syncModeSelector ??= new MultiSyncModeSelector(
- SyncProgressResolver,
- _syncPeerPool!,
- _syncConfig,
- No.BeaconSync,
- _betterPeerStrategy!,
- _logManager,
- _chainSpec?.SealEngineType == SealEngineType.Clique);
-
- public Synchronizer(
- IDbProvider dbProvider,
- INodeStorage nodeStorage,
- ISpecProvider specProvider,
- IBlockTree blockTree,
- IReceiptStorage receiptStorage,
- ISyncPeerPool peerPool,
- INodeStatsManager nodeStatsManager,
- ISyncConfig syncConfig,
- IBlockDownloaderFactory blockDownloaderFactory,
- IPivot pivot,
- IProcessExitSource processExitSource,
- IBetterPeerStrategy betterPeerStrategy,
- ChainSpec chainSpec,
- IStateReader stateReader,
- ILogManager logManager)
- {
- _dbProvider = dbProvider ?? throw new ArgumentNullException(nameof(dbProvider));
- _nodeStorage = nodeStorage ?? throw new ArgumentNullException(nameof(nodeStorage));
- _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
- _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
- _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
- _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
- _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig));
- _blockDownloaderFactory = blockDownloaderFactory ?? throw new ArgumentNullException(nameof(blockDownloaderFactory));
- _pivot = pivot ?? throw new ArgumentNullException(nameof(pivot));
- _syncPeerPool = peerPool ?? throw new ArgumentNullException(nameof(peerPool));
- _nodeStatsManager = nodeStatsManager ?? throw new ArgumentNullException(nameof(nodeStatsManager));
- _exitSource = processExitSource ?? throw new ArgumentNullException(nameof(processExitSource));
- _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager));
- _betterPeerStrategy = betterPeerStrategy ?? throw new ArgumentNullException(nameof(betterPeerStrategy));
- _chainSpec = chainSpec ?? throw new ArgumentNullException(nameof(chainSpec));
- _stateReader = stateReader ?? throw new ArgumentNullException(nameof(_stateReader));
-
- _syncReport = new SyncReport(_syncPeerPool!, nodeStatsManager!, _syncConfig, _pivot, logManager);
-
- _progressTracker = new(
- blockTree,
- dbProvider.StateDb,
- logManager,
- _syncConfig.SnapSyncAccountRangePartitionCount);
- SnapProvider = new SnapProvider(_progressTracker, dbProvider.CodeDb, nodeStorage, logManager);
- }
+ public ISyncModeSelector SyncModeSelector => syncModeSelector;
public virtual void Start()
{
- if (!_syncConfig.SynchronizationEnabled)
+ if (!syncConfig.SynchronizationEnabled)
{
return;
}
StartFullSyncComponents();
- if (_syncConfig.FastSync)
+ if (syncConfig.FastSync)
{
StartFastBlocksComponents();
StartFastSyncComponents();
- if (_syncConfig.SnapSync)
+ if (syncConfig.SnapSync)
{
StartSnapSyncComponents();
}
@@ -170,72 +79,20 @@ public virtual void Start()
StartStateSyncComponents();
}
- if (_syncConfig.TuneDbMode != ITunableDb.TuneType.Default || _syncConfig.BlocksDbTuneDbMode != ITunableDb.TuneType.Default)
+ if (syncConfig.ExitOnSynced)
{
- SetupDbOptimizer();
- }
-
- if (_syncConfig.ExitOnSynced)
- {
- _exitSource.WatchForExit(SyncModeSelector, _logManager, TimeSpan.FromSeconds(_syncConfig.ExitOnSyncedWaitTimeSec));
+ exitSource.WatchForExit(SyncModeSelector, logManager, TimeSpan.FromSeconds(syncConfig.ExitOnSyncedWaitTimeSec));
}
WireMultiSyncModeSelector();
- s_trimmer ??= new MallocTrimmer(SyncModeSelector, TimeSpan.FromSeconds(_syncConfig.MallocTrimIntervalSec), _logManager);
- SyncModeSelector.Changed += _syncReport.SyncModeSelectorOnChanged;
- }
-
- private HeadersSyncFeed? CreateHeadersSyncFeed()
- {
- if (!_syncConfig.FastSync || !_syncConfig.DownloadHeadersInFastSync) return null;
- return new HeadersSyncFeed(_blockTree, _syncPeerPool, _syncConfig, _syncReport, _logManager);
- }
-
- private BodiesSyncFeed? CreateBodiesSyncFeed()
- {
- if (!_syncConfig.FastSync || !_syncConfig.DownloadHeadersInFastSync || !_syncConfig.DownloadBodiesInFastSync) return null;
- return new BodiesSyncFeed(_specProvider, _blockTree, _syncPeerPool, _syncConfig, _syncReport, _dbProvider.BlocksDb, _dbProvider.MetadataDb, _logManager);
- }
-
- private ReceiptsSyncFeed? CreateReceiptsSyncFeed()
- {
- if (!_syncConfig.FastSync || !_syncConfig.DownloadHeadersInFastSync || !_syncConfig.DownloadBodiesInFastSync || !_syncConfig.DownloadReceiptsInFastSync) return null;
- return new ReceiptsSyncFeed(_specProvider, _blockTree, _receiptStorage, _syncPeerPool, _syncConfig, _syncReport, _dbProvider.MetadataDb, _logManager);
- }
-
- private SnapSyncFeed? CreateSnapSyncFeed()
- {
- if (!_syncConfig.FastSync || !_syncConfig.SnapSync) return null;
- return new SnapSyncFeed(SnapProvider, _logManager);
- }
-
- private void SetupDbOptimizer()
- {
- s_dbTuner ??= new SyncDbTuner(
- _syncConfig,
- SnapSyncFeed,
- BodiesSyncFeed,
- ReceiptsSyncFeed,
- _dbProvider.StateDb as ITunableDb,
- _dbProvider.CodeDb as ITunableDb,
- _dbProvider.BlocksDb as ITunableDb,
- _dbProvider.ReceiptsDb as ITunableDb);
+ SyncModeSelector.Changed += syncReport.SyncModeSelectorOnChanged;
}
private void StartFullSyncComponents()
{
- _fullSyncFeed = new FullSyncFeed();
- BlockDownloader fullSyncBlockDownloader = _blockDownloaderFactory.Create(_fullSyncFeed, _blockTree, _receiptStorage, _syncPeerPool, _syncReport);
- fullSyncBlockDownloader.SyncEvent += DownloaderOnSyncEvent;
-
- SyncDispatcher dispatcher = CreateDispatcher(
- _fullSyncFeed,
- fullSyncBlockDownloader,
- _blockDownloaderFactory.CreateAllocationStrategyFactory()
- );
-
- dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
+ fullSyncComponent.BlockDownloader.SyncEvent += DownloaderOnSyncEvent;
+ fullSyncComponent.Dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -250,17 +107,8 @@ private void StartFullSyncComponents()
private void StartFastSyncComponents()
{
- _fastSyncFeed = new FastSyncFeed(_syncConfig);
- BlockDownloader downloader = _blockDownloaderFactory.Create(_fastSyncFeed, _blockTree, _receiptStorage, _syncPeerPool, _syncReport);
- downloader.SyncEvent += DownloaderOnSyncEvent;
-
- SyncDispatcher dispatcher = CreateDispatcher(
- _fastSyncFeed,
- downloader,
- _blockDownloaderFactory.CreateAllocationStrategyFactory()
- );
-
- dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
+ fastSyncComponent.BlockDownloader.SyncEvent += DownloaderOnSyncEvent;
+ fastSyncComponent.Dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -275,15 +123,7 @@ private void StartFastSyncComponents()
private void StartStateSyncComponents()
{
- TreeSync treeSync = new(SyncMode.StateNodes, _dbProvider.CodeDb, _nodeStorage, _blockTree, _logManager);
- _stateSyncFeed = new StateSyncFeed(treeSync, _logManager);
- SyncDispatcher stateSyncDispatcher = CreateDispatcher(
- _stateSyncFeed,
- new StateSyncDownloader(_logManager),
- new StateSyncAllocationStrategyFactory()
- );
-
- Task syncDispatcherTask = stateSyncDispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
+ Task syncDispatcherTask = stateSyncComponent.Dispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -296,15 +136,10 @@ private void StartStateSyncComponents()
});
}
+
private void StartSnapSyncComponents()
{
- SyncDispatcher dispatcher = CreateDispatcher(
- SnapSyncFeed,
- new SnapSyncDownloader(_logManager),
- new SnapSyncAllocationStrategyFactory()
- );
-
- Task _ = dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
+ Task _ = snapSyncComponent.Dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -319,14 +154,7 @@ private void StartSnapSyncComponents()
private void StartFastBlocksComponents()
{
- FastBlocksPeerAllocationStrategyFactory fastFactory = new();
- SyncDispatcher headersDispatcher = CreateDispatcher(
- HeadersSyncFeed,
- new HeadersSyncDownloader(_logManager),
- fastFactory
- );
-
- Task headersTask = headersDispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
+ Task headersTask = fastHeaderComponent.Dispatcher.Start(_syncCancellation!.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -338,18 +166,11 @@ private void StartFastBlocksComponents()
}
});
- if (_syncConfig.DownloadHeadersInFastSync)
+ if (syncConfig.DownloadHeadersInFastSync)
{
- if (_syncConfig.DownloadBodiesInFastSync)
+ if (syncConfig.DownloadBodiesInFastSync)
{
-
- SyncDispatcher bodiesDispatcher = CreateDispatcher(
- BodiesSyncFeed!,
- new BodiesSyncDownloader(_logManager),
- fastFactory
- );
-
- Task bodiesTask = bodiesDispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
+ Task bodiesTask = oldBodiesComponent.Dispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -362,15 +183,9 @@ private void StartFastBlocksComponents()
});
}
- if (_syncConfig.DownloadReceiptsInFastSync)
+ if (syncConfig.DownloadReceiptsInFastSync)
{
- SyncDispatcher receiptsDispatcher = CreateDispatcher(
- ReceiptsSyncFeed!,
- new ReceiptsSyncDispatcher(_logManager),
- fastFactory
- );
-
- Task receiptsTask = receiptsDispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
+ Task receiptsTask = oldReceiptsComponent.Dispatcher.Start(_syncCancellation.Token).ContinueWith(t =>
{
if (t.IsFaulted)
{
@@ -385,17 +200,6 @@ private void StartFastBlocksComponents()
}
}
- protected SyncDispatcher CreateDispatcher(ISyncFeed feed, ISyncDownloader downloader, IPeerAllocationStrategyFactory peerAllocationStrategyFactory)
- {
- return new(
- _syncConfig.MaxProcessingThreads,
- feed!,
- downloader,
- _syncPeerPool,
- peerAllocationStrategyFactory,
- _logManager);
- }
-
private static NodeStatsEventType Convert(SyncEvent syncEvent)
{
return syncEvent switch
@@ -410,7 +214,7 @@ private static NodeStatsEventType Convert(SyncEvent syncEvent)
private void DownloaderOnSyncEvent(object? sender, SyncEventArgs e)
{
- _nodeStatsManager.ReportSyncEvent(e.Peer.Node, Convert(e.SyncEvent));
+ nodeStatsManager.ReportSyncEvent(e.Peer.Node, Convert(e.SyncEvent));
SyncEvent?.Invoke(this, e);
}
@@ -421,27 +225,27 @@ public Task StopAsync()
return Task.WhenAny(
Task.Delay(FeedsTerminationTimeout),
Task.WhenAll(
- _fastSyncFeed?.FeedTask ?? Task.CompletedTask,
- _stateSyncFeed?.FeedTask ?? Task.CompletedTask,
- SnapSyncFeed?.FeedTask ?? Task.CompletedTask,
- _fullSyncFeed?.FeedTask ?? Task.CompletedTask,
- HeadersSyncFeed?.FeedTask ?? Task.CompletedTask,
- BodiesSyncFeed?.FeedTask ?? Task.CompletedTask,
- ReceiptsSyncFeed?.FeedTask ?? Task.CompletedTask));
+ fullSyncComponent.Feed.FeedTask,
+ fastSyncComponent.Feed.FeedTask,
+ stateSyncComponent.Feed.FeedTask,
+ snapSyncComponent.Feed.FeedTask,
+ fastHeaderComponent.Feed.FeedTask,
+ oldBodiesComponent.Feed.FeedTask,
+ oldReceiptsComponent.Feed.FeedTask));
}
private void WireMultiSyncModeSelector()
{
- WireFeedWithModeSelector(_fastSyncFeed);
- WireFeedWithModeSelector(_stateSyncFeed);
- WireFeedWithModeSelector(SnapSyncFeed);
- WireFeedWithModeSelector(_fullSyncFeed);
- WireFeedWithModeSelector(HeadersSyncFeed);
- WireFeedWithModeSelector(BodiesSyncFeed);
- WireFeedWithModeSelector(ReceiptsSyncFeed);
+ WireFeedWithModeSelector(fullSyncComponent.Feed);
+ WireFeedWithModeSelector(fastSyncComponent.Feed);
+ WireFeedWithModeSelector(stateSyncComponent.Feed);
+ WireFeedWithModeSelector(snapSyncComponent.Feed);
+ WireFeedWithModeSelector(fastHeaderComponent.Feed);
+ WireFeedWithModeSelector(oldBodiesComponent.Feed);
+ WireFeedWithModeSelector(oldReceiptsComponent.Feed);
}
- protected void WireFeedWithModeSelector(ISyncFeed? feed)
+ public void WireFeedWithModeSelector(ISyncFeed? feed)
{
if (feed is null) return;
SyncModeSelector.Changed += ((sender, args) =>
@@ -454,17 +258,141 @@ protected void WireFeedWithModeSelector(ISyncFeed? feed)
public void Dispose()
{
CancellationTokenExtensions.CancelDisposeAndClear(ref _syncCancellation);
- _syncReport.Dispose();
- _fastSyncFeed?.Dispose();
- _stateSyncFeed?.Dispose();
- _stateSyncFeed = null;
- SnapSyncFeed?.Dispose();
- _snapSyncFeed = null;
- _fullSyncFeed?.Dispose();
- HeadersSyncFeed?.Dispose();
- BodiesSyncFeed?.Dispose();
- ReceiptsSyncFeed?.Dispose();
- _progressTracker.Dispose();
}
}
}
+
+public class SynchronizerModule(ISyncConfig syncConfig) : Module
+{
+ protected override void Load(ContainerBuilder builder)
+ {
+ base.Load(builder);
+
+ builder
+ .AddSingleton()
+
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+
+ // For blocks. There are two block scope, Fast and Full
+ .AddScoped>()
+ .AddScoped, BlockDownloader>()
+ .AddScoped, BlocksSyncPeerAllocationStrategyFactory>()
+ .AddScoped>()
+
+ // For headers. There are two header scope, Fast and Beacon
+ .AddScoped>()
+ .AddScoped, HeadersSyncDownloader>()
+ .AddScoped, FastBlocksPeerAllocationStrategyFactory>()
+ .AddScoped>()
+
+ // SyncProgress resolver need one header sync batch feed, which is the fast header one.
+ .Register(ctx => ctx
+ .ResolveNamed>(nameof(HeadersSyncFeed))
+ .Feed)
+ .Named>(nameof(HeadersSyncFeed));
+
+ ConfigureSnapComponent(builder);
+ ConfigureReceiptSyncComponent(builder);
+ ConfigureBodiesSyncComponent(builder);
+ ConfigureStateSyncComponent(builder);
+
+ builder
+ .RegisterNamedComponentInItsOwnLifetime>(nameof(HeadersSyncFeed), ConfigureFastHeader)
+ .RegisterNamedComponentInItsOwnLifetime>(nameof(FastSyncFeed), ConfigureFastSync)
+ .RegisterNamedComponentInItsOwnLifetime>(nameof(FullSyncFeed), ConfigureFullSync);
+ }
+
+ private void ConfigureFullSync(ContainerBuilder scopeConfig)
+ {
+ scopeConfig.AddScoped, FullSyncFeed>();
+ }
+
+ private void ConfigureFastSync(ContainerBuilder scopeConfig)
+ {
+ if (syncConfig.FastSync)
+ {
+ scopeConfig.AddScoped, FastSyncFeed>();
+ }
+ else
+ {
+ scopeConfig.AddScoped, NoopSyncFeed>();
+ }
+ }
+
+ private void ConfigureFastHeader(ContainerBuilder scopeConfig)
+ {
+ if (!syncConfig.FastSync || !syncConfig.DownloadHeadersInFastSync)
+ {
+ scopeConfig.AddScoped, NoopSyncFeed>();
+ }
+ else
+ {
+ scopeConfig.AddScoped, HeadersSyncFeed>();
+ }
+ }
+
+ private void ConfigureSnapComponent(ContainerBuilder serviceCollection)
+ {
+ serviceCollection
+ .AddSingleton