From 18fef4d6dce4a9bdfa9193ce8224885cdb93a776 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Sat, 28 Sep 2024 08:55:47 +0800 Subject: [PATCH 01/25] Migrate more of network initialization --- .../Extensions/ISynchronizationPlugin.cs | 4 +- .../Nethermind.Api/IApiWithBlockchain.cs | 10 +- .../Nethermind.Api/IApiWithNetwork.cs | 25 +- src/Nethermind/Nethermind.Api/IBasicApi.cs | 9 +- .../Nethermind.Api/NethermindApi.cs | 39 +- .../ConfigRegistrationSource.cs | 51 +++ .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 9 +- .../ContainerBuilderExtensions.cs | 12 + src/Nethermind/Nethermind.Db/IDbProvider.cs | 1 + .../EthStatsPluginTests.cs | 2 +- .../Steps/InitializeNetwork.cs | 430 +++++++++--------- .../Steps/InitializeNodeStats.cs | 36 -- .../MergePluginTests.cs | 27 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 80 ++-- .../Synchronization/BeaconPivot.cs | 3 +- .../Synchronization/PivotUpdator.cs | 3 +- .../Config/INetworkConfig.cs | 0 .../Config/NetworkConfig.cs | 0 .../Nethermind.Network.Contract.csproj | 3 + .../Discv5/DiscoveryV5App.cs | 3 + .../NodeSourceToDiscV4Feeder.cs | 6 + src/Nethermind/Nethermind.Network/ForkInfo.cs | 6 + .../Nethermind.Network/INodeSource.cs | 2 + .../Nethermind.Network/NetworkStorage.cs | 4 +- .../Subprotocols/Snap/SnapProtocolHandler.cs | 3 +- .../Rlpx/Handshake/HandshakeService.cs | 11 + .../Nethermind.Network/Rlpx/RlpxHost.cs | 15 + .../Nethermind.Optimism/OptimismPlugin.cs | 65 ++- .../Ethereum/ContextWithMocks.cs | 77 +++- .../OldStyleFullSynchronizerTests.cs | 46 +- .../SyncThreadTests.cs | 48 +- .../SynchronizerTests.cs | 51 +-- .../Peers/SyncPeerPool.cs | 10 + .../SnapSync/ISnapServer.cs | 2 + .../SnapSync/SnapServer.cs | 14 +- .../Nethermind.Synchronization/SyncServer.cs | 6 +- .../Synchronizer.cs | 11 +- 37 files changed, 617 insertions(+), 507 deletions(-) create mode 100644 src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs delete mode 100644 src/Nethermind/Nethermind.Init/Steps/InitializeNodeStats.cs rename src/Nethermind/{Nethermind.Network => Nethermind.Network.Contract}/Config/INetworkConfig.cs (100%) rename src/Nethermind/{Nethermind.Network => Nethermind.Network.Contract}/Config/NetworkConfig.cs (100%) diff --git a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs index 9defba7560c..02814693706 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs @@ -2,11 +2,13 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Threading.Tasks; +using Autofac; namespace Nethermind.Api.Extensions { public interface ISynchronizationPlugin : INethermindPlugin { - Task InitSynchronization(); + void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder); + Task InitSynchronization(IContainer container); } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index da24eaa918b..ab8caeb0cbc 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -93,20 +93,24 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory IGasPriceOracle? GasPriceOracle { get; set; } - IEthSyncingInfo? EthSyncingInfo { get; set; } + IEthSyncingInfo? EthSyncingInfo { get; } CompositePruningTrigger PruningTrigger { get; } IBlockProductionPolicy? BlockProductionPolicy { get; set; } INodeStorageFactory NodeStorageFactory { get; set; } - BackgroundTaskScheduler BackgroundTaskScheduler { get; set; } + IBackgroundTaskScheduler BackgroundTaskScheduler { get; set; } CensorshipDetector CensorshipDetector { get; set; } public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(ContainerBuilder builder) { - return ConfigureContainerBuilderFromApiWithStores(builder) + ConfigureContainerBuilderFromApiWithStores(builder) .AddPropertiesFrom(this) .AddSingleton(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); + + if (TrieStore != null) builder.AddSingleton(TrieStore.AsReadOnly()); + + return builder; } } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs index 0b0e05e2a6d..f7cbeb251a6 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs @@ -26,31 +26,26 @@ public interface IApiWithNetwork : IApiWithBlockchain { (IApiWithNetwork GetFromApi, IApiWithNetwork SetInApi) ForNetwork => (this, this); - IDisconnectsAnalyzer? DisconnectsAnalyzer { get; set; } - IDiscoveryApp? DiscoveryApp { get; set; } + IDiscoveryApp? DiscoveryApp { get; } IGrpcServer? GrpcServer { get; set; } IIPResolver? IpResolver { get; set; } IMessageSerializationService MessageSerializationService { get; } IGossipPolicy GossipPolicy { get; set; } IMonitoringService MonitoringService { get; set; } - INodeStatsManager? NodeStatsManager { get; set; } - IPeerManager? PeerManager { get; set; } - IPeerPool? PeerPool { get; set; } - IProtocolsManager? ProtocolsManager { get; set; } - IProtocolValidator? ProtocolValidator { get; set; } + INodeStatsManager? NodeStatsManager { get; } + IPeerManager? PeerManager { get; } + IPeerPool? PeerPool { get; } IList Publishers { get; } - IRlpxHost? RlpxPeer { get; set; } + IRlpxHost? RlpxPeer { get; } IRpcModuleProvider? RpcModuleProvider { get; set; } IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } - ISessionMonitor? SessionMonitor { get; set; } - IStaticNodesManager? StaticNodesManager { get; set; } + ISessionMonitor? SessionMonitor { get; } + IStaticNodesManager? StaticNodesManager { get; } 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; } + ISyncPeerPool? SyncPeerPool { get; } + IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool { get; } + ISyncServer? SyncServer { get; } IWebSocketsManager WebSocketsManager { get; set; } ISubscriptionFactory? SubscriptionFactory { get; set; } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 1ba0adb91f9..747d1faebec 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -17,6 +17,7 @@ using Nethermind.Db; using Nethermind.KeyStore; using Nethermind.Logging; +using Nethermind.Network.Config; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Synchronization; @@ -43,7 +44,7 @@ public interface IBasicApi [SkipServiceCollection] string SealEngineType { get; set; } ISpecProvider? SpecProvider { get; set; } - IBetterPeerStrategy? BetterPeerStrategy { get; set; } + IBetterPeerStrategy? BetterPeerStrategy { get; } ITimestamper Timestamper { get; } ITimerFactory TimerFactory { get; } IProcessExitSource? ProcessExit { get; set; } @@ -61,9 +62,9 @@ public IEnumerable GetSynchronizationPlugins() => public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder builder) { - builder - .AddPropertiesFrom(this) - .AddSingleton(ConfigProvider.GetConfig()); + builder.AddPropertiesFrom(this); + builder.Register(ecdsa => ecdsa); + builder.RegisterSource(new ConfigRegistrationSource()); DbProvider!.ConfigureServiceCollection(builder); diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 566a094eaa0..aa4a2f49f3a 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -128,8 +128,8 @@ public IBlockchainBridge CreateBlockchainBridge() public ICryptoRandom CryptoRandom { get; } public IDbProvider? DbProvider { get; set; } public IDbFactory? DbFactory { get; set; } - public IDisconnectsAnalyzer? DisconnectsAnalyzer { get; set; } - public IDiscoveryApp? DiscoveryApp { get; set; } + + public IDiscoveryApp? DiscoveryApp => ApiWithNetworkServiceContainer?.ResolveOptional(); public ISigner? EngineSigner { get; set; } public ISignerStore? EngineSignerStore { get; set; } public IEnode? Enode { get; set; } @@ -154,16 +154,14 @@ public IBlockchainBridge CreateBlockchainBridge() public IMessageSerializationService MessageSerializationService { get; } = new MessageSerializationService(); public IGossipPolicy GossipPolicy { get; set; } = Policy.FullGossip; public IMonitoringService MonitoringService { get; set; } = NullMonitoringService.Instance; - public INodeStatsManager? NodeStatsManager { get; set; } - public IPeerManager? PeerManager { get; set; } - public IPeerPool? PeerPool { get; set; } - public IProtocolsManager? ProtocolsManager { get; set; } - public IProtocolValidator? ProtocolValidator { get; set; } + public INodeStatsManager? NodeStatsManager => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IPeerManager? PeerManager => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IPeerPool? PeerPool => ApiWithNetworkServiceContainer?.ResolveOptional(); public IReceiptStorage? ReceiptStorage { get; set; } public IReceiptFinder? ReceiptFinder { get; set; } public IReceiptMonitor? ReceiptMonitor { get; set; } public IRewardCalculatorSource? RewardCalculatorSource { get; set; } = NoBlockRewards.Instance; - public IRlpxHost? RlpxPeer { get; set; } + public IRlpxHost? RlpxPeer => ApiWithNetworkServiceContainer?.ResolveOptional(); public IRpcModuleProvider? RpcModuleProvider { get; set; } = NullModuleProvider.Instance; public IRpcAuthentication? RpcAuthentication { get; set; } public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } @@ -184,23 +182,22 @@ public ISealEngine SealEngine } } - public ISessionMonitor? SessionMonitor { get; set; } + public ISessionMonitor? SessionMonitor => ApiWithNetworkServiceContainer?.ResolveOptional(); public ISpecProvider? SpecProvider { get; set; } public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; - public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.Resolve()!; - - 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 => ApiWithNetworkServiceContainer?.Resolve(); - public ISyncServer? SyncServer { get; set; } + public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.ResolveOptional()!; + public IBetterPeerStrategy? BetterPeerStrategy => ApiWithNetworkServiceContainer?.ResolveOptional(); + public ISyncPeerPool? SyncPeerPool => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool => ApiWithNetworkServiceContainer?.ResolveOptional(); + public ISynchronizer? Synchronizer => ApiWithNetworkServiceContainer?.ResolveOptional(); + public ISyncServer? SyncServer => ApiWithNetworkServiceContainer?.ResolveOptional(); + + [SkipServiceCollection] public IWorldState? WorldState { get; set; } public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } public IWorldStateManager? WorldStateManager { get; set; } public IStateReader? StateReader { get; set; } - public IStaticNodesManager? StaticNodesManager { get; set; } + public IStaticNodesManager? StaticNodesManager => ApiWithNetworkServiceContainer?.ResolveOptional(); public ITimestamper Timestamper { get; } = Core.Timestamper.Default; public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default; public ITransactionProcessor? TransactionProcessor { get; set; } @@ -219,10 +216,10 @@ public ISealEngine SealEngine public IBlockImprovementContextFactory? BlockImprovementContextFactory { get; set; } public IGasPriceOracle? GasPriceOracle { get; set; } - public IEthSyncingInfo? EthSyncingInfo { get; set; } + public IEthSyncingInfo? EthSyncingInfo => ApiWithNetworkServiceContainer?.ResolveOptional(); public IBlockProductionPolicy? BlockProductionPolicy { get; set; } public INodeStorageFactory NodeStorageFactory { get; set; } = null!; - public BackgroundTaskScheduler BackgroundTaskScheduler { get; set; } = null!; + public IBackgroundTaskScheduler BackgroundTaskScheduler { get; set; } = null!; public CensorshipDetector CensorshipDetector { get; set; } = null!; public IWallet? Wallet { get; set; } public IBlockStore? BadBlocksStore { get; set; } diff --git a/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs b/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs new file mode 100644 index 00000000000..883213e83c9 --- /dev/null +++ b/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Generic; +using System.Linq; +using Autofac; +using Autofac.Core; +using Autofac.Core.Activators.Delegate; +using Autofac.Core.Lifetime; +using Autofac.Core.Registration; + +namespace Nethermind.Config; + +/// +/// Dynamically resolve IConfig +/// +public class ConfigRegistrationSource : IRegistrationSource +{ + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + IServiceWithType swt = service as IServiceWithType; + if (swt == null || !typeof(IConfig).IsAssignableFrom(swt.ServiceType)) + { + // It's not a request for the base handler type, so skip it. + return Enumerable.Empty(); + } + + // Dynamically resolve IConfig + ComponentRegistration registration = new ComponentRegistration( + Guid.NewGuid(), + new DelegateActivator(swt.ServiceType, (c, p) => + { + IConfigProvider configProvider = c.Resolve(); + object config = typeof(IConfigProvider) + .GetMethod("GetConfig") + .MakeGenericMethod(swt.ServiceType) + .Invoke(configProvider, new object[] { }); + return config; + }), + new RootScopeLifetime(), + InstanceSharing.Shared, + InstanceOwnership.OwnedByLifetimeScope, + new[] { service }, + new Dictionary()); + + return new IComponentRegistration[] { registration }; + } + + public bool IsAdapterForIndividualComponents => false; +} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index f3c766da5f0..535746f6d0c 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -3,6 +3,7 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; +using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Config; @@ -12,6 +13,7 @@ using Nethermind.Logging; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; +using Nethermind.Synchronization; [assembly: InternalsVisibleTo("Nethermind.Merge.AuRa")] @@ -49,13 +51,16 @@ public Task Init(INethermindApi nethermindApi) return Task.CompletedTask; } - public Task InitSynchronization() + public void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder) { if (_nethermindApi is not null) { - _nethermindApi.BetterPeerStrategy = new AuRaBetterPeerStrategy(_nethermindApi.BetterPeerStrategy!, _nethermindApi.LogManager); + containerBuilder.RegisterDecorator(); } + } + public Task InitSynchronization(IContainer container) + { return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs index 1c30a830b55..8df60a5ba5b 100644 --- a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs @@ -115,6 +115,18 @@ public static ContainerBuilder RegisterNamedComponentInItsOwnLifetime(this Co return builder; } + + /// + /// Shorthand for registering a constructor that resolve TImpl as TAs. + /// This is useful for clarity or for conditional registration where TImpl is declared somewhere else. + /// + public static ContainerBuilder Bind(this ContainerBuilder builder) where TImpl : notnull where TAs : notnull + { + builder.Register(ctx => ctx.Resolve()) + .As(); + + return builder; + } } /// diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 6a0380b0446..59bdcc4105c 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -56,6 +56,7 @@ void ConfigureServiceCollection(ContainerBuilder sc) sc.AddKeyedSingleton(dbName, db); sc.AddKeyedSingleton(dbName, db); sc.AddKeyedSingleton(dbName, db as ITunableDb ?? new NoopTunableDb()); + sc.AddKeyedSingleton(dbName, db); } IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts); diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs index e0fffd67b31..ec9877762c4 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs @@ -20,7 +20,7 @@ public class EthStatsPluginTests [SetUp] public void Setup() { - _context = Build.ContextWithMocks(); + _context = Build.ContextWithMocksWithTestContainer(); _plugin = new EthStatsPlugin(); } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index db2854c0003..14bd322ee5e 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -15,6 +15,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Utils; using Nethermind.Core; +using Nethermind.Core.Timers; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Facade.Eth; @@ -32,14 +33,15 @@ using Nethermind.Network.Rlpx; using Nethermind.Network.Rlpx.Handshake; using Nethermind.Network.StaticNodes; +using Nethermind.Specs.ChainSpecStyle; +using Nethermind.Stats; using Nethermind.Stats.Model; using Nethermind.Synchronization; -using Nethermind.Synchronization.Blocks; using Nethermind.Synchronization.ParallelSync; using Nethermind.Synchronization.Peers; using Nethermind.Synchronization.SnapSync; using Nethermind.Synchronization.Trie; -using Nethermind.TxPool; +using Module = Autofac.Module; namespace Nethermind.Init.Steps; @@ -58,13 +60,12 @@ public static long Estimate(uint arenaCount, int arenaOrder) typeof(LoadGenesisBlock), typeof(UpdateDiscoveryConfig), typeof(SetupKeyStore), - typeof(InitializeNodeStats), typeof(ResolveIps), typeof(InitializePlugins), typeof(InitializeBlockchain))] public class InitializeNetwork : IStep { - private const string PeersDbPath = "peers"; + public const string PeersDbPath = "peers"; protected readonly IApiWithNetwork _api; private readonly ILogger _logger; @@ -86,9 +87,6 @@ public async Task Execute(CancellationToken cancellationToken) private async Task Initialize(CancellationToken cancellationToken) { - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); - if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); - if (_networkConfig.DiagTracerEnabled) { NetworkDiagTracer.IsEnabled = true; @@ -99,77 +97,68 @@ private async Task Initialize(CancellationToken cancellationToken) NetworkDiagTracer.Start(_api.LogManager); } - _api.BetterPeerStrategy = new TotalDifficultyBetterPeerStrategy(_api.LogManager); + if (_api.ChainSpec.SealEngineType == SealEngineType.Clique) + _syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself? int maxPeersCount = _networkConfig.ActivePeersMaxCount; - int maxPriorityPeersCount = _networkConfig.PriorityPeersMaxCount; Network.Metrics.PeerLimit = maxPeersCount; - SyncPeerPool apiSyncPeerPool = new(_api.BlockTree, _api.NodeStatsManager!, _api.BetterPeerStrategy, _api.LogManager, maxPeersCount, maxPriorityPeersCount); - _api.SyncPeerPool = apiSyncPeerPool; - _api.PeerDifficultyRefreshPool = apiSyncPeerPool; - _api.DisposeStack.Push(_api.SyncPeerPool); + ContainerBuilder builder = new ContainerBuilder(); + _api.ConfigureContainerBuilderFromApiWithNetwork(builder); + builder.RegisterModule(new NetworkModule(_networkConfig, _syncConfig)); - if (_api.TrieStore is HealingTrieStore healingTrieStore) - { - healingTrieStore.InitializeNetwork(new GetNodeDataTrieNodeRecovery(apiSyncPeerPool, _api.LogManager)); - } + ISynchronizationPlugin[] synchronizationPlugins = _api.GetSynchronizationPlugins().ToArray(); - if (_api.WorldState is HealingWorldState healingWorldState) + foreach (ISynchronizationPlugin plugin in synchronizationPlugins) { - healingWorldState.InitializeNetwork(new SnapTrieNodeRecovery(apiSyncPeerPool, _api.LogManager)); + plugin.ConfigureSynchronizationBuilder(builder); } - IEnumerable synchronizationPlugins = _api.GetSynchronizationPlugins(); + IContainer container = builder.Build(); + _api.ApiWithNetworkServiceContainer = container; + _api.DisposeStack.Append(container); + foreach (ISynchronizationPlugin plugin in synchronizationPlugins) { - await plugin.InitSynchronization(); + await plugin.InitSynchronization(container); } - _api.Pivot ??= new Pivot(_syncConfig); + // TODO: This whole thing can be injected into `InitializeNetwork`, but the container then + // need to be put at a higher level. + SyncedTxGossipPolicy txGossipPolicy = container.Resolve(); + ISyncServer _ = container.Resolve(); + IDiscoveryApp discoveryApp = container.Resolve(); + IPeerPool peerPool = container.Resolve(); + IPeerManager peerManager = container.Resolve(); + ISessionMonitor sessionMonitor = container.Resolve(); + IRlpxHost rlpxHost = container.Resolve(); + IStaticNodesManager staticNodesManager = container.Resolve(); + Func nodeSourceToDiscV4Feeder = container.Resolve>(); + IProtocolsManager protocolsManager = container.Resolve(); + EnrDiscovery enrDiscover = container.Resolve(); + SnapCapabilitySwitcher snapCapabilitySwitcher = container.Resolve(); + ISyncPeerPool syncPeerPool = container.Resolve(); + ISynchronizer synchronizer = container.Resolve(); + + _api.TxGossipPolicy.Policies.Add(txGossipPolicy); - if (_api.Synchronizer is null) + if (_api.TrieStore is HealingTrieStore healingTrieStore) { - if (_api.ChainSpec.SealEngineType == SealEngineType.Clique) - _syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself? - - ContainerBuilder builder = new ContainerBuilder(); - _api.ConfigureContainerBuilderFromApiWithNetwork(builder) - .AddSingleton(No.BeaconSync); - builder.RegisterModule(new SynchronizerModule(_syncConfig)); - IContainer container = builder.Build(); + healingTrieStore.InitializeNetwork(container.Resolve()); + } - _api.ApiWithNetworkServiceContainer = container; - _api.DisposeStack.Append(container); + if (_api.WorldState is HealingWorldState healingWorldState) + { + healingWorldState.InitializeNetwork(container.Resolve()); } - _api.EthSyncingInfo = new EthSyncingInfo(_api.BlockTree, _api.ReceiptStorage!, _syncConfig, - _api.SyncModeSelector!, _api.SyncProgressResolver!, _api.LogManager); - _api.TxGossipPolicy.Policies.Add(new SyncedTxGossipPolicy(_api.SyncModeSelector)); - - ISyncServer syncServer = _api.SyncServer = new SyncServer( - _api.TrieStore!.TrieNodeRlpStore, - _api.DbProvider.CodeDb, - _api.BlockTree, - _api.ReceiptStorage!, - _api.BlockValidator!, - _api.SealValidator!, - _api.SyncPeerPool, - _api.SyncModeSelector, - _api.Config(), - _api.GossipPolicy, - _api.SpecProvider!, - _api.LogManager); - - _api.DisposeStack.Push(syncServer); - - InitDiscovery(); + InitDiscovery(discoveryApp); if (cancellationToken.IsCancellationRequested) { return; } - await InitPeer().ContinueWith(initPeerTask => + await InitPeer(rlpxHost, staticNodesManager, nodeSourceToDiscV4Feeder, protocolsManager).ContinueWith(initPeerTask => { if (initPeerTask.IsFaulted) { @@ -179,8 +168,6 @@ await InitPeer().ContinueWith(initPeerTask => if (_syncConfig.SnapSync && _syncConfig.SnapServingEnabled != true) { - SnapCapabilitySwitcher snapCapabilitySwitcher = - new(_api.ProtocolsManager, _api.SyncModeSelector, _api.LogManager); snapCapabilitySwitcher.EnableSnapCapabilityUntilSynced(); } @@ -191,7 +178,7 @@ await InitPeer().ContinueWith(initPeerTask => return; } - await StartSync().ContinueWith(initNetTask => + await StartSync(syncPeerPool, synchronizer).ContinueWith(initNetTask => { if (initNetTask.IsFaulted) { @@ -204,7 +191,7 @@ await StartSync().ContinueWith(initNetTask => return; } - await StartDiscovery().ContinueWith(initDiscoveryTask => + await StartDiscovery(discoveryApp).ContinueWith(initDiscoveryTask => { if (initDiscoveryTask.IsFaulted) { @@ -219,7 +206,7 @@ await StartDiscovery().ContinueWith(initDiscoveryTask => return; } - StartPeer(); + StartPeer(peerPool, peerManager, sessionMonitor); } catch (Exception e) { @@ -237,10 +224,8 @@ await StartDiscovery().ContinueWith(initDiscoveryTask => ThisNodeInfo.AddInfo("Node address :", $"{_api.Enode.Address} (do not use as an account)"); } - private Task StartDiscovery() + private Task StartDiscovery(IDiscoveryApp discoveryApp) { - if (_api.DiscoveryApp is null) throw new StepDependencyException(nameof(_api.DiscoveryApp)); - if (!_api.Config().DiscoveryEnabled) { if (_logger.IsWarn) _logger.Warn($"Skipping discovery init due to {nameof(IInitConfig.DiscoveryEnabled)} set to false"); @@ -248,68 +233,41 @@ private Task StartDiscovery() } if (_logger.IsDebug) _logger.Debug("Starting discovery process."); - _ = _api.DiscoveryApp.StartAsync(); + _ = discoveryApp.StartAsync(); if (_logger.IsDebug) _logger.Debug("Discovery process started."); return Task.CompletedTask; } - private void StartPeer() + private void StartPeer(IPeerPool peerPool, IPeerManager peerManager, ISessionMonitor sessionMonitor) { - if (_api.PeerManager is null) throw new StepDependencyException(nameof(_api.PeerManager)); - if (_api.SessionMonitor is null) throw new StepDependencyException(nameof(_api.SessionMonitor)); - if (_api.PeerPool is null) throw new StepDependencyException(nameof(_api.PeerPool)); - if (!_api.Config().PeerManagerEnabled) { if (_logger.IsWarn) _logger.Warn($"Skipping peer manager init due to {nameof(IInitConfig.PeerManagerEnabled)} set to false"); } if (_logger.IsDebug) _logger.Debug("Initializing peer manager"); - _api.PeerPool.Start(); - _api.PeerManager.Start(); - _api.SessionMonitor.Start(); + peerPool.Start(); + peerManager.Start(); + sessionMonitor.Start(); if (_logger.IsDebug) _logger.Debug("Peer manager initialization completed"); } - private void InitDiscovery() + private void InitDiscovery(IDiscoveryApp discoveryApp) { - if (_api.NodeStatsManager is null) throw new StepDependencyException(nameof(_api.NodeStatsManager)); - if (_api.Timestamper is null) throw new StepDependencyException(nameof(_api.Timestamper)); - if (_api.NodeKey is null) throw new StepDependencyException(nameof(_api.NodeKey)); - if (_api.CryptoRandom is null) throw new StepDependencyException(nameof(_api.CryptoRandom)); - if (_api.EthereumEcdsa is null) throw new StepDependencyException(nameof(_api.EthereumEcdsa)); - - if (!_api.Config().DiscoveryEnabled) - { - _api.DiscoveryApp = new NullDiscoveryApp(); - return; - } - - _api.DiscoveryApp = new CompositeDiscoveryApp(_api.NodeKey, - _networkConfig, _api.Config(), _api.Config(), - _api.EthereumEcdsa, _api.MessageSerializationService, - _api.LogManager, _api.Timestamper, _api.CryptoRandom, - _api.NodeStatsManager, _api.IpResolver - ); - - _api.DiscoveryApp.Initialize(_api.NodeKey.PublicKey); + discoveryApp.Initialize(_api.NodeKey!.PublicKey); } - private Task StartSync() + private Task StartSync(ISyncPeerPool syncPeerPool, ISynchronizer synchronizer) { - if (_api.SyncPeerPool is null) throw new StepDependencyException(nameof(_api.SyncPeerPool)); - if (_api.Synchronizer is null) throw new StepDependencyException(nameof(_api.Synchronizer)); - if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); - ISyncConfig syncConfig = _api.Config(); if (syncConfig.NetworkingEnabled) { - _api.SyncPeerPool!.Start(); + syncPeerPool.Start(); if (syncConfig.SynchronizationEnabled) { - if (_logger.IsDebug) _logger.Debug($"Starting synchronization from block {_api.BlockTree.Head?.Header.ToString(BlockHeader.Format.Short)}."); - _api.Synchronizer!.Start(); + if (_logger.IsDebug) _logger.Debug($"Starting synchronization from block {_api.BlockTree!.Head?.Header.ToString(BlockHeader.Format.Short)}."); + synchronizer.Start(); } else { @@ -322,29 +280,16 @@ private Task StartSync() return Task.CompletedTask; } - private async Task InitPeer() + private async Task InitPeer( + IRlpxHost rlpxHost, + IStaticNodesManager staticNodesManager, + Func nodeSourceToDiscV4Feeder, + IProtocolsManager protocolsManager + ) { - if (_api.DbProvider is null) throw new StepDependencyException(nameof(_api.DbProvider)); - if (_api.BlockTree is null) throw new StepDependencyException(nameof(_api.BlockTree)); - if (_api.ReceiptStorage is null) throw new StepDependencyException(nameof(_api.ReceiptStorage)); - if (_api.BlockValidator is null) throw new StepDependencyException(nameof(_api.BlockValidator)); - if (_api.SyncPeerPool is null) throw new StepDependencyException(nameof(_api.SyncPeerPool)); - if (_api.Synchronizer is null) throw new StepDependencyException(nameof(_api.Synchronizer)); - if (_api.Enode is null) throw new StepDependencyException(nameof(_api.Enode)); - if (_api.NodeKey is null) throw new StepDependencyException(nameof(_api.NodeKey)); - if (_api.MainBlockProcessor is null) throw new StepDependencyException(nameof(_api.MainBlockProcessor)); - if (_api.NodeStatsManager is null) throw new StepDependencyException(nameof(_api.NodeStatsManager)); - if (_api.KeyStore is null) throw new StepDependencyException(nameof(_api.KeyStore)); - if (_api.Wallet is null) throw new StepDependencyException(nameof(_api.Wallet)); - if (_api.EthereumEcdsa is null) throw new StepDependencyException(nameof(_api.EthereumEcdsa)); if (_api.SpecProvider is null) throw new StepDependencyException(nameof(_api.SpecProvider)); - if (_api.TxPool is null) throw new StepDependencyException(nameof(_api.TxPool)); - if (_api.TxSender is null) throw new StepDependencyException(nameof(_api.TxSender)); - if (_api.EthereumJsonSerializer is null) throw new StepDependencyException(nameof(_api.EthereumJsonSerializer)); - if (_api.DiscoveryApp is null) throw new StepDependencyException(nameof(_api.DiscoveryApp)); /* rlpx */ - EciesCipher eciesCipher = new(_api.CryptoRandom); Eip8MessagePad eip8Pad = new(_api.CryptoRandom); _api.MessageSerializationService.Register(new AuthEip8MessageSerializer(eip8Pad)); _api.MessageSerializationService.Register(new AckEip8MessageSerializer(eip8Pad)); @@ -353,122 +298,175 @@ private async Task InitPeer() _api.MessageSerializationService.Register(receiptsMessageSerializer); _api.MessageSerializationService.Register(new Network.P2P.Subprotocols.Eth.V66.Messages.ReceiptsMessageSerializer(receiptsMessageSerializer)); - HandshakeService encryptionHandshakeServiceA = new( - _api.MessageSerializationService, - eciesCipher, - _api.CryptoRandom, - _api.EthereumEcdsa, - _api.NodeKey.Unprotect(), - _api.LogManager); - IDiscoveryConfig discoveryConfig = _api.Config(); // TODO: hack, but changing it in all the documentation would be a nightmare _networkConfig.Bootnodes = discoveryConfig.Bootnodes; - IInitConfig initConfig = _api.Config(); - - _api.DisconnectsAnalyzer = new MetricsDisconnectsAnalyzer(); - _api.SessionMonitor = new SessionMonitor(_networkConfig, _api.LogManager); - _api.RlpxPeer = new RlpxHost( - _api.MessageSerializationService, - _api.NodeKey.PublicKey, - _networkConfig.ProcessingThreadCount, - _networkConfig.P2PPort, - _networkConfig.LocalIp, - _networkConfig.ConnectTimeoutMs, - encryptionHandshakeServiceA, - _api.SessionMonitor, - _api.DisconnectsAnalyzer, - _api.LogManager, - TimeSpan.FromMilliseconds(_networkConfig.SimulateSendLatencyMs) - ); - - await _api.RlpxPeer.Init(); - - _api.StaticNodesManager = new StaticNodesManager(initConfig.StaticNodesPath, _api.LogManager); - await _api.StaticNodesManager.InitAsync(); - - // ToDo: PeersDB is registered outside dbProvider - string dbName = "PeersDB"; - IFullDb peersDb = initConfig.DiagnosticMode == DiagnosticMode.MemDb - ? new MemDb(dbName) - : new SimpleFilePublicKeyDb(dbName, PeersDbPath.GetApplicationResourcePath(initConfig.BaseDbPath), - _api.LogManager); - - NetworkStorage peerStorage = new(peersDb, _api.LogManager); - ISyncServer syncServer = _api.SyncServer!; - ForkInfo forkInfo = new(_api.SpecProvider!, syncServer.Genesis.Hash!); - - ProtocolValidator protocolValidator = new(_api.NodeStatsManager!, _api.BlockTree, forkInfo, _api.LogManager); - PooledTxsRequestor pooledTxsRequestor = new(_api.TxPool!, _api.Config()); - - ISnapServer? snapServer = null; + await rlpxHost.Init(); + await staticNodesManager.InitAsync(); + if (_syncConfig.SnapServingEnabled == true) { - // TODO: Add a proper config for the state persistence depth. - snapServer = new SnapServer(_api.TrieStore!.AsReadOnly(), _api.DbProvider.CodeDb, new LastNStateRootTracker(_api.BlockTree, 128), _api.LogManager); + protocolsManager.AddSupportedCapability(new Capability(Protocol.Snap, 1)); } - _api.ProtocolsManager = new ProtocolsManager( - _api.SyncPeerPool!, - syncServer, - _api.BackgroundTaskScheduler, - _api.TxPool, - pooledTxsRequestor, - _api.DiscoveryApp, - _api.MessageSerializationService, - _api.RlpxPeer, - _api.NodeStatsManager, - protocolValidator, - peerStorage, - forkInfo, - _api.GossipPolicy, - _networkConfig, - snapServer, - _api.LogManager, - _api.TxGossipPolicy); + if (!_networkConfig.DisableDiscV4DnsFeeder) + { + // Feed some nodes into discoveryApp in case all bootnodes is faulty. + _ = nodeSourceToDiscV4Feeder().Run(_api.ProcessExit!.Token); + } - if (_syncConfig.SnapServingEnabled == true) + foreach (INethermindPlugin plugin in _api.Plugins) { - _api.ProtocolsManager!.AddSupportedCapability(new Capability(Protocol.Snap, 1)); + await plugin.InitNetworkProtocol(); } + } +} - _api.ProtocolValidator = protocolValidator; +public class NetworkModule(INetworkConfig networkConfig, ISyncConfig syncConfig): Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); - NodesLoader nodesLoader = new(_networkConfig, _api.NodeStatsManager, peerStorage, _api.RlpxPeer, _api.LogManager); + builder.RegisterModule(new SynchronizerModule(syncConfig)); - // I do not use the key here -> API is broken - no sense to use the node signer here - NodeRecordSigner nodeRecordSigner = new(_api.EthereumEcdsa, new PrivateKeyGenerator().Generate()); - EnrRecordParser enrRecordParser = new(nodeRecordSigner); + builder + .Register(ctx => + { + // Had to manually construct as the network config is not referrable by NodeStatsManagerv + ITimerFactory timerFactory = ctx.Resolve(); + ILogManager logManager = ctx.Resolve(); + INetworkConfig config = ctx.Resolve(); + return new NodeStatsManager(timerFactory, logManager, config.MaxCandidatePeerCount); + }) + .As() + .SingleInstance(); + + builder + .AddSingleton() + .AddSingleton(No.BeaconSync) + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + ; + + builder + .RegisterType() + .As() + .As() + .SingleInstance(); + + + builder + .AddSingleton() + .AddSingleton(); + + builder + .Register(ctx => (IDiscoveryApp)(ctx.Resolve().DiscoveryEnabled + ? ctx.Resolve() + : ctx.Resolve())) + .As() + .SingleInstance(); - if (_networkConfig.DiscoveryDns == null) + /* rlpx */ + builder + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(); + + builder + .Register(ctx => + { + // TOOD: Move StaticNodesPath to NetworkConfig. + IInitConfig initConfig = ctx.Resolve(); + ILogManager logManager = ctx.Resolve(); + return new StaticNodesManager(initConfig.StaticNodesPath, logManager); + }) + .As() + .SingleInstance(); + + builder + .Register(ctx => + { + IInitConfig initConfig = ctx.Resolve(); + ILogManager logManager = ctx.Resolve(); + + // ToDo: PeersDB is registered outside dbProvider + string dbName = "PeersDB"; + IFullDb peersDb = initConfig.DiagnosticMode == DiagnosticMode.MemDb + ? new MemDb(dbName) + : new SimpleFilePublicKeyDb(dbName, + InitializeNetwork.PeersDbPath.GetApplicationResourcePath(initConfig.BaseDbPath), + logManager); + + return peersDb; + }) + .Named(nameof(NetworkStorage)); + + + builder + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(); + + builder + .Register(ctx => + { + IEthereumEcdsa ecdsa = ctx.Resolve(); + ILogManager logManager = ctx.Resolve(); + INetworkConfig networkConfig = ctx.Resolve(); + ChainSpec chainSpec = ctx.Resolve(); + + // I do not use the key here -> API is broken - no sense to use the node signer here + NodeRecordSigner nodeRecordSigner = new(ecdsa, new PrivateKeyGenerator().Generate()); + EnrRecordParser enrRecordParser = new(nodeRecordSigner); + + if (networkConfig.DiscoveryDns == null) + { + string chainName = BlockchainIds.GetBlockchainName(chainSpec.NetworkId).ToLowerInvariant(); + networkConfig.DiscoveryDns = $"all.{chainName}.ethdisco.net"; + } + + EnrDiscovery enrDiscovery = new(enrRecordParser, networkConfig, logManager); // initialize with a proper network + + return enrDiscovery; + }) + .AsSelf() + .Named(INodeSource.EnrSource) + .SingleInstance(); + + if (!networkConfig.OnlyStaticPeers) { - string chainName = BlockchainIds.GetBlockchainName(_api.ChainSpec!.NetworkId).ToLowerInvariant(); - _networkConfig.DiscoveryDns = $"all.{chainName}.ethdisco.net"; + builder + .Bind() + .Bind(); } - - EnrDiscovery enrDiscovery = new(enrRecordParser, _networkConfig, _api.LogManager); // initialize with a proper network - - if (!_networkConfig.DisableDiscV4DnsFeeder) + else { - // Feed some nodes into discoveryApp in case all bootnodes is faulty. - _ = new NodeSourceToDiscV4Feeder(enrDiscovery, _api.DiscoveryApp, 50).Run(_api.ProcessExit!.Token); + builder + .Bind() + .Bind() + .Bind() + .Bind(); } - CompositeNodeSource nodeSources = _networkConfig.OnlyStaticPeers - ? new(_api.StaticNodesManager, nodesLoader) - : new(_api.StaticNodesManager, nodesLoader, enrDiscovery, _api.DiscoveryApp); - _api.PeerPool = new PeerPool(nodeSources, _api.NodeStatsManager, peerStorage, _networkConfig, _api.LogManager); - _api.PeerManager = new PeerManager( - _api.RlpxPeer, - _api.PeerPool, - _api.NodeStatsManager, - _networkConfig, - _api.LogManager); + builder + .RegisterComposite(); - foreach (INethermindPlugin plugin in _api.Plugins) - { - await plugin.InitNetworkProtocol(); - } + builder + .AddSingleton() + .AddSingleton() + .AddSingleton(); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNodeStats.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNodeStats.cs deleted file mode 100644 index ddf6d80d99f..00000000000 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNodeStats.cs +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System.Threading; -using System.Threading.Tasks; -using Nethermind.Api; -using Nethermind.Network.Config; -using Nethermind.Stats; - -namespace Nethermind.Init.Steps -{ - [RunnerStepDependencies] - public class InitializeNodeStats : IStep - { - private readonly IApiWithNetwork _api; - - public InitializeNodeStats(INethermindApi api) - { - _api = api; - } - - public Task Execute(CancellationToken _) - { - INetworkConfig config = _api.Config(); - - // create shared objects between discovery and peer manager - NodeStatsManager nodeStatsManager = new(_api.TimerFactory, _api.LogManager, config.MaxCandidatePeerCount); - _api.NodeStatsManager = nodeStatsManager; - _api.DisposeStack.Push(nodeStatsManager); - - return Task.CompletedTask; - } - - public bool MustInitialize => false; - } -} diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index d93e6c8a649..ed3a3277cce 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Autofac; using FluentAssertions; using Nethermind.Api; using Nethermind.Blockchain.Synchronization; @@ -12,9 +13,11 @@ using Nethermind.Core; using Nethermind.Core.Exceptions; using Nethermind.Db; +using Nethermind.Init.Steps; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Network.Config; using Nethermind.Specs.ChainSpecStyle; using NUnit.Framework; using NSubstitute; @@ -36,7 +39,7 @@ public void Setup() BlocksConfig? miningConfig = new(); IJsonRpcConfig jsonRpcConfig = new JsonRpcConfig() { Enabled = true, EnabledModules = [ModuleType.Engine] }; - _context = Build.ContextWithMocks(); + _context = Build.ContextWithoutContainer(); _context.SealEngineType = SealEngineType.Clique; _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); @@ -68,6 +71,14 @@ public void Setup() _consensusPlugin = new(); } + private ContainerBuilder CreateContainerBuilder() + { + ContainerBuilder builder = new ContainerBuilder(); + ((IApiWithNetwork)_context).ConfigureContainerBuilderFromApiWithNetwork(builder); + builder.RegisterModule(new NetworkModule(new NetworkConfig(), new SyncConfig())); + return builder; + } + [TearDown] public void TearDown() => _plugin.DisposeAsync().GetAwaiter().GetResult(); @@ -95,7 +106,12 @@ public void Init_merge_plugin_does_not_throw_exception(bool enabled) Assert.DoesNotThrowAsync(async () => await _consensusPlugin!.Init(_context)); Assert.DoesNotThrowAsync(async () => await _plugin.Init(_context)); Assert.DoesNotThrowAsync(async () => await _plugin.InitNetworkProtocol()); - Assert.DoesNotThrowAsync(async () => await _plugin.InitSynchronization()); + + ContainerBuilder builder = CreateContainerBuilder(); + _plugin.ConfigureSynchronizationBuilder(builder); + IContainer container = builder.Build(); + + Assert.DoesNotThrowAsync(async () => await _plugin.InitSynchronization(container)); Assert.DoesNotThrow(() => _plugin.InitBlockProducer(_consensusPlugin!, null)); Assert.DoesNotThrowAsync(async () => await _plugin.InitRpcModules()); Assert.DoesNotThrowAsync(async () => await _plugin.DisposeAsync()); @@ -106,7 +122,12 @@ public async Task Initializes_correctly() { Assert.DoesNotThrowAsync(async () => await _consensusPlugin!.Init(_context)); await _plugin.Init(_context); - await _plugin.InitSynchronization(); + + ContainerBuilder builder = CreateContainerBuilder(); + _plugin.ConfigureSynchronizationBuilder(builder); + IContainer container = builder.Build(); + + await _plugin.InitSynchronization(container); await _plugin.InitNetworkProtocol(); ISyncConfig syncConfig = _context.Config(); Assert.That(syncConfig.NetworkingEnabled, Is.True); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 81b83425ace..8183f3c99e7 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -9,6 +9,7 @@ using Autofac; using Autofac.Core; using Autofac.Extensions.DependencyInjection; +using Autofac.Features.AttributeFilters; using Microsoft.Extensions.DependencyInjection; using Nethermind.Api; using Nethermind.Api.Extensions; @@ -389,7 +390,21 @@ protected virtual void RegisterEngineRpcModule(IEngineRpcModule engineRpcModule) _api.RpcModuleProvider.RegisterSingle(engineRpcModule); } - public Task InitSynchronization() + public void ConfigureSynchronizationBuilder(ContainerBuilder builder) + { + if (!MergeEnabled) return; + + builder + .AddSingleton(_poSSwitcher) + .AddSingleton(_blockCacheService) + .AddSingleton(_mergeConfig) + .AddSingleton(_invalidChainTracker); + + builder + .RegisterModule(new MergeNetworkModule()); + } + + public Task InitSynchronization(IContainer container) { if (MergeEnabled) { @@ -408,11 +423,6 @@ public Task InitSynchronization() if (_api.StateReader is null) throw new ArgumentNullException(nameof(_api.StateReader)); // ToDo strange place for validators initialization - PeerRefresher peerRefresher = new(_api.PeerDifficultyRefreshPool, _api.TimerFactory, _api.LogManager); - _peerRefresher = peerRefresher; - _api.DisposeStack.Push(peerRefresher); - _beaconPivot = new BeaconPivot(_syncConfig, _api.DbProvider.MetadataDb, _api.BlockTree, _api.PoSSwitcher, _api.LogManager); - MergeHeaderValidator headerValidator = new( _poSSwitcher, _api.HeaderValidator, @@ -436,36 +446,11 @@ public Task InitSynchronization() _api.LogManager), _invalidChainTracker, _api.LogManager); - _beaconSync = new BeaconSync(_beaconPivot, _api.BlockTree, _syncConfig, _blockCacheService, _poSSwitcher, _api.LogManager); - - _api.BetterPeerStrategy = new MergeBetterPeerStrategy(_api.BetterPeerStrategy, _poSSwitcher, _beaconPivot, _api.LogManager); - - _api.Pivot = _beaconPivot; - - ContainerBuilder builder = new ContainerBuilder(); - - _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, - _api.SyncModeSelector, - _api.SyncPeerPool, - _syncConfig, - _blockCacheService, - _beaconSync, - _api.DbProvider.MetadataDb, - _api.LogManager); + _peerRefresher = container.Resolve(); + _beaconPivot = container.Resolve(); + _beaconSync = container.Resolve(); + container.Resolve(); } return Task.CompletedTask; @@ -475,3 +460,28 @@ public Task InitSynchronization() public bool MustInitialize { get => true; } } + +public class MergeNetworkModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + builder + .AddSingleton() + .AddSingleton() + .AddSingleton(); + + builder + .RegisterType() + .As() + .As() + .WithAttributeFiltering() + .SingleInstance(); + + builder + .RegisterDecorator(); + + builder + .RegisterModule(new MergeSynchronizerModule()); + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs index dbbb4eeb778..2cab05a9beb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/BeaconPivot.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.Consensus; @@ -45,7 +46,7 @@ private BlockHeader? CurrentBeaconPivot public BeaconPivot( ISyncConfig syncConfig, - IDb metadataDb, + [KeyFilter(DbNames.Metadata)] IDb metadataDb, IBlockTree blockTree, IPoSSwitcher poSSwitcher, ILogManager logManager) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PivotUpdator.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PivotUpdator.cs index d4f874d75fb..63f5aef3101 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PivotUpdator.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PivotUpdator.cs @@ -4,6 +4,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Autofac.Features.AttributeFilters; using Nethermind.Blockchain; using Nethermind.Blockchain.Synchronization; using Nethermind.Consensus.Validators; @@ -44,7 +45,7 @@ public PivotUpdator(IBlockTree blockTree, ISyncConfig syncConfig, IBlockCacheService blockCacheService, IBeaconSyncStrategy beaconSyncStrategy, - IDb metadataDb, + [KeyFilter(DbNames.Metadata)] IDb metadataDb, ILogManager logManager) { _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); diff --git a/src/Nethermind/Nethermind.Network/Config/INetworkConfig.cs b/src/Nethermind/Nethermind.Network.Contract/Config/INetworkConfig.cs similarity index 100% rename from src/Nethermind/Nethermind.Network/Config/INetworkConfig.cs rename to src/Nethermind/Nethermind.Network.Contract/Config/INetworkConfig.cs diff --git a/src/Nethermind/Nethermind.Network/Config/NetworkConfig.cs b/src/Nethermind/Nethermind.Network.Contract/Config/NetworkConfig.cs similarity index 100% rename from src/Nethermind/Nethermind.Network/Config/NetworkConfig.cs rename to src/Nethermind/Nethermind.Network.Contract/Config/NetworkConfig.cs diff --git a/src/Nethermind/Nethermind.Network.Contract/Nethermind.Network.Contract.csproj b/src/Nethermind/Nethermind.Network.Contract/Nethermind.Network.Contract.csproj index e8a4d7f0d10..8bd6fa5f4ce 100644 --- a/src/Nethermind/Nethermind.Network.Contract/Nethermind.Network.Contract.csproj +++ b/src/Nethermind/Nethermind.Network.Contract/Nethermind.Network.Contract.csproj @@ -3,4 +3,7 @@ annotations + + + diff --git a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs index 149284c8a6b..abd4afb1b9c 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs @@ -291,6 +291,9 @@ static int[] GetDistances(byte[] srcNodeId, byte[] destNodeId) await Task.WhenAll(discoverTasks); } + catch (OperationCanceledException) + { + } catch (Exception ex) { if (_logger.IsError) _logger.Error($"Discovery via custom random walk failed.", ex); diff --git a/src/Nethermind/Nethermind.Network.Discovery/NodeSourceToDiscV4Feeder.cs b/src/Nethermind/Nethermind.Network.Discovery/NodeSourceToDiscV4Feeder.cs index ba13003b0e0..fccba8d30da 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/NodeSourceToDiscV4Feeder.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/NodeSourceToDiscV4Feeder.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Stats.Model; +using Autofac.Features.AttributeFilters; namespace Nethermind.Network.Discovery; @@ -11,6 +12,11 @@ public class NodeSourceToDiscV4Feeder private readonly IDiscoveryApp _discoveryApp; private readonly int _maxNodes; + public NodeSourceToDiscV4Feeder([KeyFilter(INodeSource.EnrSource)] INodeSource nodeSource, IDiscoveryApp discoveryApp) + : this(nodeSource, discoveryApp, 50) + { + } + public NodeSourceToDiscV4Feeder(INodeSource nodeSource, IDiscoveryApp discoveryApp, int maxNodes) { _nodeSource = nodeSource; diff --git a/src/Nethermind/Nethermind.Network/ForkInfo.cs b/src/Nethermind/Nethermind.Network/ForkInfo.cs index 6bf1941e7f0..08e27c6b427 100644 --- a/src/Nethermind/Nethermind.Network/ForkInfo.cs +++ b/src/Nethermind/Nethermind.Network/ForkInfo.cs @@ -12,6 +12,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Specs; +using Nethermind.Synchronization; namespace Nethermind.Network { @@ -21,6 +22,11 @@ public class ForkInfo private (ForkActivation Activation, ForkId Id)[] Forks { get; } private readonly bool _hasTimestampFork; + public ForkInfo(ISpecProvider specProvider, ISyncServer syncServer) + : this(specProvider, syncServer.Genesis.Hash!) + { + } + public ForkInfo(ISpecProvider specProvider, Hash256 genesisHash) { _hasTimestampFork = specProvider.TimestampFork != ISpecProvider.TimestampForkNever; diff --git a/src/Nethermind/Nethermind.Network/INodeSource.cs b/src/Nethermind/Nethermind.Network/INodeSource.cs index 4270bbc40e8..ad9d46677a5 100644 --- a/src/Nethermind/Nethermind.Network/INodeSource.cs +++ b/src/Nethermind/Nethermind.Network/INodeSource.cs @@ -12,4 +12,6 @@ public interface INodeSource { IAsyncEnumerable DiscoverNodes(CancellationToken cancellationToken); event EventHandler NodeRemoved; + + public const string EnrSource = nameof(EnrSource); } diff --git a/src/Nethermind/Nethermind.Network/NetworkStorage.cs b/src/Nethermind/Nethermind.Network/NetworkStorage.cs index 166c2d38206..d78170e2cbb 100644 --- a/src/Nethermind/Nethermind.Network/NetworkStorage.cs +++ b/src/Nethermind/Nethermind.Network/NetworkStorage.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Text; - +using Autofac.Features.AttributeFilters; using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Crypto; @@ -25,7 +25,7 @@ public class NetworkStorage : INetworkStorage private long _removeCounter; private NetworkNode[]? _nodes; - public NetworkStorage(IFullDb? fullDb, ILogManager? logManager) + public NetworkStorage([KeyFilter(nameof(NetworkStorage))] IFullDb? fullDb, ILogManager? logManager) { _fullDb = fullDb ?? throw new ArgumentNullException(nameof(fullDb)); _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs index 171e83e89c7..ea3751af6e5 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapProtocolHandler.cs @@ -21,6 +21,7 @@ using Nethermind.State.Snap; using Nethermind.Stats; using Nethermind.Stats.Model; +using Nethermind.Synchronization; using Nethermind.Synchronization.SnapSync; namespace Nethermind.Network.P2P.Subprotocols.Snap @@ -71,7 +72,7 @@ public SnapProtocolHandler(ISession session, _getTrieNodesRequests = new(Send); SyncServer = snapServer; BackgroundTaskScheduler = new BackgroundTaskSchedulerWrapper(this, backgroundTaskScheduler); - ServingEnabled = SyncServer is not null; + ServingEnabled = SyncServer is not null && SyncServer.IsEnabled; } public override event EventHandler? ProtocolInitialized; diff --git a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs index f1657f241a2..fe7a046c3a9 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs @@ -29,6 +29,17 @@ public class HandshakeService : IHandshakeService private readonly ILogger _logger; private readonly IEcdsa _ecdsa; + public HandshakeService( + IMessageSerializationService messageSerializationService, + IEciesCipher eciesCipher, + ICryptoRandom cryptoRandom, + IEcdsa ecdsa, + ProtectedPrivateKey privateKey, + ILogManager logManager) + : this(messageSerializationService, eciesCipher, cryptoRandom, ecdsa, privateKey.Unprotect(), logManager) + { + } + public HandshakeService( IMessageSerializationService messageSerializationService, IEciesCipher eciesCipher, diff --git a/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs b/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs index 7917c84cd84..7292f7952ab 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs @@ -13,6 +13,7 @@ using DotNetty.Transport.Channels.Sockets; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; +using Nethermind.Crypto; using Nethermind.Logging; using Nethermind.Network.Config; using Nethermind.Network.P2P; @@ -44,6 +45,20 @@ public class RlpxHost : IRlpxHost private readonly TimeSpan _sendLatency; private readonly TimeSpan _connectTimeout; + public RlpxHost( + IMessageSerializationService serializationService, + ProtectedPrivateKey nodeKey, + INetworkConfig networkConfig, + IHandshakeService handshakeService, + ISessionMonitor sessionMonitor, + IDisconnectsAnalyzer disconnectsAnalyzer, + ILogManager logManager + ) : this(serializationService, nodeKey.PublicKey, networkConfig.ProcessingThreadCount, networkConfig.P2PPort, + networkConfig.LocalIp, networkConfig.ConnectTimeoutMs, handshakeService, sessionMonitor, disconnectsAnalyzer, + logManager, TimeSpan.FromMilliseconds(networkConfig.SimulateSendLatencyMs)) + { + } + public RlpxHost(IMessageSerializationService serializationService, PublicKey localNodeId, int networkProcessingThread, diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 76633fbf876..dd4aadcb79c 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -26,6 +26,7 @@ using Nethermind.Core; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.HealthChecks; +using Nethermind.Network; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Serialization.Rlp; @@ -125,7 +126,32 @@ public Task Init(INethermindApi api) return Task.CompletedTask; } - public Task InitSynchronization() + public void ConfigureSynchronizationBuilder(ContainerBuilder builder) + { + if (_api is null || !ShouldRunSteps(_api)) + return; + + builder + .AddSingleton(_blockCacheService!) + .AddSingleton(_mergeConfig) + .AddSingleton(_invalidChainTracker!) + .AddSingleton() + .AddSingleton() + .AddSingleton(); + + builder + .RegisterType() + .As() + .As() + .SingleInstance(); + + builder + .RegisterDecorator(); + + builder.RegisterModule(new MergeSynchronizerModule()); + } + + public Task InitSynchronization(IContainer container) { if (_api is null || !ShouldRunSteps(_api)) return Task.CompletedTask; @@ -144,39 +170,10 @@ public Task InitSynchronization() _invalidChainTracker.SetupBlockchainProcessorInterceptor(_api.BlockchainProcessor); - _peerRefresher = new PeerRefresher(_api.PeerDifficultyRefreshPool, _api.TimerFactory, _api.LogManager); - _api.DisposeStack.Push((PeerRefresher)_peerRefresher); - - _beaconPivot = new BeaconPivot(_syncConfig, _api.DbProvider.MetadataDb, _api.BlockTree, _api.PoSSwitcher, _api.LogManager); - _beaconSync = new BeaconSync(_beaconPivot, _api.BlockTree, _syncConfig, _blockCacheService, _api.PoSSwitcher, _api.LogManager); - _api.BetterPeerStrategy = new MergeBetterPeerStrategy(_api.BetterPeerStrategy, _api.PoSSwitcher, _beaconPivot, _api.LogManager); - _api.Pivot = _beaconPivot; - - ContainerBuilder builder = new ContainerBuilder(); - ((INethermindApi)_api).ConfigureContainerBuilderFromApiWithNetwork(builder) - .AddSingleton(_beaconSync) - .AddSingleton(_beaconPivot) - .AddSingleton(_api.PoSSwitcher) - .AddSingleton(_mergeConfig) - .AddSingleton(_invalidChainTracker); - - 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.SyncModeSelector, - _api.SyncPeerPool, - _syncConfig, - _blockCacheService, - _beaconSync, - _api.DbProvider.MetadataDb, - _api.LogManager); + _peerRefresher = container.Resolve(); + _beaconPivot = container.Resolve(); + _beaconSync = container.Resolve(); + _ = container.Resolve(); return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 9b0a4f49d77..5bc661b44ab 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System.IO; using System.IO.Abstractions; using Autofac; using Nethermind.Api; @@ -43,30 +44,33 @@ using Nethermind.Wallet; using Nethermind.Sockets; using Nethermind.Specs; -using Nethermind.Synchronization.SnapSync; using Nethermind.Trie; using NSubstitute; using Nethermind.Blockchain.Blocks; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Consensus.Scheduler; using Nethermind.Core; using Nethermind.Facade.Find; +using Nethermind.Core.Test.Builders; +using Nethermind.Init.Steps; +using Nethermind.Network.Config; +using Nethermind.Network.P2P.Analyzers; namespace Nethermind.Runner.Test.Ethereum { public static class Build { - public static NethermindApi ContextWithMocks() + public static NethermindApi ContextWithoutContainer() { var api = new NethermindApi(Substitute.For(), Substitute.For(), LimboLogs.Instance, new ChainSpec()) { + NodeKey = new ProtectedPrivateKey(TestItem.PrivateKeyA, Path.GetTempPath()), Enode = Substitute.For(), TxPool = Substitute.For(), Wallet = Substitute.For(), BlockTree = Substitute.For(), - SyncServer = Substitute.For(), DbProvider = TestMemDbProvider.Init(), - PeerManager = Substitute.For(), - PeerPool = Substitute.For(), SpecProvider = Substitute.For(), EthereumEcdsa = Substitute.For(), MainBlockProcessor = Substitute.For(), @@ -75,12 +79,10 @@ public static NethermindApi ContextWithMocks() BlockValidator = Substitute.For(), RewardCalculatorSource = Substitute.For(), TxPoolInfoProvider = Substitute.For(), - StaticNodesManager = Substitute.For(), BloomStorage = Substitute.For(), Sealer = Substitute.For(), BlockchainProcessor = Substitute.For(), BlockProducer = Substitute.For(), - DiscoveryApp = Substitute.For(), EngineSigner = Substitute.For(), FileSystem = Substitute.For(), FilterManager = Substitute.For(), @@ -91,40 +93,45 @@ public static NethermindApi ContextWithMocks() KeyStore = Substitute.For(), LogFinder = Substitute.For(), MonitoringService = Substitute.For(), - ProtocolsManager = Substitute.For(), - ProtocolValidator = Substitute.For(), - RlpxPeer = Substitute.For(), SealValidator = Substitute.For(), - SessionMonitor = Substitute.For(), WorldState = Substitute.For(), StateReader = Substitute.For(), TransactionProcessor = Substitute.For(), TxSender = Substitute.For(), BlockProcessingQueue = Substitute.For(), EngineSignerStore = Substitute.For(), - NodeStatsManager = Substitute.For(), RpcModuleProvider = Substitute.For(), - SyncPeerPool = Substitute.For(), - PeerDifficultyRefreshPool = Substitute.For(), WebSocketsManager = Substitute.For(), ChainLevelInfoRepository = Substitute.For(), TrieStore = Substitute.For(), BlockProducerEnvFactory = Substitute.For(), TransactionComparerProvider = Substitute.For(), GasPriceOracle = Substitute.For(), - EthSyncingInfo = Substitute.For(), HealthHintService = Substitute.For(), TxValidator = new TxValidator(MainnetSpecProvider.Instance.ChainId), UnclesValidator = Substitute.For(), BlockProductionPolicy = Substitute.For(), - BetterPeerStrategy = Substitute.For(), ReceiptMonitor = Substitute.For(), BadBlocksStore = Substitute.For(), + BackgroundTaskScheduler = Substitute.For(), ApiWithNetworkServiceContainer = new ContainerBuilder() + .AddSingleton(Substitute.For()) .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) .Build(), }; @@ -132,5 +139,41 @@ public static NethermindApi ContextWithMocks() api.NodeStorageFactory = new NodeStorageFactory(INodeStorage.KeyScheme.HalfPath, LimboLogs.Instance); return api; } + + public static NethermindApi ContextWithMocks() + { + NethermindApi api = ContextWithoutContainer(); + api.ApiWithNetworkServiceContainer = new ContainerBuilder() + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .AddSingleton(Substitute.For()) + .Build(); + + return api; + } + + public static NethermindApi ContextWithMocksWithTestContainer() + { + NethermindApi api = ContextWithoutContainer(); + + var builder = new ContainerBuilder(); + ((IApiWithNetwork)api).ConfigureContainerBuilderFromApiWithNetwork(builder); + builder.RegisterModule(new NetworkModule(new NetworkConfig(), new SyncConfig())); + api.ApiWithNetworkServiceContainer = builder.Build(); + + return api; + } } } diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index 89bd50a3ca4..e6ded153433 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -2,9 +2,13 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Autofac; +using Autofac.Core; +using Autofac.Core.Registration; +using Autofac.Diagnostics; using Autofac.Extensions.DependencyInjection; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; @@ -22,7 +26,9 @@ using Nethermind.Core.Test.Builders; using Nethermind.Core.Timers; using Nethermind.Db; +using Nethermind.Init.Steps; using Nethermind.Logging; +using Nethermind.Network.Config; using Nethermind.Specs; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; @@ -55,58 +61,37 @@ public async Task Setup() _stateDb = dbProvider.StateDb; _codeDb = dbProvider.CodeDb; _receiptStorage = Substitute.For(); - SyncConfig quickConfig = new() { FastSync = false }; - ITimerFactory timerFactory = Substitute.For(); - NodeStatsManager stats = new(timerFactory, LimboLogs.Instance); - _pool = new SyncPeerPool(_blockTree, stats, new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance), LimboLogs.Instance, 25); - SyncConfig syncConfig = new(); + SyncConfig syncConfig = new() { FastSync = false }; NodeStorage nodeStorage = new NodeStorage(_stateDb); TrieStore trieStore = new(nodeStorage, LimboLogs.Instance); - TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance); - Pivot pivot = new(syncConfig); IStateReader stateReader = new StateReader(trieStore, _codeDb, LimboLogs.Instance); ContainerBuilder builder = new ContainerBuilder() .AddSingleton(nodeStorage) .AddSingleton(MainnetSpecProvider.Instance) + .AddSingleton(Substitute.For()) + .AddSingleton(new NetworkConfig()) .AddSingleton(_blockTree) .AddSingleton(_receiptStorage) - .AddSingleton(_pool) - .AddSingleton(stats) + .AddSingleton(_receiptStorage) .AddSingleton(syncConfig) .AddSingleton(Always.Valid) .AddSingleton(Always.Valid) - .AddSingleton(pivot) .AddSingleton(Substitute.For()) - .AddSingleton(bestPeerStrategy) .AddSingleton(new ChainSpec()) .AddSingleton(stateReader) - .AddSingleton(No.BeaconSync) + .AddSingleton(Policy.FullGossip) .AddSingleton(LimboLogs.Instance); dbProvider.ConfigureServiceCollection(builder); - - builder.RegisterModule(new SynchronizerModule(syncConfig)); - + builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); - _synchronizer = container.Resolve(); - - _syncServer = new SyncServer( - trieStore.TrieNodeRlpStore, - _codeDb, - _blockTree, - _receiptStorage, - Always.Valid, - Always.Valid, - _pool, - container.Resolve(), - quickConfig, - Policy.FullGossip, - MainnetSpecProvider.Instance, - LimboLogs.Instance); + _pool = container.Resolve(); + _synchronizer = container.Resolve(); + _syncServer = container.Resolve(); } [TearDown] @@ -155,6 +140,7 @@ public void Syncs_with_empty_peer() _remoteBlockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(1).TestObject; ISyncPeer peer = new SyncPeerMock(_remoteBlockTree); + Stopwatch sw = Stopwatch.StartNew(); _pool.Start(); _synchronizer.Start(); _pool.AddPeer(peer); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 33e43446a69..8e645cee8b4 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -6,8 +6,6 @@ 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; @@ -34,18 +32,16 @@ using Nethermind.State; using Nethermind.Stats; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Synchronization.Blocks; -using Nethermind.Synchronization.ParallelSync; using Nethermind.Synchronization.Peers; -using Nethermind.Synchronization.Reporting; using Nethermind.Trie.Pruning; using Nethermind.TxPool; using NSubstitute; using NUnit.Framework; using BlockTree = Nethermind.Blockchain.BlockTree; -using Nethermind.Synchronization.SnapSync; using Nethermind.Config; using Nethermind.Core.Specs; +using Nethermind.Init.Steps; +using Nethermind.Network.Config; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Trie; @@ -315,10 +311,6 @@ private SyncTestContext CreateSyncManager(int index) BlockchainProcessor processor = new(tree, blockProcessor, step, stateReader, logManager, BlockchainProcessor.Options.Default); - ITimerFactory timerFactory = Substitute.For(); - NodeStatsManager nodeStatsManager = new(timerFactory, logManager); - SyncPeerPool syncPeerPool = new(tree, nodeStatsManager, new TotalDifficultyBetterPeerStrategy(LimboLogs.Instance), logManager, 25); - WorldState devState = new(trieStore, codeDb, logManager); VirtualMachine devEvm = new(blockhashProvider, specProvider, codeInfoRepository, logManager); TransactionProcessor devTxProcessor = new(specProvider, devState, devEvm, codeInfoRepository, logManager); @@ -358,49 +350,31 @@ private SyncTestContext CreateSyncManager(int index) tree, producer); - TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance); - Pivot pivot = new(syncConfig); - ContainerBuilder builder = new ContainerBuilder(); builder .AddSingleton(dbProvider) + .AddSingleton(Substitute.For()) + .AddSingleton(new NetworkConfig()) .AddSingleton(new NodeStorage(dbProvider.StateDb)) .AddSingleton(MainnetSpecProvider.Instance) .AddSingleton(tree) - .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(syncPeerPool) - .AddSingleton(nodeStatsManager) + .AddSingleton(NullReceiptStorage.Instance) + .AddSingleton(NullReceiptStorage.Instance) .AddSingleton(syncConfig) .AddSingleton(blockValidator) .AddSingleton(sealValidator) - .AddSingleton(pivot) .AddSingleton(Substitute.For()) - .AddSingleton(bestPeerStrategy) .AddSingleton(new ChainSpec()) + .AddSingleton(Policy.FullGossip) .AddSingleton(stateReader) .AddSingleton(receiptStorage) - .AddSingleton(No.BeaconSync) .AddSingleton(logManager); dbProvider.ConfigureServiceCollection(builder); - builder.RegisterModule(new SynchronizerModule(syncConfig)); + builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); - - Synchronizer synchronizer = container.Resolve(); - - ISyncModeSelector selector = synchronizer.SyncModeSelector; - SyncServer syncServer = new( - trieStore.TrieNodeRlpStore, - codeDb, - tree, - receiptStorage, - Always.Valid, - Always.Valid, - syncPeerPool, - selector, - syncConfig, - Policy.FullGossip, - MainnetSpecProvider.Instance, - logManager); + ISynchronizer synchronizer = container.Resolve(); + ISyncPeerPool syncPeerPool = container.Resolve(); + ISyncServer syncServer = container.Resolve(); ManualResetEventSlim waitEvent = new(); tree.NewHeadBlock += (_, _) => waitEvent.Set(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index 47c721d274c..659a4b36275 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -9,8 +9,6 @@ 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; @@ -24,6 +22,7 @@ using Nethermind.Core.Test.Builders; using Nethermind.Core.Timers; using Nethermind.Db; +using Nethermind.Init.Steps; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs; @@ -31,13 +30,13 @@ using Nethermind.Stats; using Nethermind.Stats.Model; using Nethermind.Merge.Plugin; +using Nethermind.Merge.Plugin.Handlers; using Nethermind.Merge.Plugin.InvalidChainTracker; -using Nethermind.Merge.Plugin.Synchronization; using Nethermind.Merge.Plugin.Test; +using Nethermind.Network.Config; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; using Nethermind.Synchronization.Blocks; -using Nethermind.Synchronization.ParallelSync; using Nethermind.Synchronization.Peers; using Nethermind.Trie.Pruning; using NSubstitute; @@ -319,29 +318,17 @@ ISyncConfig GetSyncConfig() => .WithoutSettingHead .TestObject; - ITimerFactory timerFactory = Substitute.For(); - NodeStatsManager stats = new(timerFactory, _logManager); - MergeConfig mergeConfig = new(); if (WithTTD(synchronizerType)) { mergeConfig.TerminalTotalDifficulty = UInt256.MaxValue.ToString(CultureInfo.InvariantCulture); } PoSSwitcher poSSwitcher = new(mergeConfig, syncConfig, dbProvider.MetadataDb, BlockTree, new TestSingleReleaseSpecProvider(Constantinople.Instance), new ChainSpec(), _logManager); - IBeaconPivot beaconPivot = new BeaconPivot(syncConfig, dbProvider.MetadataDb, BlockTree, poSSwitcher, _logManager); - TrieStore trieStore = new(stateDb, LimboLogs.Instance); - TotalDifficultyBetterPeerStrategy totalDifficultyBetterPeerStrategy = new(LimboLogs.Instance); - IBetterPeerStrategy bestPeerStrategy = IsMerge(synchronizerType) - ? new MergeBetterPeerStrategy(totalDifficultyBetterPeerStrategy, poSSwitcher, beaconPivot, LimboLogs.Instance) - : totalDifficultyBetterPeerStrategy; StateReader reader = new StateReader(trieStore, codeDb, LimboLogs.Instance); 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(); @@ -350,48 +337,36 @@ ISyncConfig GetSyncConfig() => builder .AddSingleton(dbProvider) .AddSingleton(nodeStorage) + .AddSingleton(new NetworkConfig()) + .AddSingleton(Substitute.For()) .AddSingleton(MainnetSpecProvider.Instance) .AddSingleton(BlockTree) .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(SyncPeerPool) - .AddSingleton(stats) + .AddSingleton(NullReceiptStorage.Instance) .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(Policy.FullGossip) + .AddSingleton(new BlockCacheService()) .AddSingleton(_logManager); - builder.RegisterModule(new SynchronizerModule(syncConfig)); + builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); if (IsMerge(synchronizerType)) { - builder.RegisterModule(new MergeSynchronizerModule()); + builder.RegisterModule(new MergeNetworkModule()); } IContainer container = builder.Build(); - Synchronizer = container.Resolve(); - SyncServer = new SyncServer( - trieStore.TrieNodeRlpStore, - codeDb, - BlockTree, - NullReceiptStorage.Instance, - Always.Valid, - Always.Valid, - SyncPeerPool, - container.Resolve(), - syncConfig, - Policy.FullGossip, - MainnetSpecProvider.Instance, - _logManager); + Synchronizer = container.Resolve(); + SyncPeerPool = container.Resolve(); + SyncServer = container.Resolve(); SyncPeerPool.Start(); diff --git a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs index 2bee35f4e76..13f2a2289c9 100644 --- a/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs +++ b/src/Nethermind/Nethermind.Synchronization/Peers/SyncPeerPool.cs @@ -17,6 +17,7 @@ using Nethermind.Core.Extensions; using Nethermind.Int256; using Nethermind.Logging; +using Nethermind.Network.Config; using Nethermind.Stats; using Nethermind.Stats.Model; using Nethermind.Synchronization.Peers.AllocationStrategies; @@ -59,6 +60,15 @@ public class SyncPeerPool : ISyncPeerPool, IPeerDifficultyRefreshPool private readonly TimeSpan _timeBeforeWakingShallowSleepingPeerUp = TimeSpan.FromMilliseconds(DefaultUpgradeIntervalInMs); private Timer? _upgradeTimer; + public SyncPeerPool(IBlockTree blockTree, + INodeStatsManager nodeStatsManager, + IBetterPeerStrategy betterPeerStrategy, + INetworkConfig networkConfig, + ILogManager logManager) + : this(blockTree, nodeStatsManager, betterPeerStrategy, logManager, networkConfig.ActivePeersMaxCount, networkConfig.PriorityPeersMaxCount) + { + } + public SyncPeerPool(IBlockTree blockTree, INodeStatsManager nodeStatsManager, IBetterPeerStrategy betterPeerStrategy, diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/ISnapServer.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/ISnapServer.cs index b4171153a40..5834b478c1a 100644 --- a/src/Nethermind/Nethermind.Synchronization/SnapSync/ISnapServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/ISnapServer.cs @@ -25,6 +25,8 @@ namespace Nethermind.Synchronization.SnapSync; public interface ISnapServer { + bool IsEnabled { get; } + IOwnedReadOnlyList? GetTrieNodes(IReadOnlyList pathSet, in ValueHash256 rootHash, CancellationToken cancellationToken); IOwnedReadOnlyList GetByteCodes(IReadOnlyList requestedHashes, long byteLimit, CancellationToken cancellationToken); diff --git a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapServer.cs b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapServer.cs index e18b9e1e36e..672a24bc530 100644 --- a/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SnapSync/SnapServer.cs @@ -17,13 +17,16 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; +using Autofac.Features.AttributeFilters; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Utils; using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; +using Nethermind.Db; using Nethermind.Logging; using Nethermind.Serialization.Rlp; using Nethermind.State; @@ -52,6 +55,15 @@ public class SnapServer : ISnapServer private const long HardResponseByteLimit = 2000000; private const int HardResponseNodeLimit = 100000; + public bool IsEnabled { get; } = true; + + public SnapServer(ISyncConfig syncConfig, IReadOnlyTrieStore trieStore, [KeyFilter(DbNames.Code)] IReadOnlyKeyValueStore codeDb, + IBlockTree blockTree, ILogManager logManager) + : this(trieStore, codeDb, new LastNStateRootTracker(blockTree, 128), logManager) + { + IsEnabled = syncConfig.SnapServingEnabled == true; + } + public SnapServer(IReadOnlyTrieStore trieStore, IReadOnlyKeyValueStore codeDb, ILastNStateRootTracker stateRootTracker, ILogManager logManager) { _store = trieStore ?? throw new ArgumentNullException(nameof(trieStore)); diff --git a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs index 429f27af1be..78f898b6012 100644 --- a/src/Nethermind/Nethermind.Synchronization/SyncServer.cs +++ b/src/Nethermind/Nethermind.Synchronization/SyncServer.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Autofac.Features.AttributeFilters; using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; @@ -20,6 +21,7 @@ using Nethermind.Core.Collections; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Synchronization.FastSync; @@ -54,8 +56,8 @@ public class SyncServer : ISyncServer private BlockHeader? _pivotHeader; public SyncServer( - IReadOnlyKeyValueStore stateDb, - IReadOnlyKeyValueStore codeDb, + [KeyFilter(DbNames.State)] IReadOnlyKeyValueStore stateDb, + [KeyFilter(DbNames.Code)] IReadOnlyKeyValueStore codeDb, IBlockTree blockTree, IReceiptFinder receiptFinder, IBlockValidator blockValidator, diff --git a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs index 826406ca9de..68ef1ab1617 100644 --- a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs +++ b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Autofac; @@ -54,8 +55,6 @@ public class Synchronizer( /* sync events are used mainly for managing sync peers reputation */ public event EventHandler? SyncEvent; - public ISyncModeSelector SyncModeSelector => syncModeSelector; - public virtual void Start() { if (!syncConfig.SynchronizationEnabled) @@ -81,12 +80,12 @@ public virtual void Start() if (syncConfig.ExitOnSynced) { - exitSource.WatchForExit(SyncModeSelector, logManager, TimeSpan.FromSeconds(syncConfig.ExitOnSyncedWaitTimeSec)); + exitSource.WatchForExit(syncModeSelector, logManager, TimeSpan.FromSeconds(syncConfig.ExitOnSyncedWaitTimeSec)); } WireMultiSyncModeSelector(); - SyncModeSelector.Changed += syncReport.SyncModeSelectorOnChanged; + syncModeSelector.Changed += syncReport.SyncModeSelectorOnChanged; } private void StartFullSyncComponents() @@ -248,11 +247,11 @@ private void WireMultiSyncModeSelector() public void WireFeedWithModeSelector(ISyncFeed? feed) { if (feed is null) return; - SyncModeSelector.Changed += ((sender, args) => + syncModeSelector.Changed += ((sender, args) => { feed?.SyncModeSelectorOnChanged(args.Current); }); - feed?.SyncModeSelectorOnChanged(SyncModeSelector.Current); + feed?.SyncModeSelectorOnChanged(syncModeSelector.Current); } public void Dispose() From dae8d74e14f78c15336f50d62bcb673f7315f9a0 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Mon, 30 Sep 2024 21:43:43 +0800 Subject: [PATCH 02/25] Fix build --- .../Nethermind.Init/Steps/InitializeNetwork.cs | 1 - .../Ethereum/ContextWithMocks.cs | 13 +++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 14bd322ee5e..d3988b11fa8 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -425,7 +425,6 @@ protected override void Load(ContainerBuilder builder) { IEthereumEcdsa ecdsa = ctx.Resolve(); ILogManager logManager = ctx.Resolve(); - INetworkConfig networkConfig = ctx.Resolve(); ChainSpec chainSpec = ctx.Resolve(); // I do not use the key here -> API is broken - no sense to use the node signer here diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 5bc661b44ab..1ed5e0a0e19 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -164,13 +164,22 @@ public static NethermindApi ContextWithMocks() return api; } - public static NethermindApi ContextWithMocksWithTestContainer() + public static NethermindApi ContextWithMocksWithTestContainer(INetworkConfig networkConfig = null, ISyncConfig syncConfig = null) { NethermindApi api = ContextWithoutContainer(); + if (networkConfig == null) + { + networkConfig = new NetworkConfig(); + } + if (syncConfig == null) + { + syncConfig = new SyncConfig(); + } + var builder = new ContainerBuilder(); ((IApiWithNetwork)api).ConfigureContainerBuilderFromApiWithNetwork(builder); - builder.RegisterModule(new NetworkModule(new NetworkConfig(), new SyncConfig())); + builder.RegisterModule(new NetworkModule(networkConfig, syncConfig)); api.ApiWithNetworkServiceContainer = builder.Build(); return api; From 8de5f2cb3e25f0ca76b78ee46575f03593407180 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Mon, 30 Sep 2024 22:12:33 +0800 Subject: [PATCH 03/25] Unnecessary code --- .../Ethereum/ContextWithMocks.cs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 1ed5e0a0e19..3ad5bf853b0 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -114,25 +114,6 @@ public static NethermindApi ContextWithoutContainer() ReceiptMonitor = Substitute.For(), BadBlocksStore = Substitute.For(), BackgroundTaskScheduler = Substitute.For(), - - ApiWithNetworkServiceContainer = new ContainerBuilder() - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .Build(), }; api.WorldStateManager = new ReadOnlyWorldStateManager(api.DbProvider, Substitute.For(), LimboLogs.Instance); From 2bff61f81849556e88d1544217dffd078ad44b57 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 02:51:18 +0800 Subject: [PATCH 04/25] Fix startup --- .../Nethermind.Init/Steps/InitializeNetwork.cs | 7 ------- .../CompositeDiscoveryApp.cs | 9 ++------- .../Nethermind.Network.Discovery/DiscoveryApp.cs | 4 +--- .../Discv5/DiscoveryV5App.cs | 2 -- src/Nethermind/Nethermind.Network/IDiscoveryApp.cs | 1 - 5 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index d3988b11fa8..9e50bd25150 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -135,7 +135,6 @@ private async Task Initialize(CancellationToken cancellationToken) IStaticNodesManager staticNodesManager = container.Resolve(); Func nodeSourceToDiscV4Feeder = container.Resolve>(); IProtocolsManager protocolsManager = container.Resolve(); - EnrDiscovery enrDiscover = container.Resolve(); SnapCapabilitySwitcher snapCapabilitySwitcher = container.Resolve(); ISyncPeerPool syncPeerPool = container.Resolve(); ISynchronizer synchronizer = container.Resolve(); @@ -152,7 +151,6 @@ private async Task Initialize(CancellationToken cancellationToken) healingWorldState.InitializeNetwork(container.Resolve()); } - InitDiscovery(discoveryApp); if (cancellationToken.IsCancellationRequested) { return; @@ -252,11 +250,6 @@ private void StartPeer(IPeerPool peerPool, IPeerManager peerManager, ISessionMon if (_logger.IsDebug) _logger.Debug("Peer manager initialization completed"); } - private void InitDiscovery(IDiscoveryApp discoveryApp) - { - discoveryApp.Initialize(_api.NodeKey!.PublicKey); - } - private Task StartSync(ISyncPeerPool syncPeerPool, ISynchronizer synchronizer) { ISyncConfig syncConfig = _api.Config(); diff --git a/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs b/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs index af7018c4a1a..f7013d14c6b 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs @@ -67,11 +67,8 @@ public CompositeDiscoveryApp(ProtectedPrivateKey? nodeKey, _nodeStatsManager = nodeStatsManager ?? throw new ArgumentNullException(nameof(nodeStatsManager)); _ipResolver = ipResolver ?? throw new ArgumentNullException(nameof(ipResolver)); _connections = new DiscoveryConnectionsPool(logManager.GetClassLogger(), _networkConfig, _discoveryConfig); - } - public void Initialize(PublicKey masterPublicKey) - { - var nodeKeyProvider = new SameKeyGenerator(_nodeKey.Unprotect()); + SameKeyGenerator nodeKeyProvider = new SameKeyGenerator(_nodeKey.Unprotect()); List allNodeSources = new(); if ((_discoveryConfig.DiscoveryVersion & DiscoveryVersion.V4) != 0) @@ -189,9 +186,8 @@ private void InitDiscoveryV4(IDiscoveryConfig discoveryConfig, SameKeyGenerator _networkConfig, discoveryConfig, _timestamper, + _nodeKey.PublicKey, _logManager); - - _v4.Initialize(_nodeKey.PublicKey); } private void InitDiscoveryV5(SameKeyGenerator privateKeyProvider) @@ -202,7 +198,6 @@ private void InitDiscoveryV5(SameKeyGenerator privateKeyProvider) _logManager); _v5 = new DiscoveryV5App(privateKeyProvider, _ipResolver, _networkConfig, _discoveryConfig, discv5DiscoveryDb, _logManager); - _v5.Initialize(_nodeKey.PublicKey); } private NodeRecord PrepareNodeRecord(SameKeyGenerator privateKeyProvider) diff --git a/src/Nethermind/Nethermind.Network.Discovery/DiscoveryApp.cs b/src/Nethermind/Nethermind.Network.Discovery/DiscoveryApp.cs index 0dbfb89798d..180b728781e 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/DiscoveryApp.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/DiscoveryApp.cs @@ -48,6 +48,7 @@ public DiscoveryApp(INodesLocator nodesLocator, INetworkConfig? networkConfig, IDiscoveryConfig? discoveryConfig, ITimestamper? timestamper, + PublicKey masterPublicKey, ILogManager? logManager) { _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); @@ -63,10 +64,7 @@ public DiscoveryApp(INodesLocator nodesLocator, _discoveryStorage = discoveryStorage ?? throw new ArgumentNullException(nameof(discoveryStorage)); _networkConfig = networkConfig ?? throw new ArgumentNullException(nameof(networkConfig)); _discoveryStorage.StartBatch(); - } - public void Initialize(PublicKey masterPublicKey) - { _discoveryManager.NodeDiscovered += OnNodeDiscovered; _nodeTable.Initialize(masterPublicKey); if (_nodeTable.MasterNode is null) diff --git a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs index abd4afb1b9c..a402924f759 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/Discv5/DiscoveryV5App.cs @@ -190,8 +190,6 @@ private bool TryGetNodeFromEnr(IEnr enr, [NotNullWhen(true)] out Node? node) public event EventHandler? NodeRemoved; - public void Initialize(PublicKey masterPublicKey) { } - public void InitializeChannel(IChannel channel) { var handler = _serviceProvider.GetRequiredService(); diff --git a/src/Nethermind/Nethermind.Network/IDiscoveryApp.cs b/src/Nethermind/Nethermind.Network/IDiscoveryApp.cs index 1e473ba424e..3d8cab8c00e 100644 --- a/src/Nethermind/Nethermind.Network/IDiscoveryApp.cs +++ b/src/Nethermind/Nethermind.Network/IDiscoveryApp.cs @@ -11,7 +11,6 @@ namespace Nethermind.Network { public interface IDiscoveryApp : INodeSource { - void Initialize(PublicKey masterPublicKey); void InitializeChannel(IChannel channel); Task StartAsync(); Task StopAsync(); From f38c7c9d1c0ee412be2ce0a040240260e9e73bae Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 12:18:51 +0800 Subject: [PATCH 05/25] Pluggable DI container --- .../Nethermind.Analytics/AnalyticsPlugin.cs | 24 ++- .../Nethermind.Api.Test/TestPlugin.cs | 2 + .../Nethermind.Api.Test/TestPlugin2.cs | 2 + .../Extensions/IConsensusPlugin.cs | 9 - .../Extensions/IInitializationPlugin.cs | 7 - .../Extensions/INethermindPlugin.cs | 4 + .../Nethermind.Api/IApiWithBlockchain.cs | 2 +- src/Nethermind/Nethermind.Api/IBasicApi.cs | 16 +- .../Nethermind.Api/NethermindApi.cs | 29 ++-- .../Nethermind.AuRa.Test/AuRaPluginTests.cs | 28 --- .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 23 ++- .../InitializationSteps/AuRaNethermindApi.cs | 4 +- .../CliquePlugin.cs | 5 +- .../EthashPlugin.cs | 5 +- .../NethDevPlugin.cs | 5 +- .../Blockchain/TestBlockchain.cs | 21 +++ .../Nethermind.Core.Test.csproj | 1 + .../ContainerBuilderExtensions.cs | 10 +- src/Nethermind/Nethermind.Db/IDbProvider.cs | 4 +- .../EthStatsPluginTests.cs | 4 +- .../Nethermind.EthStats/EthStatsPlugin.cs | 22 +-- .../ClefSignerPlugin.cs | 1 + .../NodeHealthServiceTests.cs | 4 +- .../HealthChecksPlugin.cs | 1 + src/Nethermind/Nethermind.Hive/HivePlugin.cs | 11 +- .../SnapshotPlugin.cs | 13 +- .../Steps/EthereumStepsLoader.cs | 70 ++------ .../Steps/EthereumStepsManager.cs | 27 ++- .../Steps/IEthereumRunnerStep.cs | 43 +++++ .../Steps/IEthereumStepsLoader.cs | 2 +- .../Steps/InitializeNetwork.cs | 2 +- .../TraceStorePlugin.cs | 27 ++- .../AuRaMergeEngineModuleTests.cs | 39 +++-- .../Nethermind.Merge.AuRa/AuRaMergePlugin.cs | 22 ++- .../MergePluginTests.cs | 8 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 37 ++-- .../OptimismNethermindApi.cs | 7 +- .../Nethermind.Optimism/OptimismPlugin.cs | 36 ++-- .../Ethereum/ContextWithMocks.cs | 161 ++++++++++-------- .../Steps/EthereumStepsManagerTests.cs | 92 +++++----- .../EthereumRunnerTests.cs | 8 +- .../Modules/BaseModuleTests.cs | 57 +++++++ .../Ethereum/Api/ApiBuilder.cs | 67 ++++++-- .../Ethereum/EthereumRunner.cs | 33 +--- .../Nethermind.Runner/Modules/BaseModule.cs | 129 ++++++++++++++ .../Nethermind.Runner/Modules/CoreModule.cs | 27 +++ .../Nethermind.Runner/Modules/RunnerModule.cs | 24 +++ src/Nethermind/Nethermind.Runner/Program.cs | 28 +-- .../Nethermind.Shutter/ShutterPlugin.cs | 26 +-- .../OldStyleFullSynchronizerTests.cs | 32 ++-- .../SyncThreadTests.cs | 36 ++-- .../SynchronizerTests.cs | 42 ++--- .../Nethermind.UPnP.Plugin/UPnPPlugin.cs | 6 +- 53 files changed, 805 insertions(+), 540 deletions(-) delete mode 100644 src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs create mode 100644 src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs create mode 100644 src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs create mode 100644 src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs create mode 100644 src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs diff --git a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs index 503ce7ffc4c..aa02becc61b 100644 --- a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs +++ b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs @@ -12,14 +12,11 @@ namespace Nethermind.Analytics { - public class AnalyticsPlugin : INethermindPlugin + public class AnalyticsPlugin(IAnalyticsConfig analyticsConfig, IInitConfig initConfig) : INethermindPlugin { - private IAnalyticsConfig _analyticsConfig; private IList _publishers; private INethermindApi _api; - private bool _isOn; - public ValueTask DisposeAsync() { return ValueTask.CompletedTask; } public string Name => "Analytics"; @@ -28,19 +25,20 @@ public class AnalyticsPlugin : INethermindPlugin public string Author => "Nethermind"; + + public bool PluginEnabled =>initConfig.WebSocketsEnabled && + (analyticsConfig.PluginsEnabled || + analyticsConfig.StreamBlocks || + analyticsConfig.StreamTransactions); + public Task Init(INethermindApi api) { _api = api; var (getFromAPi, _) = _api.ForInit; - _analyticsConfig = getFromAPi.Config(); IInitConfig initConfig = getFromAPi.Config(); - _isOn = initConfig.WebSocketsEnabled && - (_analyticsConfig.PluginsEnabled || - _analyticsConfig.StreamBlocks || - _analyticsConfig.StreamTransactions); - if (!_isOn) + if (!PluginEnabled) { if (!initConfig.WebSocketsEnabled) { @@ -57,7 +55,7 @@ public Task Init(INethermindApi api) private void TxPoolOnNewDiscovered(object sender, TxEventArgs e) { - if (_analyticsConfig.StreamTransactions) + if (analyticsConfig.StreamTransactions) { foreach (IPublisher publisher in _publishers) { @@ -70,12 +68,12 @@ private void TxPoolOnNewDiscovered(object sender, TxEventArgs e) public Task InitNetworkProtocol() { var (getFromAPi, _) = _api.ForNetwork; - if (_isOn) + if (PluginEnabled) { getFromAPi.TxPool!.NewDiscovered += TxPoolOnNewDiscovered; } - if (_isOn) + if (PluginEnabled) { AnalyticsWebSocketsModule webSocketsModule = new(getFromAPi.EthereumJsonSerializer, getFromAPi.LogManager); getFromAPi.WebSocketsManager!.AddModule(webSocketsModule, true); diff --git a/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs b/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs index 39aa5a8be2e..b51185fc6ff 100644 --- a/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs +++ b/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs @@ -30,5 +30,7 @@ public Task InitRpcModules() { throw new System.NotImplementedException(); } + + public bool PluginEnabled => true; } } diff --git a/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs b/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs index 51377593c31..570ee4b8d57 100644 --- a/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs +++ b/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs @@ -30,5 +30,7 @@ public Task InitRpcModules() { throw new System.NotImplementedException(); } + + public bool PluginEnabled => true; } } diff --git a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs index 9a0be89152e..88b0aad8d6b 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs @@ -1,13 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only -using System.Threading.Tasks; -using Nethermind.Config; using Nethermind.Consensus; -using Nethermind.Consensus.Producers; -using Nethermind.Logging; -using Nethermind.Serialization.Json; -using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Api.Extensions { @@ -15,9 +9,6 @@ public interface IConsensusPlugin : INethermindPlugin, IBlockProducerFactory { string SealEngineType { get; } - INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, - ILogManager logManager, ChainSpec chainSpec) => new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec); - IBlockProducerRunner CreateBlockProducerRunner(); } } diff --git a/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs index 308038d06e8..06e6a95c7a0 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs @@ -9,11 +9,4 @@ namespace Nethermind.Api.Extensions; /// public interface IInitializationPlugin : INethermindPlugin { - /// - /// This method will be called on the plugin instance - /// decide whether or not we need to run initialization steps - /// defined in its assembly. It receives the api to be able to - /// look at the config. - /// - bool ShouldRunSteps(INethermindApi api); } diff --git a/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs index 2c9f2042f42..c6cf0983cd4 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Autofac; namespace Nethermind.Api.Extensions; @@ -23,4 +24,7 @@ void InitTxTypesAndRlpDecoders(INethermindApi api) { } Task InitRpcModules() => Task.CompletedTask; bool MustInitialize => false; + + bool PluginEnabled { get; } + void ConfigureContainer(ContainerBuilder builder) {} } diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index da24eaa918b..1263974b81e 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -106,7 +106,7 @@ public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(Container { return ConfigureContainerBuilderFromApiWithStores(builder) .AddPropertiesFrom(this) - .AddSingleton(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); + .AddInstance(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); } } } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 1ba0adb91f9..ffd0f158250 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -28,25 +28,25 @@ public interface IBasicApi DisposableStack DisposeStack { get; } IAbiEncoder AbiEncoder { get; } - ChainSpec ChainSpec { get; set; } - IConfigProvider ConfigProvider { get; set; } + ChainSpec ChainSpec { get; } + IConfigProvider ConfigProvider { get; } ICryptoRandom CryptoRandom { get; } IDbProvider? DbProvider { get; set; } IDbFactory? DbFactory { get; set; } IEthereumEcdsa? EthereumEcdsa { get; set; } - IJsonSerializer EthereumJsonSerializer { get; set; } + IJsonSerializer EthereumJsonSerializer { get; } IFileSystem FileSystem { get; set; } IKeyStore? KeyStore { get; set; } - ILogManager LogManager { get; set; } + ILogManager LogManager { get; } ProtectedPrivateKey? OriginalSignerKey { get; set; } IReadOnlyList Plugins { get; } [SkipServiceCollection] - string SealEngineType { get; set; } - ISpecProvider? SpecProvider { get; set; } + string SealEngineType { get; } + ISpecProvider? SpecProvider { get; } IBetterPeerStrategy? BetterPeerStrategy { get; set; } ITimestamper Timestamper { get; } ITimerFactory TimerFactory { get; } - IProcessExitSource? ProcessExit { get; set; } + IProcessExitSource? ProcessExit { get; } public IConsensusPlugin? GetConsensusPlugin() => Plugins @@ -63,7 +63,7 @@ public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder b { builder .AddPropertiesFrom(this) - .AddSingleton(ConfigProvider.GetConfig()); + .AddInstance(ConfigProvider.GetConfig()); DbProvider!.ConfigureServiceCollection(builder); diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 566a094eaa0..0d906f77a4a 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -64,16 +64,13 @@ namespace Nethermind.Api { public class NethermindApi : INethermindApi { - public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) + public NethermindApi(ILifetimeScope lifetimeScope) { - ConfigProvider = configProvider; - EthereumJsonSerializer = jsonSerializer; - LogManager = logManager; - ChainSpec = chainSpec; - CryptoRandom = new CryptoRandom(); - DisposeStack.Push(CryptoRandom); + BaseContainer = lifetimeScope; } + public ILifetimeScope BaseContainer { get; set; } + public IBlockchainBridge CreateBlockchainBridge() { ReadOnlyBlockTree readOnlyTree = BlockTree!.AsReadOnly(); @@ -124,8 +121,8 @@ public IBlockchainBridge CreateBlockchainBridge() public IBlockValidator? BlockValidator { get; set; } public IBloomStorage? BloomStorage { get; set; } public IChainLevelInfoRepository? ChainLevelInfoRepository { get; set; } - public IConfigProvider ConfigProvider { get; set; } - public ICryptoRandom CryptoRandom { get; } + public IConfigProvider ConfigProvider => BaseContainer.Resolve(); + public ICryptoRandom CryptoRandom => BaseContainer.Resolve(); public IDbProvider? DbProvider { get; set; } public IDbFactory? DbFactory { get; set; } public IDisconnectsAnalyzer? DisconnectsAnalyzer { get; set; } @@ -145,11 +142,11 @@ public IBlockchainBridge CreateBlockchainBridge() new BuildBlocksWhenRequested(); public IIPResolver? IpResolver { get; set; } - public IJsonSerializer EthereumJsonSerializer { get; set; } + public IJsonSerializer EthereumJsonSerializer => BaseContainer.Resolve(); public IKeyStore? KeyStore { get; set; } public IPasswordProvider? PasswordProvider { get; set; } public ILogFinder? LogFinder { get; set; } - public ILogManager LogManager { get; set; } + public ILogManager LogManager => BaseContainer.Resolve(); public IKeyValueStoreWithBatching? MainStateDbWithCache { get; set; } public IMessageSerializationService MessageSerializationService { get; } = new MessageSerializationService(); public IGossipPolicy GossipPolicy { get; set; } = Policy.FullGossip; @@ -168,7 +165,7 @@ public IBlockchainBridge CreateBlockchainBridge() public IRpcAuthentication? RpcAuthentication { get; set; } public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } public ISealer? Sealer { get; set; } = NullSealEngine.Instance; - public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None; + public string SealEngineType => ChainSpec.SealEngineType; public ISealValidator? SealValidator { get; set; } = NullSealEngine.Instance; private ISealEngine? _sealEngine; public ISealEngine SealEngine @@ -185,7 +182,7 @@ public ISealEngine SealEngine } public ISessionMonitor? SessionMonitor { get; set; } - public ISpecProvider? SpecProvider { get; set; } + public ISpecProvider? SpecProvider => BaseContainer.Resolve(); public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.Resolve()!; @@ -237,12 +234,12 @@ public ISealEngine SealEngine /// public ProtectedPrivateKey? OriginalSignerKey { get; set; } - public ChainSpec ChainSpec { get; set; } + public ChainSpec ChainSpec => BaseContainer.Resolve(); public DisposableStack DisposeStack { get; } = new(); - public IReadOnlyList Plugins { get; } = new List(); + public IReadOnlyList Plugins => BaseContainer.Resolve>(); public IList Publishers { get; } = new List(); // this should be called publishers public CompositePruningTrigger PruningTrigger { get; } = new(); - public IProcessExitSource? ProcessExit { get; set; } + public IProcessExitSource? ProcessExit => BaseContainer.Resolve(); public CompositeTxGossipPolicy TxGossipPolicy { get; } = new(); public IContainer? ApiWithNetworkServiceContainer { get; set; } diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs deleted file mode 100644 index 03c84f9b2b8..00000000000 --- a/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using FluentAssertions; -using Nethermind.Api; -using Nethermind.Config; -using Nethermind.Consensus.AuRa; -using Nethermind.Consensus.AuRa.InitializationSteps; -using Nethermind.Logging; -using Nethermind.Serialization.Json; -using Nethermind.Specs.ChainSpecStyle; -using NUnit.Framework; - -namespace Nethermind.AuRa.Test -{ - public class AuRaPluginTests - { - [Test] - public void Init_when_not_AuRa_doesnt_trow() - { - AuRaPlugin auRaPlugin = new(); - Action init = () => auRaPlugin.Init(new AuRaNethermindApi(new ConfigProvider(), new EthereumJsonSerializer(), new TestLogManager(), new ChainSpec())); - init.Should().NotThrow(); - } - - } -} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index f3c766da5f0..0ff09e0d929 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -3,12 +3,15 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; +using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Config; using Nethermind.Consensus.AuRa.InitializationSteps; using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; +using Nethermind.Core; +using Nethermind.Init.Steps; using Nethermind.Logging; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; @@ -20,7 +23,7 @@ namespace Nethermind.Consensus.AuRa /// /// Consensus plugin for AuRa setup. /// - public class AuRaPlugin : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin + public class AuRaPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin { private AuRaNethermindApi? _nethermindApi; public string Name => SealEngineType; @@ -30,9 +33,14 @@ public class AuRaPlugin : IConsensusPlugin, ISynchronizationPlugin, IInitializat public string Author => "Nethermind"; public string SealEngineType => Core.SealEngineType.AuRa; + public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; private StartBlockProducerAuRa? _blockProducerStarter; + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterModule(new AuraModule()); + } public ValueTask DisposeAsync() { @@ -76,10 +84,17 @@ public IBlockProducerRunner CreateBlockProducerRunner() _nethermindApi.BlockTree, _nethermindApi.BlockProducer!); } + } - public INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, - ILogManager logManager, ChainSpec chainSpec) => new AuRaNethermindApi(configProvider, jsonSerializer, logManager, chainSpec); + public class AuraModule : Module + { + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); - public bool ShouldRunSteps(INethermindApi api) => true; + builder + .AddSingleton() + .AddIStepsFromAssembly(GetType().Assembly); + } } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs index c3822f5edd0..fab6f6b2c54 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/AuRaNethermindApi.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Autofac; using Nethermind.Api; using Nethermind.Blockchain; using Nethermind.Config; @@ -20,8 +21,7 @@ namespace Nethermind.Consensus.AuRa.InitializationSteps { public class AuRaNethermindApi : NethermindApi { - public AuRaNethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) - : base(configProvider, jsonSerializer, logManager, chainSpec) + public AuRaNethermindApi(ILifetimeScope lifetimeScope) : base(lifetimeScope) { } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs index 9167e80f900..76bc1ef0393 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs @@ -21,11 +21,12 @@ using Nethermind.Db; using Nethermind.Evm.TransactionProcessing; using Nethermind.JsonRpc.Modules; +using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; namespace Nethermind.Consensus.Clique { - public class CliquePlugin : IConsensusPlugin + public class CliquePlugin(ChainSpec chainSpec) : IConsensusPlugin { public string Name => "Clique"; @@ -33,6 +34,8 @@ public class CliquePlugin : IConsensusPlugin public string Author => "Nethermind"; + public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public Task Init(INethermindApi nethermindApi) { _nethermindApi = nethermindApi; diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs index dae39105746..c49e91fc64d 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs @@ -7,10 +7,11 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Transactions; +using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Consensus.Ethash { - public class EthashPlugin : IConsensusPlugin + public class EthashPlugin(ChainSpec chainSpec) : IConsensusPlugin { private INethermindApi _nethermindApi; @@ -22,6 +23,8 @@ public class EthashPlugin : IConsensusPlugin public string Author => "Nethermind"; + public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public Task Init(INethermindApi nethermindApi) { _nethermindApi = nethermindApi; diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs b/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs index 215ae44e976..53ea388044a 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs @@ -18,11 +18,12 @@ using Nethermind.Db; using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; +using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; namespace Nethermind.Consensus.Ethash { - public class NethDevPlugin : IConsensusPlugin + public class NethDevPlugin(ChainSpec chainSpec) : IConsensusPlugin { private INethermindApi? _nethermindApi; @@ -40,6 +41,8 @@ public Task Init(INethermindApi nethermindApi) return Task.CompletedTask; } + public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) { if (_nethermindApi!.SealEngineType != Nethermind.Core.SealEngineType.NethDev) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 2af6892ee13..f07d4c411aa 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Autofac; +using Nethermind.Api; using Nethermind.Blockchain; using Nethermind.Blockchain.BeaconBlockRoot; using Nethermind.Blockchain.Blocks; @@ -33,6 +35,7 @@ using Nethermind.Facade.Find; using Nethermind.Int256; using Nethermind.Logging; +using Nethermind.Runner.Modules; using Nethermind.Serialization.Json; using Nethermind.Specs; using Nethermind.Specs.Test; @@ -127,11 +130,18 @@ protected TestBlockchain() private PreBlockCaches PreBlockCaches { get; } = new(); + protected IContainer Container { get; private set; } = null!; + protected virtual async Task Build(ISpecProvider? specProvider = null, UInt256? initialValues = null, bool addBlockOnStart = true) { Timestamper = new ManualTimestamper(new DateTime(2020, 2, 15, 12, 50, 30, DateTimeKind.Utc)); JsonSerializer = new EthereumJsonSerializer(); SpecProvider = CreateSpecProvider(specProvider ?? MainnetSpecProvider.Instance); + + ContainerBuilder builder = new ContainerBuilder(); + ConfigureContainer(builder); + Container = builder.Build(); + EthereumEcdsa = new EthereumEcdsa(SpecProvider.ChainId); DbProvider = await CreateDbProvider(); TrieStore = new TrieStore(StateDb, LogManager); @@ -250,6 +260,17 @@ protected virtual async Task Build(ISpecProvider? specProvider = return this; } + protected virtual void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterModule(new BaseModule()); + builder.RegisterModule(new CoreModule()); + + builder + .AddInstance(SpecProvider) + .AddInstance(LogManager) + .AddInstance(new ConfigProvider()); + } + private static ISpecProvider CreateSpecProvider(ISpecProvider specProvider) { return specProvider is TestSpecProvider { AllowTestChainOverride: false } diff --git a/src/Nethermind/Nethermind.Core.Test/Nethermind.Core.Test.csproj b/src/Nethermind/Nethermind.Core.Test/Nethermind.Core.Test.csproj index d277beb757b..acdc0dad54a 100644 --- a/src/Nethermind/Nethermind.Core.Test/Nethermind.Core.Test.csproj +++ b/src/Nethermind/Nethermind.Core.Test/Nethermind.Core.Test.csproj @@ -24,6 +24,7 @@ + diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs index 1c30a830b55..c11037fb923 100644 --- a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using Autofac; +using Autofac.Core; using Autofac.Features.AttributeFilters; namespace Nethermind.Core; @@ -50,7 +51,7 @@ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) wh return builder; } - public static ContainerBuilder AddSingleton(this ContainerBuilder builder, T instance) where T : class + public static ContainerBuilder AddInstance(this ContainerBuilder builder, T instance) where T : class { builder.RegisterInstance(instance) .As() @@ -115,6 +116,13 @@ public static ContainerBuilder RegisterNamedComponentInItsOwnLifetime(this Co return builder; } + + public static ContainerBuilder AddModule(this ContainerBuilder builder, IModule module) + { + builder.RegisterModule(module); + + return builder; + } } /// diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 6a0380b0446..0e29da0e432 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -36,7 +36,7 @@ public interface IDbProvider : IDisposable void ConfigureServiceCollection(ContainerBuilder sc) { - sc.AddSingleton(this); + sc.AddInstance(this); // TODO: Have hooks that automatically get these string[] dbNames = [ @@ -59,7 +59,7 @@ void ConfigureServiceCollection(ContainerBuilder sc) } IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts); - sc.AddSingleton>(receiptColumnDb); + sc.AddInstance>(receiptColumnDb); sc.AddKeyedSingleton(DbNames.Receipts, receiptColumnDb as ITunableDb ?? new NoopTunableDb()); } } diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs index e0fffd67b31..832ac20ec64 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs @@ -11,7 +11,6 @@ namespace Nethermind.EthStats.Test; public class EthStatsPluginTests { - public IEthStatsConfig StatsConfig { get; private set; } = null!; private NethermindApi _context = null!; #pragma warning disable NUnit1032 private INethermindPlugin _plugin = null!; @@ -21,7 +20,7 @@ public class EthStatsPluginTests public void Setup() { _context = Build.ContextWithMocks(); - _plugin = new EthStatsPlugin(); + _plugin = new EthStatsPlugin(new EthStatsConfig() { Enabled = true}); } [TearDown] @@ -31,7 +30,6 @@ public void Setup() [TestCase(false)] public void Init_eth_stats_plugin_does_not_throw_exception(bool enabled) { - StatsConfig = new EthStatsConfig() { Enabled = enabled }; Assert.DoesNotThrow(() => _plugin.InitTxTypesAndRlpDecoders(_context)); Assert.DoesNotThrowAsync(async () => await _plugin.Init(_context)); Assert.DoesNotThrowAsync(async () => await _plugin.InitNetworkProtocol()); diff --git a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs index b57e083dbe6..88f4eea3327 100644 --- a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs +++ b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs @@ -18,9 +18,8 @@ namespace Nethermind.EthStats; -public class EthStatsPlugin : INethermindPlugin +public class EthStatsPlugin(IEthStatsConfig ethStatsConfig) : INethermindPlugin { - private IEthStatsConfig _ethStatsConfig = null!; private IEthStatsClient _ethStatsClient = null!; private IEthStatsIntegration _ethStatsIntegration = null!; private INethermindApi _api = null!; @@ -31,6 +30,7 @@ public class EthStatsPlugin : INethermindPlugin public string Name => "EthStats"; public string Description => "Ethereum Statistics"; public string Author => "Nethermind"; + public bool PluginEnabled => ethStatsConfig.Enabled; public ValueTask DisposeAsync() { @@ -42,10 +42,10 @@ public Task Init(INethermindApi nethermindApi) { _api = nethermindApi; var (getFromAPi, _) = _api.ForInit; - _ethStatsConfig = getFromAPi.Config(); + ethStatsConfig = getFromAPi.Config(); IInitConfig initConfig = getFromAPi.Config(); - _isOn = _ethStatsConfig.Enabled; + _isOn = ethStatsConfig.Enabled; _logger = getFromAPi.LogManager.GetClassLogger(); if (!_isOn) @@ -72,10 +72,10 @@ public async Task InitNetworkProtocol() if (_isOn) { - string instanceId = $"{_ethStatsConfig.Name}-{Keccak.Compute(getFromAPi.Enode!.Info)}"; + string instanceId = $"{ethStatsConfig.Name}-{Keccak.Compute(getFromAPi.Enode!.Info)}"; if (_logger.IsInfo) { - _logger.Info($"Initializing ETH Stats for the instance: {instanceId}, server: {_ethStatsConfig.Server}"); + _logger.Info($"Initializing ETH Stats for the instance: {instanceId}, server: {ethStatsConfig.Server}"); } MessageSender sender = new(instanceId, _api.LogManager); const int reconnectionInterval = 5000; @@ -88,22 +88,22 @@ public async Task InitNetworkProtocol() string protocol = $"{P2PProtocolInfoProvider.DefaultCapabilitiesToString()}"; _ethStatsClient = new EthStatsClient( - _ethStatsConfig.Server, + ethStatsConfig.Server, reconnectionInterval, sender, _api.LogManager); _ethStatsIntegration = new EthStatsIntegration( - _ethStatsConfig.Name!, + ethStatsConfig.Name!, node, port, network, protocol, api, client, - _ethStatsConfig.Contact!, + ethStatsConfig.Contact!, canUpdateHistory, - _ethStatsConfig.Secret!, + ethStatsConfig.Secret!, _ethStatsClient, sender, getFromAPi.TxPool!, @@ -112,7 +112,7 @@ public async Task InitNetworkProtocol() getFromAPi.GasPriceOracle!, getFromAPi.EthSyncingInfo!, initConfig.IsMining, - TimeSpan.FromSeconds(_ethStatsConfig.SendInterval), + TimeSpan.FromSeconds(ethStatsConfig.SendInterval), getFromAPi.LogManager); await _ethStatsIntegration.InitAsync(); diff --git a/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs b/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs index 9c96f175d1b..ef60f479bf6 100644 --- a/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs +++ b/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs @@ -22,6 +22,7 @@ public class ClefSignerPlugin : INethermindPlugin public string Description => "Enabled signing from a remote Clef instance over Json RPC."; public string Author => "Nethermind"; + public bool PluginEnabled => true; public ValueTask DisposeAsync() => ValueTask.CompletedTask; diff --git a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs index 92d9b5bce85..4975d3788fb 100644 --- a/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs +++ b/src/Nethermind/Nethermind.HealthChecks.Test/NodeHealthServiceTests.cs @@ -42,7 +42,7 @@ public void CheckHealth_returns_expected_results([ValueSource(nameof(CheckHealth ISyncConfig syncConfig = Substitute.For(); IHealthHintService healthHintService = Substitute.For(); INethermindApi api = Substitute.For(); - api.SpecProvider = Substitute.For(); + api.SpecProvider.Returns(Substitute.For()); blockchainProcessor.IsProcessingBlocks(Arg.Any()).Returns(test.IsProcessingBlocks); blockProducerRunner.IsProducingBlocks(Arg.Any()).Returns(test.IsProducingBlocks); syncServer.GetPeerCount().Returns(test.PeerCount); @@ -113,7 +113,7 @@ public void post_merge_health_checks([ValueSource(nameof(CheckHealthPostMergeTes drive.TotalSize.Returns((long)(_freeSpaceBytes * 100.0 / test.AvailableDiskSpacePercent)); drive.RootDirectory.FullName.Returns("C:/"); - api.SpecProvider = Substitute.For(); + api.SpecProvider.Returns(Substitute.For()); api.SpecProvider.TerminalTotalDifficulty.Returns(UInt256.Zero); BlockHeaderBuilder GetBlockHeader(int blockNumber) => Build.A.BlockHeader.WithNumber(blockNumber); diff --git a/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs b/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs index e56363a30e3..1f2e8058816 100644 --- a/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs +++ b/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs @@ -53,6 +53,7 @@ public async ValueTask DisposeAsync() public string Author => "Nethermind"; public bool MustInitialize => true; + public bool PluginEnabled => true; public FreeDiskSpaceChecker FreeDiskSpaceChecker => LazyInitializer.EnsureInitialized(ref _freeDiskSpaceChecker, () => new FreeDiskSpaceChecker( diff --git a/src/Nethermind/Nethermind.Hive/HivePlugin.cs b/src/Nethermind/Nethermind.Hive/HivePlugin.cs index 62aaef0a766..35e988dd3fb 100644 --- a/src/Nethermind/Nethermind.Hive/HivePlugin.cs +++ b/src/Nethermind/Nethermind.Hive/HivePlugin.cs @@ -10,12 +10,12 @@ namespace Nethermind.Hive { - public class HivePlugin : INethermindPlugin + public class HivePlugin(IHiveConfig hiveConfig) : INethermindPlugin { private INethermindApi _api = null!; - private IHiveConfig _hiveConfig = null!; private ILogger _logger; private readonly CancellationTokenSource _disposeCancellationToken = new(); + public bool PluginEnabled => Environment.GetEnvironmentVariable("NETHERMIND_HIVE_ENABLED")?.ToLowerInvariant() == "true" || hiveConfig.Enabled; public ValueTask DisposeAsync() { @@ -33,17 +33,14 @@ public ValueTask DisposeAsync() public Task Init(INethermindApi api) { _api = api ?? throw new ArgumentNullException(nameof(api)); - _hiveConfig = _api.ConfigProvider.GetConfig(); _logger = _api.LogManager.GetClassLogger(); - Enabled = Environment.GetEnvironmentVariable("NETHERMIND_HIVE_ENABLED")?.ToLowerInvariant() == "true" || _hiveConfig.Enabled; - return Task.CompletedTask; } public async Task InitNetworkProtocol() { - if (Enabled) + if (PluginEnabled) { if (_api.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.BlockProcessingQueue is null) throw new ArgumentNullException(nameof(_api.BlockProcessingQueue)); @@ -73,7 +70,5 @@ public Task InitRpcModules() { return Task.CompletedTask; } - - private bool Enabled { get; set; } } } diff --git a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs index 52449d70f0b..09796421d69 100644 --- a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs +++ b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs @@ -1,9 +1,11 @@ +using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; +using Nethermind.Init.Steps; namespace Nethermind.Init.Snapshot; -public class SnapshotPlugin : IInitializationPlugin +public class SnapshotPlugin(ISnapshotConfig snapshotConfig) : IInitializationPlugin { public string Name => "Snapshot"; @@ -15,8 +17,13 @@ public class SnapshotPlugin : IInitializationPlugin public Task InitNetworkProtocol() => Task.CompletedTask; public Task InitRpcModules() => Task.CompletedTask; - public bool ShouldRunSteps(INethermindApi api) => - api.Config() is { Enabled: true, DownloadUrl: not null }; + public bool PluginEnabled => + snapshotConfig is { Enabled: true, DownloadUrl: not null }; + + public void ConfigureContainer(ContainerBuilder builder) + { + builder.AddIStepsFromAssembly(GetType().Assembly); + } public ValueTask DisposeAsync() => ValueTask.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Init/Steps/EthereumStepsLoader.cs b/src/Nethermind/Nethermind.Init/Steps/EthereumStepsLoader.cs index 1fb0ac15acf..9d63bc23be9 100644 --- a/src/Nethermind/Nethermind.Init/Steps/EthereumStepsLoader.cs +++ b/src/Nethermind/Nethermind.Init/Steps/EthereumStepsLoader.cs @@ -4,83 +4,47 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; -using Nethermind.Api; namespace Nethermind.Init.Steps { public class EthereumStepsLoader : IEthereumStepsLoader { - private readonly IEnumerable _stepsAssemblies; - private readonly Type _baseApiType = typeof(INethermindApi); + private readonly IReadOnlyList _steps; - public EthereumStepsLoader(params Assembly[] stepsAssemblies) - : this((IEnumerable)stepsAssemblies) { } - - public EthereumStepsLoader(IEnumerable stepsAssemblies) + public EthereumStepsLoader(IReadOnlyList steps) { - _stepsAssemblies = stepsAssemblies; + _steps = steps; } - public IEnumerable LoadSteps(Type apiType) + public IEnumerable LoadSteps() { - if (!apiType.GetInterfaces().Contains(_baseApiType)) - { - throw new NotSupportedException($"api type must implement {_baseApiType.Name}"); - } - - List allStepTypes = new List(); - foreach (Assembly stepsAssembly in _stepsAssemblies) - { - allStepTypes.AddRange(stepsAssembly.GetExportedTypes() - .Where(t => !t.IsInterface && !t.IsAbstract && IsStepType(t))); - } - - return allStepTypes - .Select(s => new StepInfo(s, GetStepBaseType(s))) + return _steps .GroupBy(s => s.StepBaseType) - .Select(g => SelectImplementation(g.ToArray(), apiType)) + .Select(g => SelectImplementation(g.ToArray(), g.Key)) .Where(s => s is not null) .Select(s => s!); } - private static bool HasConstructorWithParameter(Type type, Type parameterType) + private StepInfo? SelectImplementation(StepInfo[] stepsWithTheSameBase, Type baseType) { - Type[] expectedParams = { parameterType }; - return type.GetConstructors().Any( - c => c.GetParameters().Select(p => p.ParameterType).SequenceEqual(expectedParams)); - } - - private StepInfo? SelectImplementation(StepInfo[] stepsWithTheSameBase, Type apiType) - { - StepInfo[] stepsWithMatchingApiType = stepsWithTheSameBase - .Where(t => HasConstructorWithParameter(t.StepType, apiType)).ToArray(); - - if (stepsWithMatchingApiType.Length == 0) + // In case of multiple step declaration, make sure that there is one final step that is the most specific + // implementation. + StepInfo[] stepWithNoParent = stepsWithTheSameBase.Where((currentStep) => { - // base API type this time - stepsWithMatchingApiType = stepsWithTheSameBase - .Where(t => HasConstructorWithParameter(t.StepType, _baseApiType)).ToArray(); - } + return !stepsWithTheSameBase.Any(otherStep => + otherStep != currentStep && currentStep.StepType.IsAssignableFrom(otherStep.StepType)); + }).ToArray(); - if (stepsWithMatchingApiType.Length > 1) + if (stepWithNoParent.Length != 1) { - Array.Sort(stepsWithMatchingApiType, (t1, t2) => t1.StepType.IsAssignableFrom(t2.StepType) ? 1 : -1); + throw new InvalidOperationException( + $"Unable to find unique step for group {baseType.FullName}. Current steps: {stepWithNoParent}"); } - return stepsWithMatchingApiType.FirstOrDefault(); + return stepWithNoParent[0]; } private static bool IsStepType(Type t) => typeof(IStep).IsAssignableFrom(t); - private static Type GetStepBaseType(Type type) - { - while (type.BaseType is not null && IsStepType(type.BaseType)) - { - type = type.BaseType; - } - - return type; - } } } diff --git a/src/Nethermind/Nethermind.Init/Steps/EthereumStepsManager.cs b/src/Nethermind/Nethermind.Init/Steps/EthereumStepsManager.cs index 337729eb705..903cea88893 100644 --- a/src/Nethermind/Nethermind.Init/Steps/EthereumStepsManager.cs +++ b/src/Nethermind/Nethermind.Init/Steps/EthereumStepsManager.cs @@ -9,6 +9,7 @@ using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; +using Autofac; using Nethermind.Api; using Nethermind.Core.Extensions; using Nethermind.Logging; @@ -20,22 +21,19 @@ public class EthereumStepsManager private readonly ILogger _logger; private readonly AutoResetEvent _autoResetEvent = new AutoResetEvent(true); - private readonly INethermindApi _api; + private readonly ILifetimeScope _container; private readonly List _allSteps; private readonly Dictionary _allStepsByBaseType; public EthereumStepsManager( IEthereumStepsLoader loader, - INethermindApi context, - ILogManager logManager) + ILifetimeScope container, + ILogger logger) { - ArgumentNullException.ThrowIfNull(loader); + _container = container; + _logger = logger; - _api = context ?? throw new ArgumentNullException(nameof(context)); - _logger = logManager?.GetClassLogger() - ?? throw new ArgumentNullException(nameof(logManager)); - - _allSteps = loader.LoadSteps(_api.GetType()).ToList(); + _allSteps = loader.LoadSteps().ToList(); _allStepsByBaseType = _allSteps.ToDictionary(s => s.StepBaseType, s => s); } @@ -147,14 +145,14 @@ private void RunOneRoundOfInitialization(CancellationToken cancellationToken) private async Task ExecuteStep(IStep step, StepInfo stepInfo, CancellationToken cancellationToken) { - long startTime = Stopwatch.GetTimestamp(); + Stopwatch stopwatch = Stopwatch.StartNew(); try { await step.Execute(cancellationToken); if (_logger.IsDebug) _logger.Debug( - $"Step {step.GetType().Name.PadRight(24)} executed in {Stopwatch.GetElapsedTime(startTime).TotalMilliseconds:N0}ms"); + $"Step {step.GetType().Name.PadRight(24)} executed in {stopwatch.ElapsedMilliseconds}ms"); stepInfo.Stage = StepInitializationStage.Complete; } @@ -164,7 +162,7 @@ private async Task ExecuteStep(IStep step, StepInfo stepInfo, CancellationToken { if (_logger.IsError) _logger.Error( - $"Step {step.GetType().Name.PadRight(24)} failed after {Stopwatch.GetElapsedTime(startTime).TotalMilliseconds:N0}ms", + $"Step {step.GetType().Name.PadRight(24)} failed after {stopwatch.ElapsedMilliseconds}ms", exception); stepInfo.Stage = StepInitializationStage.Failed; @@ -174,12 +172,13 @@ private async Task ExecuteStep(IStep step, StepInfo stepInfo, CancellationToken if (_logger.IsWarn) { _logger.Warn( - $"Step {step.GetType().Name.PadRight(24)} failed after {Stopwatch.GetElapsedTime(startTime).TotalMilliseconds:N0}ms {exception}"); + $"Step {step.GetType().Name.PadRight(24)} failed after {stopwatch.ElapsedMilliseconds}ms {exception}"); } stepInfo.Stage = StepInitializationStage.Complete; } finally { + stopwatch.Stop(); _autoResetEvent.Set(); if (_logger.IsDebug) _logger.Debug($"{step.GetType().Name.PadRight(24)} complete"); @@ -191,7 +190,7 @@ private async Task ExecuteStep(IStep step, StepInfo stepInfo, CancellationToken IStep? step = null; try { - step = Activator.CreateInstance(stepInfo.StepType, _api) as IStep; + step = (IStep)_container.Resolve(stepInfo.StepType); } catch (Exception e) { diff --git a/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs b/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs index df856ac2e03..c36f3418a12 100644 --- a/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs +++ b/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs @@ -1,8 +1,13 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Autofac; +using Autofac.Features.AttributeFilters; namespace Nethermind.Init.Steps { @@ -12,4 +17,42 @@ public interface IStep public bool MustInitialize => true; } + + public static class ContainerBuilderExtensions + { + public static ContainerBuilder AddIStepsFromAssembly(this ContainerBuilder builder, Assembly assembly) + { + foreach (Type stepType in assembly.GetExportedTypes().Where(IsStepType)) + { + AddIStep(builder, stepType); + } + + return builder; + } + + public static ContainerBuilder AddIStep(this ContainerBuilder builder, Type stepType) + { + builder.RegisterType(stepType) + .AsSelf() + .As() + .WithAttributeFiltering(); + + StepInfo info = new StepInfo(stepType, GetStepBaseType(stepType)); + builder.RegisterInstance(info); + + return builder; + } + + private static bool IsStepType(Type t) => !t.IsInterface && !t.IsAbstract && typeof(IStep).IsAssignableFrom((Type?)(Type?)t); + private static bool IsBaseStepType(Type t) => t != typeof(IStep) && typeof(IStep).IsAssignableFrom((Type?)t); + private static Type GetStepBaseType(Type type) + { + while (type.BaseType is not null && IsBaseStepType(type.BaseType)) + { + type = type.BaseType; + } + + return type; + } + } } diff --git a/src/Nethermind/Nethermind.Init/Steps/IEthereumStepsLoader.cs b/src/Nethermind/Nethermind.Init/Steps/IEthereumStepsLoader.cs index fac08caa63a..58a44f5139b 100644 --- a/src/Nethermind/Nethermind.Init/Steps/IEthereumStepsLoader.cs +++ b/src/Nethermind/Nethermind.Init/Steps/IEthereumStepsLoader.cs @@ -8,6 +8,6 @@ namespace Nethermind.Init.Steps { public interface IEthereumStepsLoader { - public IEnumerable LoadSteps(Type apiType); + public IEnumerable LoadSteps(); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index db2854c0003..d21db889b84 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -135,7 +135,7 @@ private async Task Initialize(CancellationToken cancellationToken) ContainerBuilder builder = new ContainerBuilder(); _api.ConfigureContainerBuilderFromApiWithNetwork(builder) - .AddSingleton(No.BeaconSync); + .AddInstance(No.BeaconSync); builder.RegisterModule(new SynchronizerModule(_syncConfig)); IContainer container = builder.Build(); diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs index 42978992818..9b3ec096450 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs @@ -11,11 +11,10 @@ namespace Nethermind.JsonRpc.TraceStore; -public class TraceStorePlugin : INethermindPlugin +public class TraceStorePlugin(ITraceStoreConfig config) : INethermindPlugin { private const string DbName = "TraceStore"; private INethermindApi _api = null!; - private ITraceStoreConfig _config = null!; private IJsonRpcConfig _jsonRpcConfig = null!; private IDb? _db; private TraceStorePruner? _pruner; @@ -25,29 +24,29 @@ public class TraceStorePlugin : INethermindPlugin public string Name => DbName; public string Description => "Allows to serve traces without the block state, by saving historical traces to DB."; public string Author => "Nethermind"; - private bool Enabled => _config?.Enabled == true; + public bool PluginEnabled => config.Enabled; public Task Init(INethermindApi nethermindApi) { _api = nethermindApi; _logManager = _api.LogManager; - _config = _api.Config(); + config = _api.Config(); _jsonRpcConfig = _api.Config(); _logger = _logManager.GetClassLogger(); - if (Enabled) + if (PluginEnabled) { // Setup serialization - _traceSerializer = new ParityLikeTraceSerializer(_logManager, _config.MaxDepth, _config.VerifySerialized); + _traceSerializer = new ParityLikeTraceSerializer(_logManager, config.MaxDepth, config.VerifySerialized); // Setup DB _db = _api.DbFactory!.CreateDb(new DbSettings(DbName, DbName.ToLower())); _api.DbProvider!.RegisterDb(DbName, _db); //Setup pruning if configured - if (_config.BlocksToKeep != 0) + if (config.BlocksToKeep != 0) { - _pruner = new TraceStorePruner(_api.BlockTree!, _db, _config.BlocksToKeep, _logManager); + _pruner = new TraceStorePruner(_api.BlockTree!, _db, config.BlocksToKeep, _logManager); } } @@ -56,12 +55,12 @@ public Task Init(INethermindApi nethermindApi) public Task InitNetworkProtocol() { - if (Enabled) + if (PluginEnabled) { - if (_logger.IsInfo) _logger.Info($"Starting TraceStore with {_config.TraceTypes} traces."); + if (_logger.IsInfo) _logger.Info($"Starting TraceStore with {config.TraceTypes} traces."); // Setup tracing - ParityLikeBlockTracer parityTracer = new(_config.TraceTypes); + ParityLikeBlockTracer parityTracer = new(config.TraceTypes); DbPersistingBlockTracer dbPersistingTracer = new(parityTracer, _db!, _traceSerializer!, _logManager); _api.BlockchainProcessor!.Tracers.Add(dbPersistingTracer); @@ -73,12 +72,12 @@ public Task InitNetworkProtocol() public Task InitRpcModules() { - if (Enabled && _jsonRpcConfig.Enabled) + if (PluginEnabled && _jsonRpcConfig.Enabled) { IRpcModuleProvider apiRpcModuleProvider = _api.RpcModuleProvider!; if (apiRpcModuleProvider.GetPool(ModuleType.Trace) is IRpcModulePool traceModulePool) { - TraceStoreModuleFactory traceModuleFactory = new(traceModulePool.Factory, _db!, _api.BlockTree!, _api.ReceiptFinder!, _traceSerializer!, _logManager, _config.DeserializationParallelization); + TraceStoreModuleFactory traceModuleFactory = new(traceModulePool.Factory, _db!, _api.BlockTree!, _api.ReceiptFinder!, _traceSerializer!, _logManager, config.DeserializationParallelization); apiRpcModuleProvider.RegisterBoundedByCpuCount(traceModuleFactory, _jsonRpcConfig.Timeout); } } @@ -88,7 +87,7 @@ public Task InitRpcModules() public ValueTask DisposeAsync() { - if (Enabled) + if (PluginEnabled) { _pruner?.Dispose(); _db?.Dispose(); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index b2d1e4c26ab..3b904bf5882 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -3,6 +3,8 @@ using System; using System.Threading.Tasks; +using Autofac; +using Nethermind.Api; using Nethermind.Blockchain.BeaconBlockRoot; using Nethermind.Blockchain.Blocks; using Nethermind.Blockchain.Synchronization; @@ -118,25 +120,28 @@ protected override Task Build(ISpecProvider? specProvider = null return base.Build(specProvider, initialValues, addBlockOnStart); } - protected override IBlockProcessor CreateBlockProcessor() + protected override void ConfigureContainer(ContainerBuilder builder) { - _api = new(new ConfigProvider(), new EthereumJsonSerializer(), LogManager, - new ChainSpec - { - AuRa = new() - { - WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") - }, - Parameters = new() - }) + base.ConfigureContainer(builder); + builder.RegisterInstance(new ChainSpec { - BlockTree = BlockTree, - DbProvider = DbProvider, - WorldStateManager = WorldStateManager, - SpecProvider = SpecProvider, - TransactionComparerProvider = TransactionComparerProvider, - TxPool = TxPool - }; + AuRa = new() + { + WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") + }, + Parameters = new() + }); + builder.RegisterModule(new AuraModule()); + } + + protected override IBlockProcessor CreateBlockProcessor() + { + _api = Container.Resolve(); + _api.BlockTree = BlockTree; + _api.DbProvider = DbProvider; + _api.WorldStateManager = WorldStateManager; + _api.TransactionComparerProvider = TransactionComparerProvider; + _api.TxPool = TxPool; WithdrawalContractFactory withdrawalContractFactory = new(_api.ChainSpec!.AuRa, _api.AbiEncoder); WithdrawalProcessor = new AuraWithdrawalProcessor( diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs index 5e6b55a5ff4..b3caaf475cb 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Blockchain; @@ -12,8 +13,10 @@ using Nethermind.Consensus.AuRa.Transactions; using Nethermind.Consensus.Transactions; using Nethermind.Core; +using Nethermind.Init.Steps; using Nethermind.Merge.Plugin; using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Merge.AuRa { @@ -21,18 +24,25 @@ namespace Nethermind.Merge.AuRa /// Plugin for AuRa -> PoS migration /// /// IMPORTANT: this plugin should always come before MergePlugin - public class AuRaMergePlugin : MergePlugin, IInitializationPlugin + public class AuRaMergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : MergePlugin(mergeConfig, chainSpec), IInitializationPlugin { private AuRaNethermindApi? _auraApi; + private readonly ChainSpec _chainSpec = chainSpec; + private readonly IMergeConfig _mergeConfig = mergeConfig; public override string Name => "AuRaMerge"; public override string Description => "AuRa Merge plugin for ETH1-ETH2"; - protected override bool MergeEnabled => ShouldRunSteps(_api); + protected override bool MergeEnabled => PluginEnabled; + public override bool PluginEnabled => _mergeConfig.Enabled && _chainSpec.SealEngineType == SealEngineType.AuRa; + + public void ConfigureContainer(ContainerBuilder builder) + { + builder.AddIStepsFromAssembly(GetType().Assembly); + } public override async Task Init(INethermindApi nethermindApi) { _api = nethermindApi; - _mergeConfig = nethermindApi.Config(); if (MergeEnabled) { await base.Init(nethermindApi); @@ -81,11 +91,5 @@ protected override IBlockFinalizationManager InitializeMergeFinilizationManager( "Cannot instantiate AuRaMergeFinalizationManager when AuRaFinalizationManager is null!"), _poSSwitcher); } - - public bool ShouldRunSteps(INethermindApi api) - { - _mergeConfig = api.Config(); - return _mergeConfig.Enabled && api.ChainSpec.SealEngineType == SealEngineType.AuRa; - } } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index d93e6c8a649..ef2246bcff9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -15,6 +15,7 @@ using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Merge.Plugin.Synchronization; using Nethermind.Specs.ChainSpecStyle; using NUnit.Framework; using NSubstitute; @@ -37,7 +38,6 @@ public void Setup() IJsonRpcConfig jsonRpcConfig = new JsonRpcConfig() { Enabled = true, EnabledModules = [ModuleType.Engine] }; _context = Build.ContextWithMocks(); - _context.SealEngineType = SealEngineType.Clique; _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); _context.ConfigProvider.GetConfig().Returns(miningConfig); @@ -56,16 +56,14 @@ public void Setup() _context.TransactionComparerProvider!, miningConfig, _context.LogManager!); - _context.ProcessExit = Substitute.For(); _context.ChainSpec.SealEngineType = SealEngineType.Clique; _context.ChainSpec!.Clique = new CliqueParameters() { Epoch = CliqueConfig.Default.Epoch, Period = CliqueConfig.Default.BlockPeriod }; - _plugin = new MergePlugin(); - - _consensusPlugin = new(); + _plugin = new MergePlugin(_mergeConfig, _context.ChainSpec); + _consensusPlugin = new(_context.ChainSpec); } [TearDown] diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 81b83425ace..d7b2dab3a7d 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -34,6 +34,7 @@ using Nethermind.Merge.Plugin.Handlers; using Nethermind.Merge.Plugin.InvalidChainTracker; using Nethermind.Merge.Plugin.Synchronization; +using Nethermind.Specs.ChainSpecStyle; using Nethermind.Synchronization; using Nethermind.Synchronization.Blocks; using Nethermind.Synchronization.ParallelSync; @@ -41,11 +42,10 @@ namespace Nethermind.Merge.Plugin; -public partial class MergePlugin : IConsensusWrapperPlugin, ISynchronizationPlugin +public partial class MergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : IConsensusWrapperPlugin, ISynchronizationPlugin { protected INethermindApi _api = null!; private ILogger _logger; - protected IMergeConfig _mergeConfig = null!; private ISyncConfig _syncConfig = null!; protected IBlocksConfig _blocksConfig = null!; protected ITxPoolConfig _txPoolConfig = null!; @@ -63,22 +63,19 @@ public partial class MergePlugin : IConsensusWrapperPlugin, ISynchronizationPlug public virtual string Description => "Merge plugin for ETH1-ETH2"; public string Author => "Nethermind"; - protected virtual bool MergeEnabled => _mergeConfig.Enabled && - _api.ChainSpec.SealEngineType is SealEngineType.BeaconChain or SealEngineType.Clique or SealEngineType.Ethash; - public int Priority => PluginPriorities.Merge; + protected virtual bool MergeEnabled => PluginEnabled; + public virtual bool PluginEnabled => mergeConfig.Enabled && chainSpec.SealEngineType is SealEngineType.BeaconChain or SealEngineType.Clique or SealEngineType.Ethash; - // Don't remove default constructor. It is used by reflection when we're loading plugins - public MergePlugin() { } + public int Priority => PluginPriorities.Merge; public virtual Task Init(INethermindApi nethermindApi) { _api = nethermindApi; - _mergeConfig = nethermindApi.Config(); _syncConfig = nethermindApi.Config(); _blocksConfig = nethermindApi.Config(); _txPoolConfig = nethermindApi.Config(); - MigrateSecondsPerSlot(_blocksConfig, _mergeConfig); + MigrateSecondsPerSlot(_blocksConfig, mergeConfig); _logger = _api.LogManager.GetClassLogger(); @@ -97,7 +94,7 @@ public virtual Task Init(INethermindApi nethermindApi) _blockCacheService = new BlockCacheService(); _poSSwitcher = new PoSSwitcher( - _mergeConfig, + mergeConfig, _syncConfig, _api.DbProvider.GetDb(DbNames.Metadata), _api.BlockTree, @@ -135,7 +132,7 @@ public virtual Task Init(INethermindApi nethermindApi) private void EnsureNotConflictingSettings() { - if (!_mergeConfig.Enabled && _mergeConfig.TerminalTotalDifficulty is not null) + if (!mergeConfig.Enabled && mergeConfig.TerminalTotalDifficulty is not null) { throw new InvalidConfigurationException( $"{nameof(MergeConfig)}.{nameof(MergeConfig.TerminalTotalDifficulty)} cannot be set when {nameof(MergeConfig)}.{nameof(MergeConfig.Enabled)} is false.", @@ -229,7 +226,7 @@ private void EnsureEngineModuleIsConfigured() private bool HasTtd() { - return _api.SpecProvider?.TerminalTotalDifficulty is not null || _mergeConfig.TerminalTotalDifficulty is not null; + return _api.SpecProvider?.TerminalTotalDifficulty is not null || mergeConfig.TerminalTotalDifficulty is not null; } public Task InitNetworkProtocol() @@ -308,13 +305,13 @@ public Task InitRpcModules() IBlockImprovementContextFactory CreateBlockImprovementContextFactory() { - if (string.IsNullOrEmpty(_mergeConfig.BuilderRelayUrl)) + if (string.IsNullOrEmpty(mergeConfig.BuilderRelayUrl)) { return new BlockImprovementContextFactory(_api.BlockProducer!, TimeSpan.FromSeconds(_blocksConfig.SecondsPerSlot)); } DefaultHttpClient httpClient = new(new HttpClient(), _api.EthereumJsonSerializer, _api.LogManager, retryDelayMilliseconds: 100); - IBoostRelay boostRelay = new BoostRelay(httpClient, _mergeConfig.BuilderRelayUrl); + IBoostRelay boostRelay = new BoostRelay(httpClient, mergeConfig.BuilderRelayUrl); return new BoostBlockImprovementContextFactory(_api.BlockProducer!, TimeSpan.FromSeconds(_blocksConfig.SecondsPerSlot), boostRelay, _api.StateReader); } @@ -346,7 +343,7 @@ IBlockImprovementContextFactory CreateBlockImprovementContextFactory() _invalidChainTracker, _beaconSync, _api.LogManager, - TimeSpan.FromSeconds(_mergeConfig.NewPayloadTimeout), + TimeSpan.FromSeconds(mergeConfig.NewPayloadTimeout), _api.Config().StoreReceipts), new ForkchoiceUpdatedHandler( _api.BlockTree, @@ -372,7 +369,7 @@ IBlockImprovementContextFactory CreateBlockImprovementContextFactory() new ExchangeCapabilitiesHandler(_api.RpcCapabilitiesProvider, _api.LogManager), new GetBlobsHandler(_api.TxPool), _api.SpecProvider, - new GCKeeper(new NoSyncGcRegionStrategy(_api.SyncModeSelector, _mergeConfig), _api.LogManager), + new GCKeeper(new NoSyncGcRegionStrategy(_api.SyncModeSelector, mergeConfig), _api.LogManager), _api.LogManager); RegisterEngineRpcModule(engineRpcModule); @@ -445,10 +442,10 @@ public Task InitSynchronization() ContainerBuilder builder = new ContainerBuilder(); _api.ConfigureContainerBuilderFromApiWithNetwork(builder) - .AddSingleton(_beaconSync) - .AddSingleton(_beaconPivot) - .AddSingleton(_mergeConfig) - .AddSingleton(_invalidChainTracker); + .AddInstance(_beaconSync) + .AddInstance(_beaconPivot) + .AddInstance(mergeConfig) + .AddInstance(_invalidChainTracker); builder.RegisterModule(new SynchronizerModule(_syncConfig)); builder.RegisterModule(new MergeSynchronizerModule()); diff --git a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs index 8e1e8f4002d..7f6b21b893a 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using Autofac; using Nethermind.Api; using Nethermind.Config; using Nethermind.Logging; @@ -12,11 +13,7 @@ namespace Nethermind.Optimism; public class OptimismNethermindApi : NethermindApi { - public OptimismNethermindApi( - IConfigProvider configProvider, - IJsonSerializer jsonSerializer, - ILogManager logManager, - ChainSpec chainSpec) : base(configProvider, jsonSerializer, logManager, chainSpec) + public OptimismNethermindApi(ILifetimeScope lifetimeScope) : base(lifetimeScope) { } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 76633fbf876..0a8909be67c 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -26,6 +26,7 @@ using Nethermind.Core; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.HealthChecks; +using Nethermind.Init.Steps; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Serialization.Rlp; @@ -34,7 +35,7 @@ namespace Nethermind.Optimism; -public class OptimismPlugin : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin +public class OptimismPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin { public string Author => "Nethermind"; public string Name => "Optimism"; @@ -52,14 +53,21 @@ public class OptimismPlugin : IConsensusPlugin, ISynchronizationPlugin, IInitial private IBeaconPivot? _beaconPivot; private BeaconSync? _beaconSync; - public bool ShouldRunSteps(INethermindApi api) => api.ChainSpec.SealEngineType == SealEngineType; - #region IConsensusPlugin public string SealEngineType => Core.SealEngineType.Optimism; public IBlockProductionTrigger DefaultBlockProductionTrigger => NeverProduceTrigger.Instance; + public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + + public void ConfigureContainer(ContainerBuilder builder) + { + builder + .AddSingleton() + .AddIStepsFromAssembly(GetType().Assembly); + } + public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) { if (additionalTxSource is not null) @@ -74,13 +82,9 @@ public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) #endregion - public INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, - ILogManager logManager, ChainSpec chainSpec) => - new OptimismNethermindApi(configProvider, jsonSerializer, logManager, chainSpec); - public void InitTxTypesAndRlpDecoders(INethermindApi api) { - if (ShouldRunSteps(api)) + if (PluginEnabled) { api.RegisterTxType(new OptimismTxDecoder(), Always.Valid); Rlp.RegisterDecoders(typeof(OptimismReceiptMessageDecoder).Assembly, true); @@ -89,7 +93,7 @@ public void InitTxTypesAndRlpDecoders(INethermindApi api) public Task Init(INethermindApi api) { - if (!ShouldRunSteps(api)) + if (!PluginEnabled) return Task.CompletedTask; _api = (OptimismNethermindApi)api; @@ -127,7 +131,7 @@ public Task Init(INethermindApi api) public Task InitSynchronization() { - if (_api is null || !ShouldRunSteps(_api)) + if (_api is null || !PluginEnabled) return Task.CompletedTask; ArgumentNullException.ThrowIfNull(_api.SpecProvider); @@ -154,11 +158,11 @@ public Task InitSynchronization() ContainerBuilder builder = new ContainerBuilder(); ((INethermindApi)_api).ConfigureContainerBuilderFromApiWithNetwork(builder) - .AddSingleton(_beaconSync) - .AddSingleton(_beaconPivot) - .AddSingleton(_api.PoSSwitcher) - .AddSingleton(_mergeConfig) - .AddSingleton(_invalidChainTracker); + .AddInstance(_beaconSync) + .AddInstance(_beaconPivot) + .AddInstance(_api.PoSSwitcher) + .AddInstance(_mergeConfig) + .AddInstance(_invalidChainTracker); builder.RegisterModule(new SynchronizerModule(_syncConfig)); builder.RegisterModule(new MergeSynchronizerModule()); @@ -183,7 +187,7 @@ public Task InitSynchronization() public async Task InitRpcModules() { - if (_api is null || !ShouldRunSteps(_api)) + if (_api is null || !PluginEnabled) return; ArgumentNullException.ThrowIfNull(_api.SpecProvider); diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 9b0a4f49d77..a467a28ff91 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -1,12 +1,13 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +#nullable enable +using System; using System.IO.Abstractions; using Autofac; using Nethermind.Api; using Nethermind.Blockchain; using Nethermind.Blockchain.Filters; -using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Services; using Nethermind.Config; @@ -43,94 +44,106 @@ using Nethermind.Wallet; using Nethermind.Sockets; using Nethermind.Specs; -using Nethermind.Synchronization.SnapSync; using Nethermind.Trie; using NSubstitute; using Nethermind.Blockchain.Blocks; using Nethermind.Core; using Nethermind.Facade.Find; +using Nethermind.Runner.Modules; namespace Nethermind.Runner.Test.Ethereum { public static class Build { - public static NethermindApi ContextWithMocks() + public static NethermindApi ContextWithMocks(Action? containerConfigurer = null) { - var api = new NethermindApi(Substitute.For(), Substitute.For(), LimboLogs.Instance, - new ChainSpec()) - { - Enode = Substitute.For(), - TxPool = Substitute.For(), - Wallet = Substitute.For(), - BlockTree = Substitute.For(), - SyncServer = Substitute.For(), - DbProvider = TestMemDbProvider.Init(), - PeerManager = Substitute.For(), - PeerPool = Substitute.For(), - SpecProvider = Substitute.For(), - EthereumEcdsa = Substitute.For(), - MainBlockProcessor = Substitute.For(), - ReceiptStorage = Substitute.For(), - ReceiptFinder = Substitute.For(), - BlockValidator = Substitute.For(), - RewardCalculatorSource = Substitute.For(), - TxPoolInfoProvider = Substitute.For(), - StaticNodesManager = Substitute.For(), - BloomStorage = Substitute.For(), - Sealer = Substitute.For(), - BlockchainProcessor = Substitute.For(), - BlockProducer = Substitute.For(), - DiscoveryApp = Substitute.For(), - EngineSigner = Substitute.For(), - FileSystem = Substitute.For(), - FilterManager = Substitute.For(), - FilterStore = Substitute.For(), - GrpcServer = Substitute.For(), - HeaderValidator = Substitute.For(), - IpResolver = Substitute.For(), - KeyStore = Substitute.For(), - LogFinder = Substitute.For(), - MonitoringService = Substitute.For(), - ProtocolsManager = Substitute.For(), - ProtocolValidator = Substitute.For(), - RlpxPeer = Substitute.For(), - SealValidator = Substitute.For(), - SessionMonitor = Substitute.For(), - WorldState = Substitute.For(), - StateReader = Substitute.For(), - TransactionProcessor = Substitute.For(), - TxSender = Substitute.For(), - BlockProcessingQueue = Substitute.For(), - EngineSignerStore = Substitute.For(), - NodeStatsManager = Substitute.For(), - RpcModuleProvider = Substitute.For(), - SyncPeerPool = Substitute.For(), - PeerDifficultyRefreshPool = Substitute.For(), - WebSocketsManager = Substitute.For(), - ChainLevelInfoRepository = Substitute.For(), - TrieStore = Substitute.For(), - BlockProducerEnvFactory = Substitute.For(), - TransactionComparerProvider = Substitute.For(), - GasPriceOracle = Substitute.For(), - EthSyncingInfo = Substitute.For(), - HealthHintService = Substitute.For(), - TxValidator = new TxValidator(MainnetSpecProvider.Instance.ChainId), - UnclesValidator = Substitute.For(), - BlockProductionPolicy = Substitute.For(), - BetterPeerStrategy = Substitute.For(), - ReceiptMonitor = Substitute.For(), - BadBlocksStore = Substitute.For(), + ContainerBuilder containerBuilder = new ContainerBuilder() + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(LimboLogs.Instance) + .AddSingleton() + .AddModule(new BaseModule()) + .AddModule(new CoreModule()) + .AddModule(new RunnerModule()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()); // need more complete chainspec to use ISpecProvider - ApiWithNetworkServiceContainer = new ContainerBuilder() - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .Build(), - }; + containerConfigurer?.Invoke(containerBuilder); + + IContainer container = containerBuilder.Build(); + + var api = container.Resolve(); + api.Enode = Substitute.For(); + api.TxPool = Substitute.For(); + api.Wallet = Substitute.For(); + api.BlockTree = Substitute.For(); + api.SyncServer = Substitute.For(); + api.DbProvider = TestMemDbProvider.Init(); + api.PeerManager = Substitute.For(); + api.PeerPool = Substitute.For(); + api.EthereumEcdsa = Substitute.For(); + api.MainBlockProcessor = Substitute.For(); + api.ReceiptStorage = Substitute.For(); + api.ReceiptFinder = Substitute.For(); + api.BlockValidator = Substitute.For(); + api.RewardCalculatorSource = Substitute.For(); + api.TxPoolInfoProvider = Substitute.For(); + api.StaticNodesManager = Substitute.For(); + api.BloomStorage = Substitute.For(); + api.Sealer = Substitute.For(); + api.BlockchainProcessor = Substitute.For(); + api.BlockProducer = Substitute.For(); + api.DiscoveryApp = Substitute.For(); + api.EngineSigner = Substitute.For(); + api.FileSystem = Substitute.For(); + api.FilterManager = Substitute.For(); + api.FilterStore = Substitute.For(); + api.GrpcServer = Substitute.For(); + api.HeaderValidator = Substitute.For(); + api.IpResolver = Substitute.For(); + api.KeyStore = Substitute.For(); + api.LogFinder = Substitute.For(); + api.MonitoringService = Substitute.For(); + api.ProtocolsManager = Substitute.For(); + api.ProtocolValidator = Substitute.For(); + api.RlpxPeer = Substitute.For(); + api.SealValidator = Substitute.For(); + api.SessionMonitor = Substitute.For(); + api.WorldState = Substitute.For(); + api.StateReader = Substitute.For(); + api.TransactionProcessor = Substitute.For(); + api.TxSender = Substitute.For(); + api.BlockProcessingQueue = Substitute.For(); + api.EngineSignerStore = Substitute.For(); + api.NodeStatsManager = Substitute.For(); + api.RpcModuleProvider = Substitute.For(); + api.SyncPeerPool = Substitute.For(); + api.PeerDifficultyRefreshPool = Substitute.For(); + api.WebSocketsManager = Substitute.For(); + api.ChainLevelInfoRepository = Substitute.For(); + api.TrieStore = Substitute.For(); + api.BlockProducerEnvFactory = Substitute.For(); + api.TransactionComparerProvider = Substitute.For(); + api.GasPriceOracle = Substitute.For(); + api.EthSyncingInfo = Substitute.For(); + api.HealthHintService = Substitute.For(); + api.TxValidator = new TxValidator(MainnetSpecProvider.Instance.ChainId); + api.UnclesValidator = Substitute.For(); + api.BlockProductionPolicy = Substitute.For(); + api.BetterPeerStrategy = Substitute.For(); + api.ReceiptMonitor = Substitute.For(); + api.BadBlocksStore = Substitute.For(); + + api.ApiWithNetworkServiceContainer = new ContainerBuilder() + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .Build(); api.WorldStateManager = new ReadOnlyWorldStateManager(api.DbProvider, Substitute.For(), LimboLogs.Instance); api.NodeStorageFactory = new NodeStorageFactory(INodeStorage.KeyScheme.HalfPath, LimboLogs.Instance); - return api; + + return (NethermindApi)api; } } } diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs index 1a058d86cfa..793327cb84c 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs @@ -4,15 +4,14 @@ using System; using System.Threading; using System.Threading.Tasks; +using Autofac; +using Autofac.Core; using FluentAssertions; using FluentAssertions.Execution; using Nethermind.Api; -using Nethermind.Config; -using Nethermind.Consensus.AuRa.InitializationSteps; using Nethermind.Init.Steps; using Nethermind.Logging; -using Nethermind.Serialization.Json; -using Nethermind.Specs.ChainSpecStyle; +using Nethermind.Runner.Modules; using NUnit.Framework; namespace Nethermind.Runner.Test.Ethereum.Steps @@ -20,31 +19,11 @@ namespace Nethermind.Runner.Test.Ethereum.Steps [TestFixture, Parallelizable(ParallelScope.All)] public class EthereumStepsManagerTests { - [Test] - public async Task When_no_assemblies_defined() - { - NethermindApi runnerContext = CreateNethermindApi(); - - IEthereumStepsLoader stepsLoader = new EthereumStepsLoader(); - EthereumStepsManager stepsManager = new EthereumStepsManager( - stepsLoader, - runnerContext, - LimboLogs.Instance); - - using CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromSeconds(1)); - await stepsManager.InitializeAll(source.Token); - } - [Test] public async Task With_steps_from_here() { - NethermindApi runnerContext = CreateNethermindApi(); - - IEthereumStepsLoader stepsLoader = new EthereumStepsLoader(GetType().Assembly); - EthereumStepsManager stepsManager = new EthereumStepsManager( - stepsLoader, - runnerContext, - LimboLogs.Instance); + IContainer runnerContext = CreateNethermindApi(); + EthereumStepsManager stepsManager = runnerContext.Resolve(); using CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromSeconds(1)); @@ -65,13 +44,8 @@ public async Task With_steps_from_here() [Retry(3)] public async Task With_steps_from_here_AuRa() { - AuRaNethermindApi runnerContext = CreateAuraApi(); - - IEthereumStepsLoader stepsLoader = new EthereumStepsLoader(GetType().Assembly); - EthereumStepsManager stepsManager = new EthereumStepsManager( - stepsLoader, - runnerContext, - LimboLogs.Instance); + IContainer runnerContext = CreateAuraApi(); + EthereumStepsManager stepsManager = runnerContext.Resolve(); using CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromSeconds(5)); @@ -88,13 +62,8 @@ public async Task With_steps_from_here_AuRa() [Test] public async Task With_failing_steps() { - NethermindApi runnerContext = CreateNethermindApi(); - - IEthereumStepsLoader stepsLoader = new EthereumStepsLoader(GetType().Assembly); - EthereumStepsManager stepsManager = new EthereumStepsManager( - stepsLoader, - runnerContext, - LimboLogs.Instance); + IContainer runnerContext = CreateNethermindApi(); + EthereumStepsManager stepsManager = runnerContext.Resolve(); using CancellationTokenSource source = new CancellationTokenSource(TimeSpan.FromSeconds(2)); @@ -111,10 +80,41 @@ public async Task With_failing_steps() } } - private static NethermindApi CreateNethermindApi() => - new(new ConfigProvider(), new EthereumJsonSerializer(), LimboLogs.Instance, new ChainSpec()); - private static AuRaNethermindApi CreateAuraApi() => - new(new ConfigProvider(), new EthereumJsonSerializer(), LimboLogs.Instance, new ChainSpec()); + private static ContainerBuilder CreateBaseContainerBuilder() + { + var builder = new ContainerBuilder(); + builder.RegisterInstance(LimboLogs.Instance).AsImplementedInterfaces(); + builder.RegisterModule(new BaseModule()); + builder.RegisterModule(new RunnerModule()); + return builder; + } + + private static IContainer CreateEmptyContainer() + { + return CreateBaseContainerBuilder() + .Build(); + } + + private static IContainer CreateNethermindApi() + { + ContainerBuilder builder = CreateBaseContainerBuilder(); + builder.AddIStep(typeof(StepLong)); + builder.AddIStep(typeof(StepForever)); + builder.AddIStep(typeof(StepA)); + builder.AddIStep(typeof(StepB)); + builder.AddIStep(typeof(StepCStandard)); + return builder.Build(); + } + private static IContainer CreateAuraApi() + { + ContainerBuilder builder = CreateBaseContainerBuilder(); + builder.AddIStep(typeof(StepLong)); + builder.AddIStep(typeof(StepForever)); + builder.AddIStep(typeof(StepA)); + builder.AddIStep(typeof(StepB)); + builder.AddIStep(typeof(StepCAuRa)); + return builder.Build(); + } } public class StepLong : IStep @@ -187,7 +187,7 @@ public virtual Task Execute(CancellationToken cancellationToken) /// public class StepCAuRa : StepC { - public StepCAuRa(AuRaNethermindApi runnerContext) + public StepCAuRa() { } @@ -199,7 +199,7 @@ public override async Task Execute(CancellationToken cancellationToken) public class StepCStandard : StepC { - public StepCStandard(NethermindApi runnerContext) + public StepCStandard() { } } diff --git a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs index 2b2c1afbcf9..11054575346 100644 --- a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs @@ -10,6 +10,7 @@ using System.Runtime.Loader; using System.Threading; using System.Threading.Tasks; +using Autofac; using Nethermind.Api; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; @@ -25,6 +26,7 @@ using Nethermind.Db.Blooms; using Nethermind.Runner.Ethereum.Api; using Nethermind.TxPool; +using NSubstitute; using NUnit.Framework; namespace Nethermind.Runner.Test; @@ -128,9 +130,9 @@ private static async Task SmokeTest(ConfigProvider configProvider, int testIndex networkConfig.P2PPort = port; networkConfig.DiscoveryPort = port; - INethermindApi nethermindApi = new ApiBuilder(configProvider, LimboLogs.Instance).Create(); - nethermindApi.RpcModuleProvider = new RpcModuleProvider(new FileSystem(), new JsonRpcConfig(), LimboLogs.Instance); - EthereumRunner runner = new(nethermindApi); + IContainer container = new ApiBuilder(configProvider, Substitute.For(), LimboLogs.Instance).Create(Array.Empty()); + container.Resolve().RpcModuleProvider = new RpcModuleProvider(new FileSystem(), new JsonRpcConfig(), LimboLogs.Instance); + EthereumRunner runner = container.Resolve(); using CancellationTokenSource cts = new(); diff --git a/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs b/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs new file mode 100644 index 00000000000..802f8a5a239 --- /dev/null +++ b/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Autofac; +using FluentAssertions; +using Nethermind.Api; +using Nethermind.Config; +using Nethermind.Logging; +using Nethermind.Runner.Modules; +using Nethermind.Serialization.Json; +using Nethermind.Specs.ChainSpecStyle; +using NSubstitute; +using NUnit.Framework; + +namespace Nethermind.Runner.Test.Modules; + +public class BaseModuleTests +{ + [Test] + public void Can_Resolve() + { + IConfigProvider configProvider = Substitute.For(); + IProcessExitSource processExitSource = Substitute.For(); + ChainSpec chainSpec = new(); + IJsonSerializer jsonSerializer = new EthereumJsonSerializer(); + ILogManager logManager = Substitute.For(); + + configProvider.GetConfig().Returns(new InitConfig()); + logManager.GetClassLogger(typeof(TestClass)).Returns(LimboLogs.Instance.GetClassLogger()); + + ContainerBuilder builder = new ContainerBuilder(); + builder.RegisterInstance(configProvider); + builder.RegisterInstance(processExitSource); + builder.RegisterInstance(chainSpec); + builder.RegisterInstance(jsonSerializer); + builder.RegisterInstance(logManager); + builder.RegisterModule(new BaseModule()); + + using IContainer container = builder.Build(); + + TestClass testObj = container.Resolve(); + testObj.Logger.Should().NotBeNull(); + testObj.InitConfig.Should().NotBeNull(); + } + + private class TestClass + { + public IInitConfig InitConfig; + public ILogger Logger; + + public TestClass(IInitConfig initConfig, ILogger logger) + { + InitConfig = initConfig; + Logger = logger; + } + } +} diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 9d17ac28787..cc2e392f9b9 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading; +using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Config; @@ -13,6 +14,7 @@ using Nethermind.Core; using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Logging; +using Nethermind.Runner.Modules; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; @@ -23,22 +25,21 @@ public class ApiBuilder private readonly IConfigProvider _configProvider; private readonly IJsonSerializer _jsonSerializer; private readonly ILogManager _logManager; - private readonly Nethermind.Logging.ILogger _logger; + private readonly ILogger _logger; + private readonly IProcessExitSource _processExitSource; private readonly IInitConfig _initConfig; - public ApiBuilder(IConfigProvider configProvider, ILogManager logManager) + public ApiBuilder(IConfigProvider configProvider, IProcessExitSource processExitSource, ILogManager logManager) { _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); _logger = _logManager.GetClassLogger(); _configProvider = configProvider ?? throw new ArgumentNullException(nameof(configProvider)); _initConfig = configProvider.GetConfig(); + _processExitSource = processExitSource; _jsonSerializer = new EthereumJsonSerializer(); } - public INethermindApi Create(params IConsensusPlugin[] consensusPlugins) => - Create((IEnumerable)consensusPlugins); - - public INethermindApi Create(IEnumerable consensusPlugins) + public IContainer Create(IEnumerable plugins) { ChainSpec chainSpec = LoadChainSpec(_jsonSerializer); bool wasCreated = Interlocked.CompareExchange(ref _apiCreated, 1, 0) == 1; @@ -47,19 +48,52 @@ public INethermindApi Create(IEnumerable consensusPlugins) throw new NotSupportedException("Creation of multiple APIs not supported."); } - string engine = chainSpec.SealEngineType; - IConsensusPlugin? enginePlugin = consensusPlugins.FirstOrDefault(p => p.SealEngineType == engine); + ContainerBuilder containerBuilder = new ContainerBuilder(); + containerBuilder.RegisterInstance(_configProvider).SingleInstance(); + containerBuilder.RegisterInstance(_processExitSource).SingleInstance(); + containerBuilder.RegisterInstance(_jsonSerializer).SingleInstance(); + containerBuilder.RegisterInstance(_logManager).SingleInstance(); + containerBuilder.RegisterInstance(chainSpec).SingleInstance(); - INethermindApi nethermindApi = - enginePlugin?.CreateApi(_configProvider, _jsonSerializer, _logManager, chainSpec) ?? - new NethermindApi(_configProvider, _jsonSerializer, _logManager, chainSpec); - nethermindApi.SealEngineType = engine; - nethermindApi.SpecProvider = new ChainSpecBasedSpecProvider(chainSpec, _logManager); - nethermindApi.GasLimitCalculator = new FollowOtherMiners(nethermindApi.SpecProvider); + containerBuilder.RegisterModule(new BaseModule()); + containerBuilder.RegisterModule(new CoreModule()); + containerBuilder.RegisterModule(new RunnerModule()); + ApplyPluginModule(plugins, chainSpec, containerBuilder); - SetLoggerVariables(chainSpec); + return containerBuilder.Build(); + } - return nethermindApi; + private void ApplyPluginModule(IEnumerable plugins, ChainSpec chainSpec, ContainerBuilder containerBuilder) + { + ContainerBuilder pluginLoaderBuilder = new ContainerBuilder(); + pluginLoaderBuilder.RegisterInstance(_configProvider).SingleInstance(); + pluginLoaderBuilder.RegisterInstance(_processExitSource).SingleInstance(); + pluginLoaderBuilder.RegisterInstance(_jsonSerializer).SingleInstance(); + pluginLoaderBuilder.RegisterInstance(_logManager).SingleInstance(); + pluginLoaderBuilder.RegisterInstance(chainSpec).SingleInstance(); + pluginLoaderBuilder.RegisterModule(new BaseModule()); + foreach (Type plugin in plugins) + { + pluginLoaderBuilder.RegisterType(plugin) + .As() + .ExternallyOwned(); + } + + // This is just to load the plugins in a way that its constructor injectable with related config. + // The plugins need to have enough information in order for it to know that it should enable itself or not. + using IContainer pluginLoader = pluginLoaderBuilder.Build(); + + foreach (INethermindPlugin nethermindPlugin in pluginLoader.Resolve>()) + { + if (_logger.IsDebug) _logger.Warn($"Plugin {nethermindPlugin.Name} enabled: {nethermindPlugin.PluginEnabled}"); + if (!nethermindPlugin.PluginEnabled) + { + continue; + } + + containerBuilder.RegisterInstance(nethermindPlugin).As(); + nethermindPlugin.ConfigureContainer(containerBuilder); + } } private int _apiCreated; @@ -81,6 +115,7 @@ private ChainSpec LoadChainSpec(IJsonSerializer ethereumJsonSerializer) IChainSpecLoader loader = new ChainSpecLoader(ethereumJsonSerializer); ChainSpec chainSpec = loader.LoadEmbeddedOrFromFile(chainSpecFile, _logger); + SetLoggerVariables(chainSpec); return chainSpec; } diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/EthereumRunner.cs b/src/Nethermind/Nethermind.Runner/Ethereum/EthereumRunner.cs index 5e79b03e1cb..6c88d0731a0 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/EthereumRunner.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/EthereumRunner.cs @@ -2,13 +2,9 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Nethermind.Api; -using Nethermind.Api.Extensions; using Nethermind.Core; using Nethermind.Init.Steps; using Nethermind.Logging; @@ -18,40 +14,26 @@ namespace Nethermind.Runner.Ethereum public class EthereumRunner { private readonly INethermindApi _api; - private readonly ILogger _logger; + private readonly EthereumStepsManager _stepManager; - public EthereumRunner(INethermindApi api) + public EthereumRunner(INethermindApi api, EthereumStepsManager stepsManager, ILogger logger) { _api = api; - _logger = api.LogManager.GetClassLogger(); + _stepManager = stepsManager; + _logger = logger; } public async Task Start(CancellationToken cancellationToken) { if (_logger.IsDebug) _logger.Debug("Initializing Ethereum"); - EthereumStepsLoader stepsLoader = new EthereumStepsLoader(GetStepsAssemblies(_api)); - EthereumStepsManager stepsManager = new EthereumStepsManager(stepsLoader, _api, _api.LogManager); - await stepsManager.InitializeAll(cancellationToken); + await _stepManager.InitializeAll(cancellationToken); string infoScreen = ThisNodeInfo.BuildNodeInfoScreen(); if (_logger.IsInfo) _logger.Info(infoScreen); } - private IEnumerable GetStepsAssemblies(INethermindApi api) - { - yield return typeof(IStep).Assembly; - yield return GetType().Assembly; - IEnumerable enabledInitializationPlugins = - _api.Plugins.OfType().Where(p => p.ShouldRunSteps(api)); - - foreach (IInitializationPlugin initializationPlugin in enabledInitializationPlugins) - { - yield return initializationPlugin.GetType().Assembly; - } - } - public async Task StopAsync() { Stop(() => _api.SessionMonitor?.Stop(), "Stopping session monitor"); @@ -66,11 +48,6 @@ public async Task StopAsync() Task rlpxPeerTask = Stop(() => _api.RlpxPeer?.Shutdown(), "Stopping rlpx peer"); await Task.WhenAll(discoveryStopTask, rlpxPeerTask, peerManagerTask, synchronizerTask, syncPeerPoolTask, peerPoolTask, blockchainProcessorTask, blockProducerTask); - foreach (INethermindPlugin plugin in _api.Plugins) - { - await Stop(async () => await plugin.DisposeAsync(), $"Disposing plugin {plugin.Name}"); - } - while (_api.DisposeStack.Count != 0) { IAsyncDisposable disposable = _api.DisposeStack.Pop(); diff --git a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs new file mode 100644 index 00000000000..8457577328a --- /dev/null +++ b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: 2024 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 Autofac.Core; +using Autofac.Core.Activators.Delegate; +using Autofac.Core.Lifetime; +using Autofac.Core.Registration; +using Autofac.Core.Resolving.Pipeline; +using Autofac.Features.ResolveAnything; +using Nethermind.Api; +using Nethermind.Config; +using Nethermind.Core; +using Nethermind.Core.Specs; +using Nethermind.Core.Timers; +using Nethermind.Crypto; +using Nethermind.Logging; +using Nethermind.Serialization.Json; +using Nethermind.Specs.ChainSpecStyle; +using Module = Autofac.Module; + +namespace Nethermind.Runner.Modules; + +/// +/// Basic common behaviour such as instrumentation and system related stuff. Should be completely compatible in all +/// situation and can be run in tests. +/// +public class BaseModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); + builder.RegisterSource(new ConfigRegistrationSource()); + LoggerMiddleware.Configure(builder); + + builder + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddInstance(TimerFactory.Default) + .AddInstance(Timestamper.Default) + .AddSingleton(); + } + + /// + /// Dynamically resolve IConfig + /// + private class ConfigRegistrationSource : IRegistrationSource + { + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + IServiceWithType swt = service as IServiceWithType; + if (swt == null || !typeof(IConfig).IsAssignableFrom(swt.ServiceType)) + { + // It's not a request for the base handler type, so skip it. + return Enumerable.Empty(); + } + + // Dynamically resolve IConfig + ComponentRegistration registration = new ComponentRegistration( + Guid.NewGuid(), + new DelegateActivator(swt.ServiceType, (c, p) => + { + IConfigProvider configProvider = c.Resolve(); + object config = typeof(IConfigProvider) + .GetMethod("GetConfig") + .MakeGenericMethod(swt.ServiceType) + .Invoke(configProvider, new object[] { }); + return config; + }), + new RootScopeLifetime(), + InstanceSharing.Shared, + InstanceOwnership.OwnedByLifetimeScope, + new[] { service }, + new Dictionary()); + + return new IComponentRegistration[] { registration }; + } + + public bool IsAdapterForIndividualComponents => false; + } + + /// + /// For automatically resolving ILogger + /// + private class LoggerMiddleware : IResolveMiddleware + { + private LoggerMiddleware() + { + } + + public PipelinePhase Phase => PipelinePhase.ParameterSelection; + + public void Execute(ResolveRequestContext context, Action next) + { + // Add our parameters. + context.ChangeParameters(context.Parameters.Union( + new[] + { + new ResolvedParameter( + (p, i) => p.ParameterType == typeof(ILogger), + (p, i) => i.Resolve().GetClassLogger(p.Member.DeclaringType) + ), + })); + + // Continue the resolve. + next(context); + } + + public static void Configure(ContainerBuilder builder) + { + LoggerMiddleware loggerMiddleware = new LoggerMiddleware(); + builder.ComponentRegistryBuilder.Registered += (senter, args) => + { + args.ComponentRegistration.PipelineBuilding += (sender2, pipeline) => + { + pipeline.Use(loggerMiddleware); + }; + }; + } + } + +} diff --git a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs new file mode 100644 index 00000000000..a7307e70eee --- /dev/null +++ b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Autofac; +using Nethermind.Api; +using Nethermind.Consensus; + +namespace Nethermind.Runner.Modules; + +/// +/// CoreModule should be something Nethermind specific +/// +public class CoreModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder.RegisterType() + .As() + .SingleInstance(); + + builder.RegisterType() + .As() + .SingleInstance(); + } +} diff --git a/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs b/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs new file mode 100644 index 00000000000..1cf85195e94 --- /dev/null +++ b/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Autofac; +using Nethermind.Core; +using Nethermind.Init.Steps; +using Nethermind.Runner.Ethereum; + +namespace Nethermind.Runner.Modules; + +public class RunnerModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddIStepsFromAssembly(typeof(IStep).Assembly) + .AddIStepsFromAssembly(GetType().Assembly); + } +} diff --git a/src/Nethermind/Nethermind.Runner/Program.cs b/src/Nethermind/Nethermind.Runner/Program.cs index fef352adc11..064e38ae738 100644 --- a/src/Nethermind/Nethermind.Runner/Program.cs +++ b/src/Nethermind/Nethermind.Runner/Program.cs @@ -14,6 +14,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Autofac; #if !DEBUG using DotNetty.Common; #endif @@ -176,32 +177,13 @@ private static void Run(string[] args) if (_logger.IsDebug) _logger.Debug($"Nethermind config:{Environment.NewLine}{serializer.Serialize(initConfig, true)}{Environment.NewLine}"); if (_logger.IsInfo) _logger.Info($"RocksDb Version: {DbOnTheRocks.GetRocksDbVersion()}"); - ApiBuilder apiBuilder = new(configProvider, logManager); - - IList plugins = new List(); - foreach (Type pluginType in pluginLoader.PluginTypes) - { - try - { - if (Activator.CreateInstance(pluginType) is INethermindPlugin plugin) - { - plugins.Add(plugin); - } - } - catch (Exception e) - { - if (_logger.IsError) _logger.Error($"Failed to create plugin {pluginType.FullName}", e); - } - } - - INethermindApi nethermindApi = apiBuilder.Create(plugins.OfType()); - ((List)nethermindApi.Plugins).AddRange(plugins); - nethermindApi.ProcessExit = _processExitSource; - + ApiBuilder nethermindContainerBuilder = new(configProvider, _processExitSource, logManager); + IContainer container = nethermindContainerBuilder.Create(pluginLoader.PluginTypes); + EthereumRunner ethereumRunner = null; _appClosed.Reset(); - EthereumRunner ethereumRunner = new(nethermindApi); try { + ethereumRunner = container.Resolve(); await ethereumRunner.Start(_processExitSource.Token); await _processExitSource.ExitTask; diff --git a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs index 04b6a444699..77d97e20ee8 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs @@ -16,20 +16,21 @@ using Nethermind.Serialization.Json; using System.Threading; using Nethermind.Config; +using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Shutter; -public class ShutterPlugin : IConsensusWrapperPlugin, IInitializationPlugin +public class ShutterPlugin(IShutterConfig shutterConfig, IMergeConfig mergeConfig, ChainSpec chainSpec) : IConsensusWrapperPlugin, IInitializationPlugin { public string Name => "Shutter"; public string Description => "Shutter plugin for AuRa post-merge chains"; public string Author => "Nethermind"; - public bool Enabled => ShouldRunSteps(_api!); + public bool Enabled => PluginEnabled; + public bool PluginEnabled => shutterConfig!.Enabled && mergeConfig!.Enabled && chainSpec.SealEngineType is SealEngineType.AuRa; + public int Priority => PluginPriorities.Shutter; private INethermindApi? _api; - private IMergeConfig? _mergeConfig; - private IShutterConfig? _shutterConfig; private IBlocksConfig? _blocksConfig; private ShutterApi? _shutterApi; private ILogger _logger; @@ -41,8 +42,6 @@ public Task Init(INethermindApi nethermindApi) { _api = nethermindApi; _blocksConfig = _api.Config(); - _mergeConfig = _api.Config(); - _shutterConfig = _api.Config(); _logger = _api.LogManager.GetClassLogger(); if (_logger.IsInfo) _logger.Info($"Initializing Shutter plugin."); return Task.CompletedTask; @@ -75,7 +74,7 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I try { - _shutterConfig!.Validate(); + shutterConfig!.Validate(); } catch (ArgumentException e) { @@ -83,11 +82,11 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I } Dictionary validatorsInfo = []; - if (_shutterConfig!.ValidatorInfoFile is not null) + if (shutterConfig!.ValidatorInfoFile is not null) { try { - validatorsInfo = LoadValidatorInfo(_shutterConfig!.ValidatorInfoFile); + validatorsInfo = LoadValidatorInfo(shutterConfig!.ValidatorInfoFile); } catch (Exception e) { @@ -105,7 +104,7 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I _api.SpecProvider, _api.Timestamper, _api.WorldStateManager, - _shutterConfig, + shutterConfig, validatorsInfo, TimeSpan.FromSeconds(_blocksConfig!.SecondsPerSlot) ); @@ -116,13 +115,6 @@ public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, I return consensusPlugin.InitBlockProducer(_shutterApi is null ? txSource : _shutterApi.TxSource.Then(txSource)); } - public bool ShouldRunSteps(INethermindApi api) - { - _shutterConfig = api.Config(); - _mergeConfig = api.Config(); - return _shutterConfig!.Enabled && _mergeConfig!.Enabled && api.ChainSpec.SealEngineType is SealEngineType.AuRa; - } - public async ValueTask DisposeAsync() { _cts.Dispose(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index 89bd50a3ca4..c813c1a01a6 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -70,22 +70,22 @@ public async Task Setup() IStateReader stateReader = new StateReader(trieStore, _codeDb, 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); + .AddInstance(nodeStorage) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(_blockTree) + .AddInstance(_receiptStorage) + .AddInstance(_pool) + .AddInstance(stats) + .AddInstance(syncConfig) + .AddInstance(Always.Valid) + .AddInstance(Always.Valid) + .AddInstance(pivot) + .AddInstance(Substitute.For()) + .AddInstance(bestPeerStrategy) + .AddInstance(new ChainSpec()) + .AddInstance(stateReader) + .AddInstance(No.BeaconSync) + .AddInstance(LimboLogs.Instance); dbProvider.ConfigureServiceCollection(builder); builder.RegisterModule(new SynchronizerModule(syncConfig)); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 33e43446a69..a00e043e67d 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -363,24 +363,24 @@ private SyncTestContext CreateSyncManager(int index) 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); + .AddInstance(dbProvider) + .AddInstance(new NodeStorage(dbProvider.StateDb)) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(tree) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(syncPeerPool) + .AddInstance(nodeStatsManager) + .AddInstance(syncConfig) + .AddInstance(blockValidator) + .AddInstance(sealValidator) + .AddInstance(pivot) + .AddInstance(Substitute.For()) + .AddInstance(bestPeerStrategy) + .AddInstance(new ChainSpec()) + .AddInstance(stateReader) + .AddInstance(receiptStorage) + .AddInstance(No.BeaconSync) + .AddInstance(logManager); dbProvider.ConfigureServiceCollection(builder); builder.RegisterModule(new SynchronizerModule(syncConfig)); IContainer container = builder.Build(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index 47c721d274c..361acf116f4 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -348,27 +348,27 @@ ISyncConfig GetSyncConfig() => 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); + .AddInstance(dbProvider) + .AddInstance(nodeStorage) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(BlockTree) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(SyncPeerPool) + .AddInstance(stats) + .AddInstance(syncConfig) + .AddInstance(pivot) + .AddInstance(poSSwitcher) + .AddInstance(mergeConfig) + .AddInstance(invalidChainTracker) + .AddInstance(Substitute.For()) + .AddInstance(bestPeerStrategy) + .AddInstance(new ChainSpec()) + .AddInstance(No.BeaconSync) + .AddInstance(reader) + .AddInstance(Always.Valid) + .AddInstance(Always.Valid) + .AddInstance(beaconPivot) + .AddInstance(_logManager); builder.RegisterModule(new SynchronizerModule(syncConfig)); diff --git a/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs b/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs index ea06514e3af..af9e6015923 100644 --- a/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs +++ b/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs @@ -9,7 +9,7 @@ namespace Nethermind.UPnP.Plugin; -public class UPnPPlugin : INethermindPlugin +public class UPnPPlugin(INetworkConfig networkConfig) : INethermindPlugin { public string Name => "UPnP"; public string Description => "Automatic port forwarding with UPnP"; @@ -22,12 +22,14 @@ public class UPnPPlugin : INethermindPlugin private INetworkConfig _networkConfig = new NetworkConfig(); private ILogger _logger = NullLogger.Instance; + public bool PluginEnabled => networkConfig.EnableUPnP; + public Task Init(INethermindApi api) { _networkConfig = api.Config(); _logger = api.LogManager.GetClassLogger(); - if (_networkConfig.EnableUPnP) + if (PluginEnabled) { Task.Factory.StartNew(RunRefreshLoop, TaskCreationOptions.LongRunning); } From 618e4886b7fca935f5e431c16cbd8a2924edf070 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 12:27:32 +0800 Subject: [PATCH 06/25] Rename PluginEnabled to Enabled and use Module instead --- .../Nethermind.Analytics/AnalyticsPlugin.cs | 8 ++--- .../Nethermind.Api.Test/TestPlugin.cs | 2 +- .../Nethermind.Api.Test/TestPlugin2.cs | 2 +- .../Extensions/IConsensusWrapperPlugin.cs | 2 +- .../Extensions/INethermindPlugin.cs | 5 ++-- src/Nethermind/Nethermind.Api/IBasicApi.cs | 2 +- .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 8 ++--- .../CliquePlugin.cs | 2 +- .../EthashPlugin.cs | 2 +- .../NethDevPlugin.cs | 2 +- .../Nethermind.EthStats/EthStatsPlugin.cs | 2 +- .../ClefSignerPlugin.cs | 2 +- .../HealthChecksPlugin.cs | 2 +- src/Nethermind/Nethermind.Hive/HivePlugin.cs | 4 +-- .../SnapshotPlugin.cs | 17 +++++++---- .../TraceStorePlugin.cs | 10 +++---- .../Nethermind.Merge.AuRa/AuRaMergePlugin.cs | 20 ++++++++----- .../MergePlugin.BlockProducer.cs | 2 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 4 +-- .../Nethermind.Optimism/OptimismPlugin.cs | 30 +++++++++++-------- .../Ethereum/Api/ApiBuilder.cs | 12 +++++--- .../Nethermind.Runner/Modules/BaseModule.cs | 2 ++ .../Nethermind.Shutter/ShutterPlugin.cs | 8 ++--- .../Nethermind.UPnP.Plugin/UPnPPlugin.cs | 4 +-- 24 files changed, 89 insertions(+), 65 deletions(-) diff --git a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs index aa02becc61b..71df7df3ce1 100644 --- a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs +++ b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs @@ -26,7 +26,7 @@ public class AnalyticsPlugin(IAnalyticsConfig analyticsConfig, IInitConfig initC public string Author => "Nethermind"; - public bool PluginEnabled =>initConfig.WebSocketsEnabled && + public bool Enabled =>initConfig.WebSocketsEnabled && (analyticsConfig.PluginsEnabled || analyticsConfig.StreamBlocks || analyticsConfig.StreamTransactions); @@ -38,7 +38,7 @@ public Task Init(INethermindApi api) IInitConfig initConfig = getFromAPi.Config(); - if (!PluginEnabled) + if (!Enabled) { if (!initConfig.WebSocketsEnabled) { @@ -68,12 +68,12 @@ private void TxPoolOnNewDiscovered(object sender, TxEventArgs e) public Task InitNetworkProtocol() { var (getFromAPi, _) = _api.ForNetwork; - if (PluginEnabled) + if (Enabled) { getFromAPi.TxPool!.NewDiscovered += TxPoolOnNewDiscovered; } - if (PluginEnabled) + if (Enabled) { AnalyticsWebSocketsModule webSocketsModule = new(getFromAPi.EthereumJsonSerializer, getFromAPi.LogManager); getFromAPi.WebSocketsManager!.AddModule(webSocketsModule, true); diff --git a/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs b/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs index b51185fc6ff..60b5375a548 100644 --- a/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs +++ b/src/Nethermind/Nethermind.Api.Test/TestPlugin.cs @@ -31,6 +31,6 @@ public Task InitRpcModules() throw new System.NotImplementedException(); } - public bool PluginEnabled => true; + public bool Enabled => true; } } diff --git a/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs b/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs index 570ee4b8d57..e84df3677c5 100644 --- a/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs +++ b/src/Nethermind/Nethermind.Api.Test/TestPlugin2.cs @@ -31,6 +31,6 @@ public Task InitRpcModules() throw new System.NotImplementedException(); } - public bool PluginEnabled => true; + public bool Enabled => true; } } diff --git a/src/Nethermind/Nethermind.Api/Extensions/IConsensusWrapperPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IConsensusWrapperPlugin.cs index becb062362d..1654ca3ea46 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/IConsensusWrapperPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/IConsensusWrapperPlugin.cs @@ -17,6 +17,6 @@ public interface IConsensusWrapperPlugin : INethermindPlugin /// int Priority => 0; - bool Enabled { get; } + bool ConsensusWrapperEnabled { get; } } } diff --git a/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs index c6cf0983cd4..d4c67139e6e 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/INethermindPlugin.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using Autofac; +using Autofac.Core; namespace Nethermind.Api.Extensions; @@ -25,6 +26,6 @@ void InitTxTypesAndRlpDecoders(INethermindApi api) { } bool MustInitialize => false; - bool PluginEnabled { get; } - void ConfigureContainer(ContainerBuilder builder) {} + bool Enabled { get; } + IModule? ContainerModule => null; } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index ffd0f158250..2aedf60621f 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -54,7 +54,7 @@ public interface IBasicApi .SingleOrDefault(cp => cp.SealEngineType == SealEngineType); public IEnumerable GetConsensusWrapperPlugins() => - Plugins.OfType().Where(p => p.Enabled); + Plugins.OfType().Where(p => p.ConsensusWrapperEnabled); public IEnumerable GetSynchronizationPlugins() => Plugins.OfType(); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index 0ff09e0d929..452af8377b5 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; using Autofac; +using Autofac.Core; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Config; @@ -33,14 +34,11 @@ public class AuRaPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizatio public string Author => "Nethermind"; public string SealEngineType => Core.SealEngineType.AuRa; - public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public bool Enabled => chainSpec.SealEngineType == SealEngineType; private StartBlockProducerAuRa? _blockProducerStarter; - public void ConfigureContainer(ContainerBuilder builder) - { - builder.RegisterModule(new AuraModule()); - } + public IModule? ContainerModule => new AuraModule(); public ValueTask DisposeAsync() { diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs index 76bc1ef0393..12c46a8ba91 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs @@ -34,7 +34,7 @@ public class CliquePlugin(ChainSpec chainSpec) : IConsensusPlugin public string Author => "Nethermind"; - public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public bool Enabled => chainSpec.SealEngineType == SealEngineType; public Task Init(INethermindApi nethermindApi) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs b/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs index c49e91fc64d..ffbad929907 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/EthashPlugin.cs @@ -23,7 +23,7 @@ public class EthashPlugin(ChainSpec chainSpec) : IConsensusPlugin public string Author => "Nethermind"; - public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public bool Enabled => chainSpec.SealEngineType == SealEngineType; public Task Init(INethermindApi nethermindApi) { diff --git a/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs b/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs index 53ea388044a..5ab25818e4b 100644 --- a/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.Ethash/NethDevPlugin.cs @@ -41,7 +41,7 @@ public Task Init(INethermindApi nethermindApi) return Task.CompletedTask; } - public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; + public bool Enabled => chainSpec.SealEngineType == SealEngineType; public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) { diff --git a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs index 88f4eea3327..1efc571334f 100644 --- a/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs +++ b/src/Nethermind/Nethermind.EthStats/EthStatsPlugin.cs @@ -30,7 +30,7 @@ public class EthStatsPlugin(IEthStatsConfig ethStatsConfig) : INethermindPlugin public string Name => "EthStats"; public string Description => "Ethereum Statistics"; public string Author => "Nethermind"; - public bool PluginEnabled => ethStatsConfig.Enabled; + public bool Enabled => ethStatsConfig.Enabled; public ValueTask DisposeAsync() { diff --git a/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs b/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs index ef60f479bf6..c1f004defc3 100644 --- a/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs +++ b/src/Nethermind/Nethermind.ExternalSigner.Plugin/ClefSignerPlugin.cs @@ -22,7 +22,7 @@ public class ClefSignerPlugin : INethermindPlugin public string Description => "Enabled signing from a remote Clef instance over Json RPC."; public string Author => "Nethermind"; - public bool PluginEnabled => true; + public bool Enabled => true; public ValueTask DisposeAsync() => ValueTask.CompletedTask; diff --git a/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs b/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs index 1f2e8058816..8021c7dc676 100644 --- a/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs +++ b/src/Nethermind/Nethermind.HealthChecks/HealthChecksPlugin.cs @@ -53,7 +53,7 @@ public async ValueTask DisposeAsync() public string Author => "Nethermind"; public bool MustInitialize => true; - public bool PluginEnabled => true; + public bool Enabled => true; public FreeDiskSpaceChecker FreeDiskSpaceChecker => LazyInitializer.EnsureInitialized(ref _freeDiskSpaceChecker, () => new FreeDiskSpaceChecker( diff --git a/src/Nethermind/Nethermind.Hive/HivePlugin.cs b/src/Nethermind/Nethermind.Hive/HivePlugin.cs index 35e988dd3fb..d2818d8d3f8 100644 --- a/src/Nethermind/Nethermind.Hive/HivePlugin.cs +++ b/src/Nethermind/Nethermind.Hive/HivePlugin.cs @@ -15,7 +15,7 @@ public class HivePlugin(IHiveConfig hiveConfig) : INethermindPlugin private INethermindApi _api = null!; private ILogger _logger; private readonly CancellationTokenSource _disposeCancellationToken = new(); - public bool PluginEnabled => Environment.GetEnvironmentVariable("NETHERMIND_HIVE_ENABLED")?.ToLowerInvariant() == "true" || hiveConfig.Enabled; + public bool Enabled => Environment.GetEnvironmentVariable("NETHERMIND_HIVE_ENABLED")?.ToLowerInvariant() == "true" || hiveConfig.Enabled; public ValueTask DisposeAsync() { @@ -40,7 +40,7 @@ public Task Init(INethermindApi api) public async Task InitNetworkProtocol() { - if (PluginEnabled) + if (Enabled) { if (_api.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.BlockProcessingQueue is null) throw new ArgumentNullException(nameof(_api.BlockProcessingQueue)); diff --git a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs index 09796421d69..b34a14c588b 100644 --- a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs +++ b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs @@ -1,4 +1,5 @@ using Autofac; +using Autofac.Core; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Init.Steps; @@ -17,13 +18,19 @@ public class SnapshotPlugin(ISnapshotConfig snapshotConfig) : IInitializationPlu public Task InitNetworkProtocol() => Task.CompletedTask; public Task InitRpcModules() => Task.CompletedTask; - public bool PluginEnabled => + public bool Enabled => snapshotConfig is { Enabled: true, DownloadUrl: not null }; - public void ConfigureContainer(ContainerBuilder builder) - { - builder.AddIStepsFromAssembly(GetType().Assembly); - } + public IModule? ContainerModule => new SnapshotPluginModule(); public ValueTask DisposeAsync() => ValueTask.CompletedTask; + + private class SnapshotPluginModule : Module + { + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + builder.AddIStepsFromAssembly(GetType().Assembly); + } + } } diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs index 9b3ec096450..91b832a9c08 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStorePlugin.cs @@ -24,7 +24,7 @@ public class TraceStorePlugin(ITraceStoreConfig config) : INethermindPlugin public string Name => DbName; public string Description => "Allows to serve traces without the block state, by saving historical traces to DB."; public string Author => "Nethermind"; - public bool PluginEnabled => config.Enabled; + public bool Enabled => config.Enabled; public Task Init(INethermindApi nethermindApi) { @@ -34,7 +34,7 @@ public Task Init(INethermindApi nethermindApi) _jsonRpcConfig = _api.Config(); _logger = _logManager.GetClassLogger(); - if (PluginEnabled) + if (Enabled) { // Setup serialization _traceSerializer = new ParityLikeTraceSerializer(_logManager, config.MaxDepth, config.VerifySerialized); @@ -55,7 +55,7 @@ public Task Init(INethermindApi nethermindApi) public Task InitNetworkProtocol() { - if (PluginEnabled) + if (Enabled) { if (_logger.IsInfo) _logger.Info($"Starting TraceStore with {config.TraceTypes} traces."); @@ -72,7 +72,7 @@ public Task InitNetworkProtocol() public Task InitRpcModules() { - if (PluginEnabled && _jsonRpcConfig.Enabled) + if (Enabled && _jsonRpcConfig.Enabled) { IRpcModuleProvider apiRpcModuleProvider = _api.RpcModuleProvider!; if (apiRpcModuleProvider.GetPool(ModuleType.Trace) is IRpcModulePool traceModulePool) @@ -87,7 +87,7 @@ public Task InitRpcModules() public ValueTask DisposeAsync() { - if (PluginEnabled) + if (Enabled) { _pruner?.Dispose(); _db?.Dispose(); diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs index b3caaf475cb..c1e1fc4307e 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using Autofac; +using Autofac.Core; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Blockchain; @@ -32,13 +33,9 @@ public class AuRaMergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : Me public override string Name => "AuRaMerge"; public override string Description => "AuRa Merge plugin for ETH1-ETH2"; - protected override bool MergeEnabled => PluginEnabled; - public override bool PluginEnabled => _mergeConfig.Enabled && _chainSpec.SealEngineType == SealEngineType.AuRa; - - public void ConfigureContainer(ContainerBuilder builder) - { - builder.AddIStepsFromAssembly(GetType().Assembly); - } + protected override bool MergeEnabled => Enabled; + public override bool Enabled => _mergeConfig.Enabled && _chainSpec.SealEngineType == SealEngineType.AuRa; + public IModule? ContainerModule => new AuraMergeModule(); public override async Task Init(INethermindApi nethermindApi) { @@ -91,5 +88,14 @@ protected override IBlockFinalizationManager InitializeMergeFinilizationManager( "Cannot instantiate AuRaMergeFinalizationManager when AuRaFinalizationManager is null!"), _poSSwitcher); } + + private class AuraMergeModule: Module + { + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + builder.AddIStepsFromAssembly(GetType().Assembly); + } + } } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.BlockProducer.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.BlockProducer.cs index d17d39b5599..b499460ecc6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.BlockProducer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.BlockProducer.cs @@ -71,6 +71,6 @@ public IBlockProducerRunner InitBlockProducerRunner(IBlockProducerRunner baseRun // this looks redundant but Enabled actually comes from IConsensusWrapperPlugin // while MergeEnabled comes from merge config - public bool Enabled => MergeEnabled; + public bool ConsensusWrapperEnabled => MergeEnabled; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index d7b2dab3a7d..345809e5736 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -63,8 +63,8 @@ public partial class MergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) public virtual string Description => "Merge plugin for ETH1-ETH2"; public string Author => "Nethermind"; - protected virtual bool MergeEnabled => PluginEnabled; - public virtual bool PluginEnabled => mergeConfig.Enabled && chainSpec.SealEngineType is SealEngineType.BeaconChain or SealEngineType.Clique or SealEngineType.Ethash; + protected virtual bool MergeEnabled => Enabled; + public virtual bool Enabled => mergeConfig.Enabled && chainSpec.SealEngineType is SealEngineType.BeaconChain or SealEngineType.Clique or SealEngineType.Ethash; public int Priority => PluginPriorities.Merge; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 0a8909be67c..a043461468c 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using Autofac; +using Autofac.Core; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Consensus; @@ -59,14 +60,8 @@ public class OptimismPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchroniz public IBlockProductionTrigger DefaultBlockProductionTrigger => NeverProduceTrigger.Instance; - public bool PluginEnabled => chainSpec.SealEngineType == SealEngineType; - - public void ConfigureContainer(ContainerBuilder builder) - { - builder - .AddSingleton() - .AddIStepsFromAssembly(GetType().Assembly); - } + public bool Enabled => chainSpec.SealEngineType == SealEngineType; + public IModule? ContainerModule => new OptimismModule(); public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) { @@ -84,7 +79,7 @@ public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null) public void InitTxTypesAndRlpDecoders(INethermindApi api) { - if (PluginEnabled) + if (Enabled) { api.RegisterTxType(new OptimismTxDecoder(), Always.Valid); Rlp.RegisterDecoders(typeof(OptimismReceiptMessageDecoder).Assembly, true); @@ -93,7 +88,7 @@ public void InitTxTypesAndRlpDecoders(INethermindApi api) public Task Init(INethermindApi api) { - if (!PluginEnabled) + if (!Enabled) return Task.CompletedTask; _api = (OptimismNethermindApi)api; @@ -131,7 +126,7 @@ public Task Init(INethermindApi api) public Task InitSynchronization() { - if (_api is null || !PluginEnabled) + if (_api is null || !Enabled) return Task.CompletedTask; ArgumentNullException.ThrowIfNull(_api.SpecProvider); @@ -187,7 +182,7 @@ public Task InitSynchronization() public async Task InitRpcModules() { - if (_api is null || !PluginEnabled) + if (_api is null || !Enabled) return; ArgumentNullException.ThrowIfNull(_api.SpecProvider); @@ -293,4 +288,15 @@ public IBlockProducerRunner CreateBlockProducerRunner() public ValueTask DisposeAsync() => ValueTask.CompletedTask; public bool MustInitialize => true; + + private class OptimismModule : Module + { + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + builder + .AddSingleton() + .AddIStepsFromAssembly(GetType().Assembly); + } + } } diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index cc2e392f9b9..d9e9f2ffdd2 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -85,14 +85,18 @@ private void ApplyPluginModule(IEnumerable plugins, ChainSpec chainSpec, C foreach (INethermindPlugin nethermindPlugin in pluginLoader.Resolve>()) { - if (_logger.IsDebug) _logger.Warn($"Plugin {nethermindPlugin.Name} enabled: {nethermindPlugin.PluginEnabled}"); - if (!nethermindPlugin.PluginEnabled) + if (_logger.IsDebug) _logger.Warn($"Plugin {nethermindPlugin.Name} enabled: {nethermindPlugin.Enabled}"); + if (!nethermindPlugin.Enabled) { continue; } - containerBuilder.RegisterInstance(nethermindPlugin).As(); - nethermindPlugin.ConfigureContainer(containerBuilder); + containerBuilder.AddInstance(nethermindPlugin); + + if (nethermindPlugin.ContainerModule is Module module) + { + containerBuilder.AddModule(nethermindPlugin.ContainerModule); + } } } diff --git a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs index 8457577328a..38e80b5f891 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs @@ -35,7 +35,9 @@ protected override void Load(ContainerBuilder builder) { base.Load(builder); + // Maybe this should not be used? as it can be error prone. builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); + builder.RegisterSource(new ConfigRegistrationSource()); LoggerMiddleware.Configure(builder); diff --git a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs index 77d97e20ee8..5ceddf845c7 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs @@ -25,8 +25,8 @@ public class ShutterPlugin(IShutterConfig shutterConfig, IMergeConfig mergeConfi public string Name => "Shutter"; public string Description => "Shutter plugin for AuRa post-merge chains"; public string Author => "Nethermind"; - public bool Enabled => PluginEnabled; - public bool PluginEnabled => shutterConfig!.Enabled && mergeConfig!.Enabled && chainSpec.SealEngineType is SealEngineType.AuRa; + public bool ConsensusWrapperEnabled => Enabled; + public bool Enabled => shutterConfig!.Enabled && mergeConfig!.Enabled && chainSpec.SealEngineType is SealEngineType.AuRa; public int Priority => PluginPriorities.Shutter; @@ -49,7 +49,7 @@ public Task Init(INethermindApi nethermindApi) public Task InitRpcModules() { - if (Enabled) + if (ConsensusWrapperEnabled) { if (_api!.BlockProducer is null) throw new ArgumentNullException(nameof(_api.BlockProducer)); @@ -61,7 +61,7 @@ public Task InitRpcModules() public IBlockProducer InitBlockProducer(IBlockProducerFactory consensusPlugin, ITxSource? txSource) { - if (Enabled) + if (ConsensusWrapperEnabled) { if (_api!.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.EthereumEcdsa is null) throw new ArgumentNullException(nameof(_api.SpecProvider)); diff --git a/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs b/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs index af9e6015923..adf7abc71ac 100644 --- a/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs +++ b/src/Nethermind/Nethermind.UPnP.Plugin/UPnPPlugin.cs @@ -22,14 +22,14 @@ public class UPnPPlugin(INetworkConfig networkConfig) : INethermindPlugin private INetworkConfig _networkConfig = new NetworkConfig(); private ILogger _logger = NullLogger.Instance; - public bool PluginEnabled => networkConfig.EnableUPnP; + public bool Enabled => networkConfig.EnableUPnP; public Task Init(INethermindApi api) { _networkConfig = api.Config(); _logger = api.LogManager.GetClassLogger(); - if (PluginEnabled) + if (Enabled) { Task.Factory.StartNew(RunRefreshLoop, TaskCreationOptions.LongRunning); } From eb7a8a85462b4f257e6265ad1e5d889437c888b4 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 12:33:13 +0800 Subject: [PATCH 07/25] Remove InitializationPlugin --- .../Extensions/IInitializationPlugin.cs | 12 ------------ .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 2 +- .../Nethermind.Init.Snapshot/SnapshotPlugin.cs | 2 +- .../Nethermind.Merge.AuRa/AuRaMergePlugin.cs | 2 +- .../Nethermind.Optimism/OptimismPlugin.cs | 2 +- .../Nethermind.Shutter/Nethermind.Shutter.csproj | 1 + src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs | 13 ++++++++++++- 7 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs diff --git a/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs deleted file mode 100644 index 06e6a95c7a0..00000000000 --- a/src/Nethermind/Nethermind.Api/Extensions/IInitializationPlugin.cs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -namespace Nethermind.Api.Extensions; - -/// -/// Assemblies containing instances of this interface will be the ones -/// used to load custom initialization steps. -/// -public interface IInitializationPlugin : INethermindPlugin -{ -} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index 452af8377b5..aa2406580f3 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -24,7 +24,7 @@ namespace Nethermind.Consensus.AuRa /// /// Consensus plugin for AuRa setup. /// - public class AuRaPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin + public class AuRaPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin { private AuRaNethermindApi? _nethermindApi; public string Name => SealEngineType; diff --git a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs index b34a14c588b..9e024c2757d 100644 --- a/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs +++ b/src/Nethermind/Nethermind.Init.Snapshot/SnapshotPlugin.cs @@ -6,7 +6,7 @@ namespace Nethermind.Init.Snapshot; -public class SnapshotPlugin(ISnapshotConfig snapshotConfig) : IInitializationPlugin +public class SnapshotPlugin(ISnapshotConfig snapshotConfig) : INethermindPlugin { public string Name => "Snapshot"; diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs index c1e1fc4307e..4bb7348a968 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs @@ -25,7 +25,7 @@ namespace Nethermind.Merge.AuRa /// Plugin for AuRa -> PoS migration /// /// IMPORTANT: this plugin should always come before MergePlugin - public class AuRaMergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : MergePlugin(mergeConfig, chainSpec), IInitializationPlugin + public class AuRaMergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : MergePlugin(mergeConfig, chainSpec) { private AuRaNethermindApi? _auraApi; private readonly ChainSpec _chainSpec = chainSpec; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index a043461468c..e4831504e3d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -36,7 +36,7 @@ namespace Nethermind.Optimism; -public class OptimismPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin, IInitializationPlugin +public class OptimismPlugin(ChainSpec chainSpec) : IConsensusPlugin, ISynchronizationPlugin { public string Author => "Nethermind"; public string Name => "Optimism"; diff --git a/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj b/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj index 5f7acfe37b8..1f8291a1331 100644 --- a/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj +++ b/src/Nethermind/Nethermind.Shutter/Nethermind.Shutter.csproj @@ -36,6 +36,7 @@ + diff --git a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs index 5ceddf845c7..908db505485 100644 --- a/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs +++ b/src/Nethermind/Nethermind.Shutter/ShutterPlugin.cs @@ -15,12 +15,14 @@ using System.IO; using Nethermind.Serialization.Json; using System.Threading; +using Autofac; using Nethermind.Config; +using Nethermind.Init.Steps; using Nethermind.Specs.ChainSpecStyle; namespace Nethermind.Shutter; -public class ShutterPlugin(IShutterConfig shutterConfig, IMergeConfig mergeConfig, ChainSpec chainSpec) : IConsensusWrapperPlugin, IInitializationPlugin +public class ShutterPlugin(IShutterConfig shutterConfig, IMergeConfig mergeConfig, ChainSpec chainSpec) : IConsensusWrapperPlugin { public string Name => "Shutter"; public string Description => "Shutter plugin for AuRa post-merge chains"; @@ -126,4 +128,13 @@ private static Dictionary LoadValidatorInfo(string fp) FileStream fstream = new(fp, FileMode.Open, FileAccess.Read, FileShare.None); return new EthereumJsonSerializer().Deserialize>(fstream); } + + private class ShutterModule : Module + { + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + builder.AddIStepsFromAssembly(GetType().Assembly); + } + } } From d7890184cd8659d75cc9ed2946fc08c526053884 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 15:06:08 +0800 Subject: [PATCH 08/25] Add fallback --- .../Nethermind.Api/IApiWithBlockchain.cs | 1 + .../Nethermind.Api/IApiWithNetwork.cs | 1 + .../Nethermind.Api/IApiWithStores.cs | 1 + src/Nethermind/Nethermind.Api/IBasicApi.cs | 1 + .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 1 + .../Blockchain/TestBlockchain.cs | 1 + .../ContainerBuilderExtensionsTests.cs | 1 + .../Container/FallbackToFieldFromApiTests.cs | 56 ++++++++++++ .../ContainerBuilderExtensions.cs | 2 +- .../Container/FallbackToFieldFromApi.cs | 86 +++++++++++++++++++ src/Nethermind/Nethermind.Db/IDbProvider.cs | 1 + .../Steps/InitializeNetwork.cs | 1 + .../Nethermind.Merge.Plugin/MergePlugin.cs | 1 + .../Synchronization/MergeSynchronizer.cs | 1 + .../Nethermind.Optimism/OptimismPlugin.cs | 1 + .../Ethereum/ContextWithMocks.cs | 1 + .../Ethereum/Api/ApiBuilder.cs | 1 + .../Nethermind.Runner/Modules/BaseModule.cs | 4 +- .../Nethermind.Runner/Modules/CoreModule.cs | 12 +-- .../Nethermind.Runner/Modules/RunnerModule.cs | 1 + .../OldStyleFullSynchronizerTests.cs | 1 + .../SyncThreadTests.cs | 1 + .../SynchronizerTests.cs | 1 + .../Synchronizer.cs | 1 + 24 files changed, 171 insertions(+), 8 deletions(-) rename src/Nethermind/Nethermind.Core.Test/{ => Container}/ContainerBuilderExtensionsTests.cs (99%) create mode 100644 src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs rename src/Nethermind/Nethermind.Core/{ => Container}/ContainerBuilderExtensions.cs (99%) create mode 100644 src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index 1263974b81e..aa32d3ea587 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -17,6 +17,7 @@ using Nethermind.Consensus.Scheduler; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs index 0b0e05e2a6d..40a5e563260 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs @@ -5,6 +5,7 @@ using Autofac; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.PubSub; using Nethermind.Grpc; using Nethermind.JsonRpc; diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs index eed8ed62430..0c2b22135a4 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -8,6 +8,7 @@ using Nethermind.Blockchain.Receipts; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Crypto; using Nethermind.Db.Blooms; using Nethermind.Facade.Find; diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 2aedf60621f..7f425fa98a1 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -11,6 +11,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Core.Timers; using Nethermind.Crypto; diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index aa2406580f3..bbacbf9bd0a 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -12,6 +12,7 @@ using Nethermind.Consensus.Producers; using Nethermind.Consensus.Transactions; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Init.Steps; using Nethermind.Logging; using Nethermind.Serialization.Json; diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index f07d4c411aa..0560d782177 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -23,6 +23,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Transactions; using Nethermind.Consensus.Validators; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; diff --git a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs similarity index 99% rename from src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs rename to src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs index 28e890c8499..bed4017cf5a 100644 --- a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs @@ -4,6 +4,7 @@ using System; using Autofac; using FluentAssertions; +using Nethermind.Core.Container; using NUnit.Framework; namespace Nethermind.Core.Test; diff --git a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs new file mode 100644 index 00000000000..d1fb1b6112d --- /dev/null +++ b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Autofac; +using Autofac.Core; +using FluentAssertions; +using Nethermind.Core.Container; +using Nethermind.Core.Exceptions; +using NUnit.Framework; + +namespace Nethermind.Core.Test.Container; + +public class FallbackToFieldFromApiTests +{ + + [Test] + public void CanResolveFieldWithTypeWhenSetLater() + { + ContainerBuilder containerBuilder = new ContainerBuilder(); + containerBuilder.AddSingleton(); + containerBuilder.RegisterSource(new FallbackToFieldFromApi()); + + IContainer container = containerBuilder.Build(); + + Action act = (() => container.Resolve()); + act.Should().Throw(); + + container.Resolve().TargetService = new TargetService(); + container.Resolve().Should().NotBeNull(); + } + + [Test] + public void ThrowExceptionIfTargetIsAlsoRegisterec() + { + ContainerBuilder containerBuilder = new ContainerBuilder(); + containerBuilder.AddSingleton(); + containerBuilder.AddSingleton(); + containerBuilder.RegisterSource(new FallbackToFieldFromApi()); + + IContainer container = containerBuilder.Build(); + + Action act = (() => container.Resolve()); + act.Should().Throw(); + } + + public class Api + { + public TargetService TargetService { get; set; } = null!; + } + + public class TargetService + { + } + +} diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs similarity index 99% rename from src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs rename to src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs index c11037fb923..616dc8fa0c1 100644 --- a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs @@ -9,7 +9,7 @@ using Autofac.Core; using Autofac.Features.AttributeFilters; -namespace Nethermind.Core; +namespace Nethermind.Core.Container; public static class ContainerBuilderExtensions { diff --git a/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs new file mode 100644 index 00000000000..441cee25253 --- /dev/null +++ b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs @@ -0,0 +1,86 @@ +// 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.Builder; +using Autofac.Core; +using Nethermind.Core.Exceptions; + +namespace Nethermind.Core.Container; + +/// +/// If a service does not have any registration, try to get it from a member fo a type `T`. +/// This allow fetching of unregistered/unconfigured component from `NethermindApi`. +/// +public class FallbackToFieldFromApi : IRegistrationSource where TApi : notnull +{ + private readonly Dictionary _availableTypes; + + public FallbackToFieldFromApi() + { + Type tApi = typeof(TApi); + + IEnumerable properties = tApi + .GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.GetCustomAttribute() == null); + + Dictionary availableTypes = new Dictionary(); + + foreach (PropertyInfo propertyInfo in properties) + { + availableTypes[propertyInfo.PropertyType] = propertyInfo; + } + + _availableTypes = availableTypes; + } + + public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) + { + if (registrationAccessor == null) + { + throw new ArgumentNullException(nameof(registrationAccessor)); + } + + TypedService? ts = service as TypedService; + if (ts == null || ts.ServiceType == typeof(string)) + { + return Enumerable.Empty(); + } + + PropertyInfo? property; + Type serviceType = ts.ServiceType; + if (registrationAccessor(service).Any()) + { + // Already have registration + if (_availableTypes.TryGetValue(serviceType, out property) && property.SetMethod != null) + { + // To prevent mistake, a service that already have registration via dependency injection must not also + // have a setter in api. This is to prevent the assumption that the setter will caause the service + // to be reflected in dependency injected components. It will not. Please remove the setter from the + // api. + throw new InvalidConfigurationException($"Service {serviceType} has both container registration and mutable field in {typeof(TApi).Name}", -1); + } + + return Enumerable.Empty(); + } + + if (!_availableTypes.TryGetValue(serviceType, out property)) + { + // Not available as a property + return Enumerable.Empty(); + } + + IRegistrationBuilder builder = RegistrationBuilder.ForDelegate(serviceType, (ctx, reg) => + { + TApi baseT = ctx.Resolve(); + return property.GetValue(baseT)!; + }); + return new[] { builder.CreateRegistration() }; + } + + public bool IsAdapterForIndividualComponents => false; +} diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 0e29da0e432..28ba78d0029 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -6,6 +6,7 @@ using Autofac; using Microsoft.Extensions.DependencyInjection; using Nethermind.Core; +using Nethermind.Core.Container; namespace Nethermind.Db { diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index d21db889b84..2f14469cc77 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -15,6 +15,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Utils; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Facade.Eth; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 345809e5736..12b81b7c267 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -21,6 +21,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Exceptions; using Nethermind.Db; using Nethermind.Facade.Proxy; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs index ac3ad98313f..8d4365842e3 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs @@ -8,6 +8,7 @@ using Autofac.Features.AttributeFilters; using Nethermind.Blockchain.Synchronization; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Logging; using Nethermind.Synchronization; using Nethermind.Synchronization.Blocks; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index e4831504e3d..bb564493843 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -25,6 +25,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.HealthChecks; using Nethermind.Init.Steps; diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index a467a28ff91..625fb33688d 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -48,6 +48,7 @@ using NSubstitute; using Nethermind.Blockchain.Blocks; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Facade.Find; using Nethermind.Runner.Modules; diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index d9e9f2ffdd2..39625b51db6 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -12,6 +12,7 @@ using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Logging; using Nethermind.Runner.Modules; diff --git a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs index 38e80b5f891..52a0178395d 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs @@ -15,6 +15,7 @@ using Nethermind.Api; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Core.Timers; using Nethermind.Crypto; @@ -27,7 +28,8 @@ namespace Nethermind.Runner.Modules; /// /// Basic common behaviour such as instrumentation and system related stuff. Should be completely compatible in all -/// situation and can be run in tests. +/// situation and can be run in tests. Probably should be called `PrePluginModule` as it is also run without +/// having plugins. /// public class BaseModule : Module { diff --git a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs index a7307e70eee..741355aa14e 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs @@ -4,6 +4,8 @@ using Autofac; using Nethermind.Api; using Nethermind.Consensus; +using Nethermind.Core.Container; +using Module = Autofac.Module; namespace Nethermind.Runner.Modules; @@ -16,12 +18,10 @@ protected override void Load(ContainerBuilder builder) { base.Load(builder); - builder.RegisterType() - .As() - .SingleInstance(); + builder + .AddSingleton() + .AddSingleton(); - builder.RegisterType() - .As() - .SingleInstance(); + builder.RegisterSource(new FallbackToFieldFromApi()); } } diff --git a/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs b/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs index 1cf85195e94..4cb7562d065 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/RunnerModule.cs @@ -3,6 +3,7 @@ using Autofac; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Init.Steps; using Nethermind.Runner.Ethereum; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index c813c1a01a6..51b953c4353 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -17,6 +17,7 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index a00e043e67d..ecbc7f53937 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -45,6 +45,7 @@ using BlockTree = Nethermind.Blockchain.BlockTree; using Nethermind.Synchronization.SnapSync; using Nethermind.Config; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Trie; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index 361acf116f4..433e3d9c9f0 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -19,6 +19,7 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; diff --git a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs index 826406ca9de..54aa84d538d 100644 --- a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs +++ b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs @@ -9,6 +9,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Extensions; using Nethermind.Logging; using Nethermind.Stats; From e72cf0dd492319d98ef3f81a5eebc296f376040f Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 17:07:39 +0800 Subject: [PATCH 09/25] Whitespace --- src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 9e50bd25150..06d1efa79bc 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -316,7 +316,7 @@ IProtocolsManager protocolsManager } } -public class NetworkModule(INetworkConfig networkConfig, ISyncConfig syncConfig): Module +public class NetworkModule(INetworkConfig networkConfig, ISyncConfig syncConfig) : Module { protected override void Load(ContainerBuilder builder) { From 5496d74a9578f1d6bac5aede23b30090add4fb0c Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 18:59:12 +0800 Subject: [PATCH 10/25] Dedup optimism logic --- .../Nethermind.Merge.Plugin/MergePlugin.cs | 2 -- .../Nethermind.Optimism/OptimismPlugin.cs | 16 ++-------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 8183f3c99e7..e146ef380a0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -395,9 +395,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) if (!MergeEnabled) return; builder - .AddSingleton(_poSSwitcher) .AddSingleton(_blockCacheService) - .AddSingleton(_mergeConfig) .AddSingleton(_invalidChainTracker); builder diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index dd4aadcb79c..625f06aa87d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -133,22 +133,10 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) builder .AddSingleton(_blockCacheService!) - .AddSingleton(_mergeConfig) - .AddSingleton(_invalidChainTracker!) - .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddSingleton(_invalidChainTracker!); builder - .RegisterType() - .As() - .As() - .SingleInstance(); - - builder - .RegisterDecorator(); - - builder.RegisterModule(new MergeSynchronizerModule()); + .RegisterModule(new MergeNetworkModule()); } public Task InitSynchronization(IContainer container) From 77c9bdb302b8e976b8c0da4e17152c0a557e76a4 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 19:09:17 +0800 Subject: [PATCH 11/25] Minor cleanup --- src/Nethermind/Nethermind.Api/IBasicApi.cs | 6 ++++-- .../OldStyleFullSynchronizerTests.cs | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 747d1faebec..75377f1ef02 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -62,8 +62,10 @@ public IEnumerable GetSynchronizationPlugins() => public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder builder) { - builder.AddPropertiesFrom(this); - builder.Register(ecdsa => ecdsa); + builder + .AddPropertiesFrom(this) + .Bind(); + builder.RegisterSource(new ConfigRegistrationSource()); DbProvider!.ConfigureServiceCollection(builder); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index e6ded153433..191654868d0 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -140,7 +140,6 @@ public void Syncs_with_empty_peer() _remoteBlockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(1).TestObject; ISyncPeer peer = new SyncPeerMock(_remoteBlockTree); - Stopwatch sw = Stopwatch.StartNew(); _pool.Start(); _synchronizer.Start(); _pool.AddPeer(peer); From 213f7e6ac979030b305f6c1365bf029eafa25acf Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 19:36:50 +0800 Subject: [PATCH 12/25] Fix test --- .../Nethermind.Merge.Plugin.Test/MergePluginTests.cs | 2 ++ src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index ed3a3277cce..a804c7047d9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -110,6 +110,7 @@ public void Init_merge_plugin_does_not_throw_exception(bool enabled) ContainerBuilder builder = CreateContainerBuilder(); _plugin.ConfigureSynchronizationBuilder(builder); IContainer container = builder.Build(); + _context.ApiWithNetworkServiceContainer = container; Assert.DoesNotThrowAsync(async () => await _plugin.InitSynchronization(container)); Assert.DoesNotThrow(() => _plugin.InitBlockProducer(_consensusPlugin!, null)); @@ -126,6 +127,7 @@ public async Task Initializes_correctly() ContainerBuilder builder = CreateContainerBuilder(); _plugin.ConfigureSynchronizationBuilder(builder); IContainer container = builder.Build(); + _context.ApiWithNetworkServiceContainer = container; await _plugin.InitSynchronization(container); await _plugin.InitNetworkProtocol(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index e146ef380a0..f881a469c59 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -288,7 +288,6 @@ public Task InitRpcModules() if (_api.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.BlockchainProcessor is null) throw new ArgumentNullException(nameof(_api.BlockchainProcessor)); if (_api.HeaderValidator is null) throw new ArgumentNullException(nameof(_api.HeaderValidator)); - if (_api.EthSyncingInfo is null) throw new ArgumentNullException(nameof(_api.EthSyncingInfo)); if (_api.Sealer is null) throw new ArgumentNullException(nameof(_api.Sealer)); if (_api.BlockValidator is null) throw new ArgumentNullException(nameof(_api.BlockValidator)); if (_api.BlockProcessingQueue is null) throw new ArgumentNullException(nameof(_api.BlockProcessingQueue)); @@ -407,17 +406,13 @@ public Task InitSynchronization(IContainer container) if (MergeEnabled) { if (_api.SpecProvider is null) throw new ArgumentNullException(nameof(_api.SpecProvider)); - if (_api.SyncPeerPool is null) throw new ArgumentNullException(nameof(_api.SyncPeerPool)); if (_api.BlockTree is null) throw new ArgumentNullException(nameof(_api.BlockTree)); if (_api.DbProvider is null) throw new ArgumentNullException(nameof(_api.DbProvider)); if (_api.BlockProcessingQueue is null) throw new ArgumentNullException(nameof(_api.BlockProcessingQueue)); if (_blockCacheService is null) throw new ArgumentNullException(nameof(_blockCacheService)); - if (_api.BetterPeerStrategy is null) throw new ArgumentNullException(nameof(_api.BetterPeerStrategy)); if (_api.SealValidator is null) throw new ArgumentNullException(nameof(_api.SealValidator)); if (_api.UnclesValidator is null) throw new ArgumentNullException(nameof(_api.UnclesValidator)); - if (_api.NodeStatsManager is null) throw new ArgumentNullException(nameof(_api.NodeStatsManager)); if (_api.HeaderValidator is null) throw new ArgumentNullException(nameof(_api.HeaderValidator)); - if (_api.PeerDifficultyRefreshPool is null) throw new ArgumentNullException(nameof(_api.PeerDifficultyRefreshPool)); if (_api.StateReader is null) throw new ArgumentNullException(nameof(_api.StateReader)); // ToDo strange place for validators initialization From 0bbd6a78e61b905c1b6079a0b787f4209fcf4f83 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 19:40:26 +0800 Subject: [PATCH 13/25] Fix optimism start --- src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs | 2 +- src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index f881a469c59..e54f37afbff 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -394,7 +394,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) if (!MergeEnabled) return; builder - .AddSingleton(_blockCacheService) + .AddSingleton(_blockCacheService) .AddSingleton(_invalidChainTracker); builder diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 625f06aa87d..78f82ad36b4 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -132,7 +132,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) return; builder - .AddSingleton(_blockCacheService!) + .AddSingleton(_blockCacheService!) .AddSingleton(_invalidChainTracker!); builder @@ -159,7 +159,7 @@ public Task InitSynchronization(IContainer container) _invalidChainTracker.SetupBlockchainProcessorInterceptor(_api.BlockchainProcessor); _peerRefresher = container.Resolve(); - _beaconPivot = container.Resolve(); + _beaconPivot = container.Resolve(); _beaconSync = container.Resolve(); _ = container.Resolve(); From 505e863881f53e375e78d896c0f79b7b1b60848c Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 20:08:26 +0800 Subject: [PATCH 14/25] These checks are no longer necessary. --- src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 78f82ad36b4..e3591f32f32 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -144,16 +144,7 @@ public Task InitSynchronization(IContainer container) if (_api is null || !ShouldRunSteps(_api)) return Task.CompletedTask; - ArgumentNullException.ThrowIfNull(_api.SpecProvider); - ArgumentNullException.ThrowIfNull(_api.BlockTree); - ArgumentNullException.ThrowIfNull(_api.DbProvider); - ArgumentNullException.ThrowIfNull(_api.PeerDifficultyRefreshPool); - ArgumentNullException.ThrowIfNull(_api.SyncPeerPool); - ArgumentNullException.ThrowIfNull(_api.NodeStatsManager); ArgumentNullException.ThrowIfNull(_api.BlockchainProcessor); - ArgumentNullException.ThrowIfNull(_api.BetterPeerStrategy); - - ArgumentNullException.ThrowIfNull(_blockCacheService); ArgumentNullException.ThrowIfNull(_invalidChainTracker); _invalidChainTracker.SetupBlockchainProcessorInterceptor(_api.BlockchainProcessor); From 40a604734f6ebe11a26422d6f950a5844513b888 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 20:12:01 +0800 Subject: [PATCH 15/25] Fix not using all hierarcy --- .../Nethermind.Core/Container/FallbackToFieldFromApi.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs index 441cee25253..4d64e71b0d1 100644 --- a/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs +++ b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs @@ -25,7 +25,8 @@ public FallbackToFieldFromApi() Type tApi = typeof(TApi); IEnumerable properties = tApi - .GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public) + .GetInterfaces() + .SelectMany(i => i.GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public)) .Where(p => p.GetCustomAttribute() == null); Dictionary availableTypes = new Dictionary(); From a00d5909fff50af691fe8e2c507fabfc331c5c83 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 17 Oct 2024 21:28:34 +0800 Subject: [PATCH 16/25] Remove some integration --- .../Extensions/ISynchronizationPlugin.cs | 2 +- .../Nethermind.Api/IApiWithBlockchain.cs | 11 -- .../Nethermind.Api/IApiWithNetwork.cs | 8 -- .../Nethermind.Api/IApiWithStores.cs | 6 - src/Nethermind/Nethermind.Api/IBasicApi.cs | 14 +-- .../Nethermind.Api/NethermindApi.cs | 30 +++-- .../ConfigRegistrationSource.cs | 51 -------- .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 2 +- .../ContainerBuilderExtensionsTests.cs | 114 ------------------ .../Container/ContainerBuilderExtensions.cs | 28 ----- src/Nethermind/Nethermind.Db/IDbProvider.cs | 29 ----- .../EthStatsPluginTests.cs | 2 +- .../Steps/InitializeNetwork.cs | 37 +++--- .../MergePluginTests.cs | 30 +---- .../Nethermind.Merge.Plugin/MergePlugin.cs | 10 +- .../Nethermind.Optimism/OptimismPlugin.cs | 10 +- .../Ethereum/ContextWithMocks.cs | 56 +-------- .../Ethereum/Api/ApiBuilder.cs | 5 + .../Nethermind.Runner/Modules/CoreModule.cs | 21 +++- .../Nethermind.Runner/Modules/DbModule.cs | 90 ++++++++++++++ .../OldStyleFullSynchronizerTests.cs | 8 +- .../SyncThreadTests.cs | 5 +- .../SynchronizerTests.cs | 10 +- 23 files changed, 181 insertions(+), 398 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs delete mode 100644 src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs create mode 100644 src/Nethermind/Nethermind.Runner/Modules/DbModule.cs diff --git a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs index 02814693706..020508af582 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs @@ -9,6 +9,6 @@ namespace Nethermind.Api.Extensions public interface ISynchronizationPlugin : INethermindPlugin { void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder); - Task InitSynchronization(IContainer container); + Task InitSynchronization(); } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index 4f458ffd5f1..075f01e4d8f 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -102,16 +102,5 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory INodeStorageFactory NodeStorageFactory { get; set; } IBackgroundTaskScheduler BackgroundTaskScheduler { get; set; } CensorshipDetector CensorshipDetector { get; set; } - - public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(ContainerBuilder builder) - { - ConfigureContainerBuilderFromApiWithStores(builder) - .AddPropertiesFrom(this) - .AddInstance(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); - - if (TrieStore != null) builder.AddInstance(TrieStore.AsReadOnly()); - - return builder; - } } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs index f1751ba9601..aecf65f55ed 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs @@ -49,13 +49,5 @@ public interface IApiWithNetwork : IApiWithBlockchain ISyncServer? SyncServer { get; } 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 0c2b22135a4..d3a3fdd462d 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -33,11 +33,5 @@ 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 91f235b7183..f181d601a73 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -49,6 +49,7 @@ public interface IBasicApi ITimestamper Timestamper { get; } ITimerFactory TimerFactory { get; } IProcessExitSource? ProcessExit { get; } + ILifetimeScope BaseContainer { get; } public IConsensusPlugin? GetConsensusPlugin() => Plugins @@ -60,18 +61,5 @@ public IEnumerable GetConsensusWrapperPlugins() => public IEnumerable GetSynchronizationPlugins() => Plugins.OfType(); - - public ContainerBuilder ConfigureContainerBuilderFromBasicApi(ContainerBuilder builder) - { - builder - .AddPropertiesFrom(this) - .Bind(); - - builder.RegisterSource(new ConfigRegistrationSource()); - - DbProvider!.ConfigureServiceCollection(builder); - - return builder; - } } } diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index 3befef4737a..b0264b90485 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -127,7 +127,7 @@ public IBlockchainBridge CreateBlockchainBridge() public IDbProvider? DbProvider { get; set; } public IDbFactory? DbFactory { get; set; } - public IDiscoveryApp? DiscoveryApp => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IDiscoveryApp? DiscoveryApp => BaseContainer.ResolveOptional(); public ISigner? EngineSigner { get; set; } public ISignerStore? EngineSignerStore { get; set; } public IEnode? Enode { get; set; } @@ -152,14 +152,14 @@ public IBlockchainBridge CreateBlockchainBridge() public IMessageSerializationService MessageSerializationService { get; } = new MessageSerializationService(); public IGossipPolicy GossipPolicy { get; set; } = Policy.FullGossip; public IMonitoringService MonitoringService { get; set; } = NullMonitoringService.Instance; - public INodeStatsManager? NodeStatsManager => ApiWithNetworkServiceContainer?.ResolveOptional(); - public IPeerManager? PeerManager => ApiWithNetworkServiceContainer?.ResolveOptional(); - public IPeerPool? PeerPool => ApiWithNetworkServiceContainer?.ResolveOptional(); + public INodeStatsManager? NodeStatsManager => BaseContainer.ResolveOptional(); + public IPeerManager? PeerManager => BaseContainer.ResolveOptional(); + public IPeerPool? PeerPool => BaseContainer.ResolveOptional(); public IReceiptStorage? ReceiptStorage { get; set; } public IReceiptFinder? ReceiptFinder { get; set; } public IReceiptMonitor? ReceiptMonitor { get; set; } public IRewardCalculatorSource? RewardCalculatorSource { get; set; } = NoBlockRewards.Instance; - public IRlpxHost? RlpxPeer => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IRlpxHost? RlpxPeer => BaseContainer.ResolveOptional(); public IRpcModuleProvider? RpcModuleProvider { get; set; } = NullModuleProvider.Instance; public IRpcAuthentication? RpcAuthentication { get; set; } public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; } @@ -180,22 +180,22 @@ public ISealEngine SealEngine } } - public ISessionMonitor? SessionMonitor => ApiWithNetworkServiceContainer?.ResolveOptional(); + public ISessionMonitor? SessionMonitor => BaseContainer.ResolveOptional(); public ISpecProvider? SpecProvider => BaseContainer.Resolve(); public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; - public ISyncModeSelector SyncModeSelector => ApiWithNetworkServiceContainer?.ResolveOptional()!; - public IBetterPeerStrategy? BetterPeerStrategy => ApiWithNetworkServiceContainer?.ResolveOptional(); - public ISyncPeerPool? SyncPeerPool => ApiWithNetworkServiceContainer?.ResolveOptional(); - public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool => ApiWithNetworkServiceContainer?.ResolveOptional(); - public ISynchronizer? Synchronizer => ApiWithNetworkServiceContainer?.ResolveOptional(); - public ISyncServer? SyncServer => ApiWithNetworkServiceContainer?.ResolveOptional(); + public ISyncModeSelector SyncModeSelector => BaseContainer.ResolveOptional()!; + public IBetterPeerStrategy? BetterPeerStrategy => BaseContainer.ResolveOptional(); + public ISyncPeerPool? SyncPeerPool => BaseContainer.ResolveOptional(); + public IPeerDifficultyRefreshPool? PeerDifficultyRefreshPool => BaseContainer.ResolveOptional(); + public ISynchronizer? Synchronizer => BaseContainer.ResolveOptional(); + public ISyncServer? SyncServer => BaseContainer.ResolveOptional(); [SkipServiceCollection] public IWorldState? WorldState { get; set; } public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; } public IWorldStateManager? WorldStateManager { get; set; } public IStateReader? StateReader { get; set; } - public IStaticNodesManager? StaticNodesManager => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IStaticNodesManager? StaticNodesManager => BaseContainer.ResolveOptional(); public ITimestamper Timestamper { get; } = Core.Timestamper.Default; public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default; public ITransactionProcessor? TransactionProcessor { get; set; } @@ -214,7 +214,7 @@ public ISealEngine SealEngine public IBlockImprovementContextFactory? BlockImprovementContextFactory { get; set; } public IGasPriceOracle? GasPriceOracle { get; set; } - public IEthSyncingInfo? EthSyncingInfo => ApiWithNetworkServiceContainer?.ResolveOptional(); + public IEthSyncingInfo? EthSyncingInfo => BaseContainer.ResolveOptional(); public IBlockProductionPolicy? BlockProductionPolicy { get; set; } public INodeStorageFactory NodeStorageFactory { get; set; } = null!; public IBackgroundTaskScheduler BackgroundTaskScheduler { get; set; } = null!; @@ -239,7 +239,5 @@ public ISealEngine SealEngine public CompositePruningTrigger PruningTrigger { get; } = new(); public IProcessExitSource? ProcessExit => BaseContainer.Resolve(); public CompositeTxGossipPolicy TxGossipPolicy { get; } = new(); - - public IContainer? ApiWithNetworkServiceContainer { get; set; } } } diff --git a/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs b/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs deleted file mode 100644 index 883213e83c9..00000000000 --- a/src/Nethermind/Nethermind.Config/ConfigRegistrationSource.cs +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using System.Collections.Generic; -using System.Linq; -using Autofac; -using Autofac.Core; -using Autofac.Core.Activators.Delegate; -using Autofac.Core.Lifetime; -using Autofac.Core.Registration; - -namespace Nethermind.Config; - -/// -/// Dynamically resolve IConfig -/// -public class ConfigRegistrationSource : IRegistrationSource -{ - public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor) - { - IServiceWithType swt = service as IServiceWithType; - if (swt == null || !typeof(IConfig).IsAssignableFrom(swt.ServiceType)) - { - // It's not a request for the base handler type, so skip it. - return Enumerable.Empty(); - } - - // Dynamically resolve IConfig - ComponentRegistration registration = new ComponentRegistration( - Guid.NewGuid(), - new DelegateActivator(swt.ServiceType, (c, p) => - { - IConfigProvider configProvider = c.Resolve(); - object config = typeof(IConfigProvider) - .GetMethod("GetConfig") - .MakeGenericMethod(swt.ServiceType) - .Invoke(configProvider, new object[] { }); - return config; - }), - new RootScopeLifetime(), - InstanceSharing.Shared, - InstanceOwnership.OwnedByLifetimeScope, - new[] { service }, - new Dictionary()); - - return new IComponentRegistration[] { registration }; - } - - public bool IsAdapterForIndividualComponents => false; -} diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index caccaf1aaa0..e98222942e2 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -60,7 +60,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder) } } - public Task InitSynchronization(IContainer container) + public Task InitSynchronization() { return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs deleted file mode 100644 index bed4017cf5a..00000000000 --- a/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only - -using System; -using Autofac; -using FluentAssertions; -using Nethermind.Core.Container; -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/Container/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs index 77d91ff9871..57d783f1f2e 100644 --- a/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs @@ -13,34 +13,6 @@ namespace Nethermind.Core.Container; 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() diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 96b8f43e3b9..8a4ce4a82bb 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -35,34 +35,5 @@ public interface IDbProvider : IDisposable void RegisterColumnDb(string dbName, IColumnsDb db); IEnumerable> GetAllDbMeta(); - void ConfigureServiceCollection(ContainerBuilder sc) - { - sc.AddInstance(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()); - sc.AddKeyedSingleton(dbName, db); - } - - IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts); - sc.AddInstance>(receiptColumnDb); - sc.AddKeyedSingleton(DbNames.Receipts, receiptColumnDb as ITunableDb ?? new NoopTunableDb()); - } } } diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs index 76ed4368b13..832ac20ec64 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs @@ -19,7 +19,7 @@ public class EthStatsPluginTests [SetUp] public void Setup() { - _context = Build.ContextWithMocksWithTestContainer(); + _context = Build.ContextWithMocks(); _plugin = new EthStatsPlugin(new EthStatsConfig() { Enabled = true}); } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index d1c243ed901..09327cc5969 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -101,7 +101,6 @@ private async Task Initialize(CancellationToken cancellationToken) Network.Metrics.PeerLimit = maxPeersCount; ContainerBuilder builder = new ContainerBuilder(); - _api.ConfigureContainerBuilderFromApiWithNetwork(builder); builder.RegisterModule(new NetworkModule(_networkConfig, _syncConfig)); ISynchronizationPlugin[] synchronizationPlugins = _api.GetSynchronizationPlugins().ToArray(); @@ -111,41 +110,37 @@ private async Task Initialize(CancellationToken cancellationToken) plugin.ConfigureSynchronizationBuilder(builder); } - IContainer container = builder.Build(); - _api.ApiWithNetworkServiceContainer = container; - _api.DisposeStack.Append(container); - foreach (ISynchronizationPlugin plugin in synchronizationPlugins) { - await plugin.InitSynchronization(container); + await plugin.InitSynchronization(); } // TODO: This whole thing can be injected into `InitializeNetwork`, but the container then // need to be put at a higher level. - SyncedTxGossipPolicy txGossipPolicy = container.Resolve(); - ISyncServer _ = container.Resolve(); - IDiscoveryApp discoveryApp = container.Resolve(); - IPeerPool peerPool = container.Resolve(); - IPeerManager peerManager = container.Resolve(); - ISessionMonitor sessionMonitor = container.Resolve(); - IRlpxHost rlpxHost = container.Resolve(); - IStaticNodesManager staticNodesManager = container.Resolve(); - Func nodeSourceToDiscV4Feeder = container.Resolve>(); - IProtocolsManager protocolsManager = container.Resolve(); - SnapCapabilitySwitcher snapCapabilitySwitcher = container.Resolve(); - ISyncPeerPool syncPeerPool = container.Resolve(); - ISynchronizer synchronizer = container.Resolve(); + SyncedTxGossipPolicy txGossipPolicy = _api.BaseContainer.Resolve(); + ISyncServer _ = _api.BaseContainer.Resolve(); + IDiscoveryApp discoveryApp = _api.BaseContainer.Resolve(); + IPeerPool peerPool = _api.BaseContainer.Resolve(); + IPeerManager peerManager = _api.BaseContainer.Resolve(); + ISessionMonitor sessionMonitor = _api.BaseContainer.Resolve(); + IRlpxHost rlpxHost = _api.BaseContainer.Resolve(); + IStaticNodesManager staticNodesManager = _api.BaseContainer.Resolve(); + Func nodeSourceToDiscV4Feeder = _api.BaseContainer.Resolve>(); + IProtocolsManager protocolsManager = _api.BaseContainer.Resolve(); + SnapCapabilitySwitcher snapCapabilitySwitcher = _api.BaseContainer.Resolve(); + ISyncPeerPool syncPeerPool = _api.BaseContainer.Resolve(); + ISynchronizer synchronizer = _api.BaseContainer.Resolve(); _api.TxGossipPolicy.Policies.Add(txGossipPolicy); if (_api.TrieStore is HealingTrieStore healingTrieStore) { - healingTrieStore.InitializeNetwork(container.Resolve()); + healingTrieStore.InitializeNetwork(_api.BaseContainer.Resolve()); } if (_api.WorldState is HealingWorldState healingWorldState) { - healingWorldState.InitializeNetwork(container.Resolve()); + healingWorldState.InitializeNetwork(_api.BaseContainer.Resolve()); } if (cancellationToken.IsCancellationRequested) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index 3b536638090..e0c5f03688a 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -13,11 +13,9 @@ using Nethermind.Core; using Nethermind.Core.Exceptions; using Nethermind.Db; -using Nethermind.Init.Steps; using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules; using Nethermind.Merge.Plugin.BlockProduction; -using Nethermind.Network.Config; using Nethermind.Specs.ChainSpecStyle; using NUnit.Framework; using NSubstitute; @@ -39,7 +37,10 @@ public void Setup() BlocksConfig? miningConfig = new(); IJsonRpcConfig jsonRpcConfig = new JsonRpcConfig() { Enabled = true, EnabledModules = [ModuleType.Engine] }; - _context = Build.ContextWithMocks(); + _context = Build.ContextWithMocks(containerConfigurer: (builder) => + { + builder.RegisterModule(new MergeNetworkModule()); + }); _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); _context.ConfigProvider.GetConfig().Returns(miningConfig); @@ -68,14 +69,6 @@ public void Setup() _consensusPlugin = new(_context.ChainSpec); } - private ContainerBuilder CreateContainerBuilder() - { - ContainerBuilder builder = new ContainerBuilder(); - ((IApiWithNetwork)_context).ConfigureContainerBuilderFromApiWithNetwork(builder); - builder.RegisterModule(new NetworkModule(new NetworkConfig(), new SyncConfig())); - return builder; - } - [TearDown] public void TearDown() => _plugin.DisposeAsync().GetAwaiter().GetResult(); @@ -104,12 +97,7 @@ public void Init_merge_plugin_does_not_throw_exception(bool enabled) Assert.DoesNotThrowAsync(async () => await _plugin.Init(_context)); Assert.DoesNotThrowAsync(async () => await _plugin.InitNetworkProtocol()); - ContainerBuilder builder = CreateContainerBuilder(); - _plugin.ConfigureSynchronizationBuilder(builder); - IContainer container = builder.Build(); - _context.ApiWithNetworkServiceContainer = container; - - Assert.DoesNotThrowAsync(async () => await _plugin.InitSynchronization(container)); + Assert.DoesNotThrowAsync(async () => await _plugin.InitSynchronization()); Assert.DoesNotThrow(() => _plugin.InitBlockProducer(_consensusPlugin!, null)); Assert.DoesNotThrowAsync(async () => await _plugin.InitRpcModules()); Assert.DoesNotThrowAsync(async () => await _plugin.DisposeAsync()); @@ -120,13 +108,7 @@ public async Task Initializes_correctly() { Assert.DoesNotThrowAsync(async () => await _consensusPlugin!.Init(_context)); await _plugin.Init(_context); - - ContainerBuilder builder = CreateContainerBuilder(); - _plugin.ConfigureSynchronizationBuilder(builder); - IContainer container = builder.Build(); - _context.ApiWithNetworkServiceContainer = container; - - await _plugin.InitSynchronization(container); + await _plugin.InitSynchronization(); await _plugin.InitNetworkProtocol(); ISyncConfig syncConfig = _context.Config(); Assert.That(syncConfig.NetworkingEnabled, Is.True); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 988b325beea..c9f67a95732 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -399,7 +399,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) .RegisterModule(new MergeNetworkModule()); } - public Task InitSynchronization(IContainer container) + public Task InitSynchronization() { if (MergeEnabled) { @@ -438,10 +438,10 @@ public Task InitSynchronization(IContainer container) _invalidChainTracker, _api.LogManager); - _peerRefresher = container.Resolve(); - _beaconPivot = container.Resolve(); - _beaconSync = container.Resolve(); - container.Resolve(); + _peerRefresher = _api.BaseContainer.Resolve(); + _beaconPivot = _api.BaseContainer.Resolve(); + _beaconSync = _api.BaseContainer.Resolve(); + _api.BaseContainer.Resolve(); } return Task.CompletedTask; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index 91e45210eb6..e59a7ae454d 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -135,7 +135,7 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) .RegisterModule(new MergeNetworkModule()); } - public Task InitSynchronization(IContainer container) + public Task InitSynchronization() { if (_api is null || !Enabled) return Task.CompletedTask; @@ -145,10 +145,10 @@ public Task InitSynchronization(IContainer container) _invalidChainTracker.SetupBlockchainProcessorInterceptor(_api.BlockchainProcessor); - _peerRefresher = container.Resolve(); - _beaconPivot = container.Resolve(); - _beaconSync = container.Resolve(); - _ = container.Resolve(); + _peerRefresher = _api.BaseContainer.Resolve(); + _beaconPivot = _api.BaseContainer.Resolve(); + _beaconSync = _api.BaseContainer.Resolve(); + _ = _api.BaseContainer.Resolve(); return Task.CompletedTask; } diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 647fc448ddd..80b18b3d144 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -63,7 +63,7 @@ namespace Nethermind.Runner.Test.Ethereum { public static class Build { - public static NethermindApi ContextWithoutContainer(Action? containerConfigurer = null) + public static NethermindApi ContextWithMocks(INetworkConfig? networkConfig = null, ISyncConfig? syncConfig = null, Action? containerConfigurer = null) { ContainerBuilder containerBuilder = new ContainerBuilder() .AddInstance(Substitute.For()) @@ -73,6 +73,8 @@ public static NethermindApi ContextWithoutContainer(Action? co .AddModule(new BaseModule()) .AddModule(new CoreModule()) .AddModule(new RunnerModule()) + .AddModule(new NetworkModule(networkConfig ?? new NetworkConfig(), syncConfig ?? new SyncConfig())) + .AddModule(new DbModule()) .AddInstance(Substitute.For()) .AddInstance(Substitute.For()); // need more complete chainspec to use ISpecProvider @@ -127,62 +129,10 @@ public static NethermindApi ContextWithoutContainer(Action? co api.BlockProductionPolicy = Substitute.For(); api.ReceiptMonitor = Substitute.For(); api.BadBlocksStore = Substitute.For(); - - api.ApiWithNetworkServiceContainer = new ContainerBuilder() - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .Build(); - api.WorldStateManager = new ReadOnlyWorldStateManager(api.DbProvider, Substitute.For(), LimboLogs.Instance); api.NodeStorageFactory = new NodeStorageFactory(INodeStorage.KeyScheme.HalfPath, LimboLogs.Instance); return (NethermindApi)api; } - - public static NethermindApi ContextWithMocks() - { - NethermindApi api = ContextWithoutContainer(); - api.ApiWithNetworkServiceContainer = new ContainerBuilder() - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .AddInstance(Substitute.For()) - .Build(); - - return api; - } - - public static NethermindApi ContextWithMocksWithTestContainer(INetworkConfig? networkConfig = null, ISyncConfig? syncConfig = null) - { - NethermindApi api = ContextWithoutContainer(); - - if (networkConfig == null) - { - networkConfig = new NetworkConfig(); - } - if (syncConfig == null) - { - syncConfig = new SyncConfig(); - } - - var builder = new ContainerBuilder(); - ((IApiWithNetwork)api).ConfigureContainerBuilderFromApiWithNetwork(builder); - builder.RegisterModule(new NetworkModule(networkConfig, syncConfig)); - api.ApiWithNetworkServiceContainer = builder.Build(); - - return api; - } } } diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 39625b51db6..86bfd346e51 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -9,12 +9,15 @@ using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; +using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Container; using Nethermind.Facade.Eth.RpcTransaction; +using Nethermind.Init.Steps; using Nethermind.Logging; +using Nethermind.Network.Config; using Nethermind.Runner.Modules; using Nethermind.Serialization.Json; using Nethermind.Specs.ChainSpecStyle; @@ -59,6 +62,8 @@ public IContainer Create(IEnumerable plugins) containerBuilder.RegisterModule(new BaseModule()); containerBuilder.RegisterModule(new CoreModule()); containerBuilder.RegisterModule(new RunnerModule()); + containerBuilder.RegisterModule(new NetworkModule(_configProvider.GetConfig(), _configProvider.GetConfig())); + containerBuilder.RegisterModule(new DbModule()); ApplyPluginModule(plugins, chainSpec, containerBuilder); return containerBuilder.Build(); diff --git a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs index 741355aa14e..6e60d94e0c1 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs @@ -3,8 +3,14 @@ using Autofac; using Nethermind.Api; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Find; using Nethermind.Consensus; using Nethermind.Core.Container; +using Nethermind.Crypto; +using Nethermind.Db; +using Nethermind.Trie; +using Nethermind.Trie.Pruning; using Module = Autofac.Module; namespace Nethermind.Runner.Modules; @@ -20,7 +26,20 @@ protected override void Load(ContainerBuilder builder) builder .AddSingleton() - .AddSingleton(); + .AddSingleton() + .Bind() + .Bind(); + + builder.Register(ctx => + { + var nodeStorageFactory = ctx.Resolve(); + var stateDb = ctx.Resolve().StateDb; + return nodeStorageFactory.WrapKeyValueStore(stateDb); + }) + .As(); + + builder.Register(ctx => ctx.Resolve().AsReadOnly()) + .As(); builder.RegisterSource(new FallbackToFieldFromApi()); } diff --git a/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs b/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs new file mode 100644 index 00000000000..1d37554089b --- /dev/null +++ b/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using Autofac; +using Nethermind.Core; +using Nethermind.Db; +using Nethermind.Trie; + +namespace Nethermind.Runner.Modules; + +public class DbModule: Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder + .Register(ctx => + { + INodeStorageFactory nodeStorageFactory = ctx.Resolve(); + IDb stateDb = ctx.Resolve().StateDb; + return nodeStorageFactory.WrapKeyValueStore(stateDb); + }) + .As(); + + // TODO: Have hooks that automatically get these. + // TODO: Make these lazy + 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) + { + ConfigureDatabase(builder, dbName); + } + + // Special case for receipt which uses columns + ConfigureColumnDb(builder, DbNames.Receipts); + } + + private void ConfigureDatabase(ContainerBuilder builder, string dbName) + { + builder + .Register(ctx => + { + IDbProvider? dbProvider = ctx.Resolve(); + return dbProvider.GetDb(dbName); + }) + .Named(dbName) + .Named(dbName) + .Named(dbName) + .Named(dbName); + + builder + .Register(ctx => + { + IDbProvider? dbProvider = ctx.Resolve(); + IDb? db = dbProvider.GetDb(dbName); + return db as ITunableDb ?? new NoopTunableDb(); + }) + .Named(dbName); + } + + private void ConfigureColumnDb(ContainerBuilder builder, string dbName) + { + builder + .Register(ctx => + { + IDbProvider? dbProvider = ctx.Resolve(); + return dbProvider.GetColumnDb(dbName); + }) + .Named>(dbName); + + builder + .Register(ctx => + { + IDbProvider? dbProvider = ctx.Resolve(); + IColumnsDb? db = dbProvider.GetColumnDb(dbName); + return db as ITunableDb ?? new NoopTunableDb(); + }) + .Named(dbName); + } +} diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index 8953a7ae0c9..e9c639a5ed5 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -30,6 +30,7 @@ using Nethermind.Init.Steps; using Nethermind.Logging; using Nethermind.Network.Config; +using Nethermind.Runner.Modules; using Nethermind.Specs; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; @@ -85,9 +86,10 @@ public async Task Setup() .AddInstance(new ChainSpec()) .AddInstance(stateReader) .AddInstance(Policy.FullGossip) - .AddInstance(LimboLogs.Instance); - dbProvider.ConfigureServiceCollection(builder); - builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); + .AddInstance(LimboLogs.Instance) + .AddModule(new DbModule()) + .AddModule(new NetworkModule(new NetworkConfig(), syncConfig)); + IContainer container = builder.Build(); _pool = container.Resolve(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 456db8d2328..4a572876f69 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -43,6 +43,7 @@ using Nethermind.Core.Specs; using Nethermind.Init.Steps; using Nethermind.Network.Config; +using Nethermind.Runner.Modules; using Nethermind.Specs.ChainSpecStyle; using Nethermind.Trie; @@ -369,9 +370,9 @@ private SyncTestContext CreateSyncManager(int index) .AddInstance(Policy.FullGossip) .AddInstance(stateReader) .AddInstance(receiptStorage) - .AddInstance(logManager); + .AddInstance(logManager) + .AddModule(new DbModule()); - dbProvider.ConfigureServiceCollection(builder); builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); ISynchronizer synchronizer = container.Resolve(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index d8879f0b05b..8338fc6979a 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -35,6 +35,7 @@ using Nethermind.Merge.Plugin.InvalidChainTracker; using Nethermind.Merge.Plugin.Test; using Nethermind.Network.Config; +using Nethermind.Runner.Modules; using Nethermind.Specs.ChainSpecStyle; using Nethermind.State; using Nethermind.Synchronization.Blocks; @@ -333,11 +334,9 @@ ISyncConfig GetSyncConfig() => IInvalidChainTracker invalidChainTracker = new NoopInvalidChainTracker(); ContainerBuilder builder = new ContainerBuilder(); - dbProvider.ConfigureServiceCollection(builder); builder .AddInstance(dbProvider) - .AddInstance(nodeStorage) .AddInstance(new NetworkConfig()) .AddInstance(Substitute.For()) .AddInstance(MainnetSpecProvider.Instance) @@ -355,9 +354,10 @@ ISyncConfig GetSyncConfig() => .AddInstance(Always.Valid) .AddInstance(Policy.FullGossip) .AddInstance(new BlockCacheService()) - .AddInstance(_logManager); - - builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); + .AddInstance(_logManager) + .AddModule(new DbModule()) + .AddModule(new NetworkModule(new NetworkConfig(), syncConfig)) + .AddInstance(nodeStorage); if (IsMerge(synchronizerType)) { From 7b8b4bb800075232d8e4555d9c428ac1ee998248 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 09:21:45 +0800 Subject: [PATCH 17/25] Fix most tests --- .../Extensions/ISynchronizationPlugin.cs | 1 - .../Nethermind.Api/IApiWithBlockchain.cs | 2 +- .../Nethermind.Api/IApiWithStores.cs | 1 + src/Nethermind/Nethermind.Api/IBasicApi.cs | 1 + .../Nethermind.Api/NethermindApi.cs | 2 +- .../Nethermind.Consensus.AuRa/AuRaPlugin.cs | 10 +--- .../Container/FallbackToFieldFromApiTests.cs | 7 ++- .../Steps/InitializeNetwork.cs | 9 ---- .../Nethermind.Merge.AuRa/AuRaMergePlugin.cs | 3 +- .../MergePluginTests.cs | 2 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 47 ++++++++----------- .../Nethermind.Merge.Plugin/PoSSwitcher.cs | 3 +- .../OptimismNethermindApi.cs | 2 +- .../Nethermind.Optimism/OptimismPlugin.cs | 28 ++--------- .../OptimismPoSSwitcher.cs | 5 ++ .../Nethermind.Runner/Modules/CoreModule.cs | 1 + .../OldStyleFullSynchronizerTests.cs | 1 + .../SyncThreadTests.cs | 6 +-- 18 files changed, 51 insertions(+), 80 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs index 020508af582..d47de6925df 100644 --- a/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs +++ b/src/Nethermind/Nethermind.Api/Extensions/ISynchronizationPlugin.cs @@ -8,7 +8,6 @@ namespace Nethermind.Api.Extensions { public interface ISynchronizationPlugin : INethermindPlugin { - void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder); Task InitSynchronization(); } } diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index 075f01e4d8f..be91259ba3b 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -53,7 +53,7 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory /// /// PoS switcher for The Merge /// - IPoSSwitcher PoSSwitcher { get; set; } + IPoSSwitcher PoSSwitcher { get; } ISealer? Sealer { get; set; } ISealValidator? SealValidator { get; set; } ISealEngine SealEngine { get; set; } diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs index d3a3fdd462d..6f8ce209ad6 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -27,6 +27,7 @@ public interface IApiWithStores : IBasicApi ILogFinder? LogFinder { get; set; } ISigner? EngineSigner { get; set; } ISignerStore? EngineSignerStore { get; set; } + [SkipServiceCollection] ProtectedPrivateKey? NodeKey { get; set; } IReceiptStorage? ReceiptStorage { get; set; } IReceiptFinder? ReceiptFinder { get; set; } diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index f181d601a73..57749bea726 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -40,6 +40,7 @@ public interface IBasicApi IFileSystem FileSystem { get; set; } IKeyStore? KeyStore { get; set; } ILogManager LogManager { get; } + [SkipServiceCollection] ProtectedPrivateKey? OriginalSignerKey { get; set; } IReadOnlyList Plugins { get; } [SkipServiceCollection] diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index b0264b90485..c831deb6109 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -182,7 +182,7 @@ public ISealEngine SealEngine public ISessionMonitor? SessionMonitor => BaseContainer.ResolveOptional(); public ISpecProvider? SpecProvider => BaseContainer.Resolve(); - public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance; + public IPoSSwitcher PoSSwitcher => BaseContainer.Resolve(); public ISyncModeSelector SyncModeSelector => BaseContainer.ResolveOptional()!; public IBetterPeerStrategy? BetterPeerStrategy => BaseContainer.ResolveOptional(); public ISyncPeerPool? SyncPeerPool => BaseContainer.ResolveOptional(); diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs index e98222942e2..54060d8344b 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/AuRaPlugin.cs @@ -52,14 +52,6 @@ public Task Init(INethermindApi nethermindApi) return Task.CompletedTask; } - public void ConfigureSynchronizationBuilder(ContainerBuilder containerBuilder) - { - if (_nethermindApi is not null) - { - containerBuilder.RegisterDecorator(); - } - } - public Task InitSynchronization() { return Task.CompletedTask; @@ -90,6 +82,8 @@ protected override void Load(ContainerBuilder builder) { base.Load(builder); + builder.RegisterDecorator(); + builder .AddSingleton() .AddIStepsFromAssembly(GetType().Assembly); diff --git a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs index d1fb1b6112d..c0f137056ef 100644 --- a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs @@ -44,7 +44,12 @@ public void ThrowExceptionIfTargetIsAlsoRegisterec() act.Should().Throw(); } - public class Api + public interface IApi + { + public TargetService TargetService { get; set; } + } + + public class Api: IApi { public TargetService TargetService { get; set; } = null!; } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 09327cc5969..023ddd59e8b 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -100,16 +100,7 @@ private async Task Initialize(CancellationToken cancellationToken) int maxPeersCount = _networkConfig.ActivePeersMaxCount; Network.Metrics.PeerLimit = maxPeersCount; - ContainerBuilder builder = new ContainerBuilder(); - builder.RegisterModule(new NetworkModule(_networkConfig, _syncConfig)); - ISynchronizationPlugin[] synchronizationPlugins = _api.GetSynchronizationPlugins().ToArray(); - - foreach (ISynchronizationPlugin plugin in synchronizationPlugins) - { - plugin.ConfigureSynchronizationBuilder(builder); - } - foreach (ISynchronizationPlugin plugin in synchronizationPlugins) { await plugin.InitSynchronization(); diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs index 4bb7348a968..c69476e82a2 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs @@ -35,7 +35,7 @@ public class AuRaMergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) : Me public override string Description => "AuRa Merge plugin for ETH1-ETH2"; protected override bool MergeEnabled => Enabled; public override bool Enabled => _mergeConfig.Enabled && _chainSpec.SealEngineType == SealEngineType.AuRa; - public IModule? ContainerModule => new AuraMergeModule(); + public override IModule? ContainerModule => new AuraMergeModule(); public override async Task Init(INethermindApi nethermindApi) { @@ -44,7 +44,6 @@ public override async Task Init(INethermindApi nethermindApi) { await base.Init(nethermindApi); _auraApi = (AuRaNethermindApi)nethermindApi; - _auraApi.PoSSwitcher = _poSSwitcher; // this runs before all init steps that use tx filters TxAuRaFilterBuilders.CreateFilter = (originalFilter, fallbackFilter) => diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs index e0c5f03688a..78da07dfcf8 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/MergePluginTests.cs @@ -39,7 +39,7 @@ public void Setup() _context = Build.ContextWithMocks(containerConfigurer: (builder) => { - builder.RegisterModule(new MergeNetworkModule()); + builder.RegisterModule(new MergeModule()); }); _context.ConfigProvider.GetConfig().Returns(_mergeConfig); _context.ConfigProvider.GetConfig().Returns(new SyncConfig()); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index c9f67a95732..8661000b76b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -70,6 +70,8 @@ public partial class MergePlugin(IMergeConfig mergeConfig, ChainSpec chainSpec) public int Priority => PluginPriorities.Merge; + public virtual IModule? ContainerModule => new MergeModule(); + public virtual Task Init(INethermindApi nethermindApi) { _api = nethermindApi; @@ -94,22 +96,9 @@ public virtual Task Init(INethermindApi nethermindApi) EnsureJsonRpcUrl(); EnsureReceiptAvailable(); - _blockCacheService = new BlockCacheService(); - _poSSwitcher = new PoSSwitcher( - mergeConfig, - _syncConfig, - _api.DbProvider.GetDb(DbNames.Metadata), - _api.BlockTree, - _api.SpecProvider, - _api.ChainSpec, - _api.LogManager); - _invalidChainTracker = new InvalidChainTracker.InvalidChainTracker( - _poSSwitcher, - _api.BlockTree, - _blockCacheService, - _api.LogManager); - _api.PoSSwitcher = _poSSwitcher; - _api.DisposeStack.Push(_invalidChainTracker); + _blockCacheService = _api.BaseContainer.Resolve(); + _poSSwitcher = _api.BaseContainer.Resolve(); + _invalidChainTracker = _api.BaseContainer.Resolve(); _blockFinalizationManager = new ManualBlockFinalizationManager(); if (_txPoolConfig.BlobsSupport.SupportsReorgs()) { @@ -387,18 +376,6 @@ protected virtual void RegisterEngineRpcModule(IEngineRpcModule engineRpcModule) _api.RpcModuleProvider.RegisterSingle(engineRpcModule); } - public void ConfigureSynchronizationBuilder(ContainerBuilder builder) - { - if (!MergeEnabled) return; - - builder - .AddInstance(_blockCacheService) - .AddInstance(_invalidChainTracker); - - builder - .RegisterModule(new MergeNetworkModule()); - } - public Task InitSynchronization() { if (MergeEnabled) @@ -452,6 +429,20 @@ public Task InitSynchronization() public bool MustInitialize { get => true; } } +public class MergeModule : Module +{ + protected override void Load(ContainerBuilder builder) + { + base.Load(builder); + + builder + .AddModule(new MergeNetworkModule()) + .AddSingleton() + .AddSingleton() + .AddSingleton(); + } +} + public class MergeNetworkModule : Module { protected override void Load(ContainerBuilder builder) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs b/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs index ff0758cc01b..0f5d118a011 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/PoSSwitcher.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; @@ -54,7 +55,7 @@ public class PoSSwitcher : IPoSSwitcher public PoSSwitcher( IMergeConfig mergeConfig, ISyncConfig syncConfig, - IDb metadataDb, + [KeyFilter(DbNames.Metadata)] IDb metadataDb, IBlockTree blockTree, ISpecProvider specProvider, ChainSpec chainSpec, diff --git a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs index 7f6b21b893a..b8c956b0c88 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismNethermindApi.cs @@ -17,7 +17,7 @@ public OptimismNethermindApi(ILifetimeScope lifetimeScope) : base(lifetimeScope) { } - public IInvalidChainTracker? InvalidChainTracker { get; set; } + public IInvalidChainTracker? InvalidChainTracker => BaseContainer.Resolve(); public OPL1CostHelper? L1CostHelper { get; set; } public OptimismSpecHelper? SpecHelper { get; set; } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index e59a7ae454d..530a4618421 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -100,17 +100,9 @@ public Task Init(INethermindApi api) ArgumentNullException.ThrowIfNull(_api.SpecProvider); - _api.PoSSwitcher = new OptimismPoSSwitcher(_api.SpecProvider, _api.ChainSpec.Optimism.BedrockBlockNumber); - - _blockCacheService = new BlockCacheService(); + _blockCacheService = _api.BaseContainer.Resolve(); _api.EthereumEcdsa = new OptimismEthereumEcdsa(_api.EthereumEcdsa); - _api.InvalidChainTracker = _invalidChainTracker = new InvalidChainTracker( - _api.PoSSwitcher, - _api.BlockTree, - _blockCacheService, - _api.LogManager); - _api.DisposeStack.Push(_invalidChainTracker); - + _invalidChainTracker = _api.BaseContainer.Resolve(); _api.FinalizationManager = _blockFinalizationManager = new ManualBlockFinalizationManager(); _api.RewardCalculatorSource = NoBlockRewards.Instance; @@ -122,19 +114,6 @@ public Task Init(INethermindApi api) return Task.CompletedTask; } - public void ConfigureSynchronizationBuilder(ContainerBuilder builder) - { - if (Enabled) - return; - - builder - .AddInstance(_blockCacheService!) - .AddInstance(_invalidChainTracker!); - - builder - .RegisterModule(new MergeNetworkModule()); - } - public Task InitSynchronization() { if (_api is null || !Enabled) @@ -266,8 +245,11 @@ private class OptimismModule : Module { protected override void Load(ContainerBuilder builder) { + base.Load(builder); builder + .AddModule(new MergeModule()) + .AddSingleton() .AddSingleton() .AddIStepsFromAssembly(GetType().Assembly); } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs index 8dd42874806..ef1b39f97b2 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs @@ -5,9 +5,14 @@ using Nethermind.Core.Specs; using Nethermind.Int256; using Nethermind.Optimism; +using Nethermind.Specs.ChainSpecStyle; public class OptimismPoSSwitcher(ISpecProvider specProvider, long bedrockBlockNumber) : IPoSSwitcher { + public OptimismPoSSwitcher(ISpecProvider specProvider, ChainSpec chainSpec): this(specProvider, chainSpec.Optimism.BedrockBlockNumber) + { + } + public UInt256? TerminalTotalDifficulty => specProvider.TerminalTotalDifficulty; public UInt256? FinalTotalDifficulty => TerminalTotalDifficulty; diff --git a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs index 6e60d94e0c1..bd3b83b2521 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/CoreModule.cs @@ -27,6 +27,7 @@ protected override void Load(ContainerBuilder builder) builder .AddSingleton() .AddSingleton() + .AddInstance(NoPoS.Instance) .Bind() .Bind(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index e9c639a5ed5..030112a8da5 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -72,6 +72,7 @@ public async Task Setup() IStateReader stateReader = new StateReader(trieStore, _codeDb, LimboLogs.Instance); ContainerBuilder builder = new ContainerBuilder() + .AddInstance(dbProvider) .AddInstance(nodeStorage) .AddInstance(MainnetSpecProvider.Instance) .AddInstance(Substitute.For()) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 4a572876f69..ccc272a5179 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -354,6 +354,8 @@ private SyncTestContext CreateSyncManager(int index) ContainerBuilder builder = new ContainerBuilder(); builder + .AddModule(new NetworkModule(new NetworkConfig(), syncConfig)) + .AddModule(new DbModule()) .AddInstance(dbProvider) .AddInstance(Substitute.For()) .AddInstance(new NetworkConfig()) @@ -370,10 +372,8 @@ private SyncTestContext CreateSyncManager(int index) .AddInstance(Policy.FullGossip) .AddInstance(stateReader) .AddInstance(receiptStorage) - .AddInstance(logManager) - .AddModule(new DbModule()); + .AddInstance(logManager); - builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); ISynchronizer synchronizer = container.Resolve(); ISyncPeerPool syncPeerPool = container.Resolve(); From 2cbf30678b7e1f4376c6a3e8e15cdd51994d5124 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 09:23:41 +0800 Subject: [PATCH 18/25] Small refactor --- .../Nethermind.Api/IApiWithBlockchain.cs | 5 ++- .../Nethermind.Api/IApiWithNetwork.cs | 1 + .../Nethermind.Api/IApiWithStores.cs | 1 + src/Nethermind/Nethermind.Api/IBasicApi.cs | 1 + .../Nethermind.Api/NethermindApi.cs | 1 + .../ContainerBuilderExtensionsTests.cs | 1 + .../ContainerBuilderExtensions.cs | 4 +- src/Nethermind/Nethermind.Db/IDbProvider.cs | 5 ++- .../Steps/InitializeNetwork.cs | 3 +- .../Nethermind.Merge.Plugin/MergePlugin.cs | 5 ++- .../Synchronization/MergeSynchronizer.cs | 1 + .../Nethermind.Optimism/OptimismPlugin.cs | 5 ++- .../Ethereum/ContextWithMocks.cs | 31 +++++++------- .../OldStyleFullSynchronizerTests.cs | 31 +++++++------- .../SyncThreadTests.cs | 35 ++++++++-------- .../SynchronizerTests.cs | 41 ++++++++++--------- .../Synchronizer.cs | 1 + 17 files changed, 94 insertions(+), 78 deletions(-) rename src/Nethermind/Nethermind.Core/{ => Container}/ContainerBuilderExtensions.cs (96%) diff --git a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs index ab8caeb0cbc..6033530eb45 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs @@ -17,6 +17,7 @@ using Nethermind.Consensus.Scheduler; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth; @@ -106,9 +107,9 @@ public ContainerBuilder ConfigureContainerBuilderFromApiWithBlockchain(Container { ConfigureContainerBuilderFromApiWithStores(builder) .AddPropertiesFrom(this) - .AddSingleton(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); + .AddInstance(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb)); - if (TrieStore != null) builder.AddSingleton(TrieStore.AsReadOnly()); + if (TrieStore != null) builder.AddInstance(TrieStore.AsReadOnly()); return builder; } diff --git a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs index f7cbeb251a6..f1751ba9601 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithNetwork.cs @@ -5,6 +5,7 @@ using Autofac; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.PubSub; using Nethermind.Grpc; using Nethermind.JsonRpc; diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs index eed8ed62430..0c2b22135a4 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -8,6 +8,7 @@ using Nethermind.Blockchain.Receipts; using Nethermind.Consensus; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Crypto; using Nethermind.Db.Blooms; using Nethermind.Facade.Find; diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index 75377f1ef02..f96efd59989 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -11,6 +11,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Core.Timers; using Nethermind.Crypto; diff --git a/src/Nethermind/Nethermind.Api/NethermindApi.cs b/src/Nethermind/Nethermind.Api/NethermindApi.cs index aa4a2f49f3a..378530ab30f 100644 --- a/src/Nethermind/Nethermind.Api/NethermindApi.cs +++ b/src/Nethermind/Nethermind.Api/NethermindApi.cs @@ -58,6 +58,7 @@ using Nethermind.Sockets; using Nethermind.Trie; using Nethermind.Consensus.Processing.CensorshipDetector; +using Nethermind.Core.Container; using Nethermind.Facade.Find; namespace Nethermind.Api diff --git a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs index 28e890c8499..bed4017cf5a 100644 --- a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs @@ -4,6 +4,7 @@ using System; using Autofac; using FluentAssertions; +using Nethermind.Core.Container; using NUnit.Framework; namespace Nethermind.Core.Test; diff --git a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs similarity index 96% rename from src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs rename to src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs index 8df60a5ba5b..ab9c1b3aee8 100644 --- a/src/Nethermind/Nethermind.Core/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs @@ -8,7 +8,7 @@ using Autofac; using Autofac.Features.AttributeFilters; -namespace Nethermind.Core; +namespace Nethermind.Core.Container; public static class ContainerBuilderExtensions { @@ -50,7 +50,7 @@ public static ContainerBuilder AddSingleton(this ContainerBuilder builder) wh return builder; } - public static ContainerBuilder AddSingleton(this ContainerBuilder builder, T instance) where T : class + public static ContainerBuilder AddInstance(this ContainerBuilder builder, T instance) where T : class { builder.RegisterInstance(instance) .As() diff --git a/src/Nethermind/Nethermind.Db/IDbProvider.cs b/src/Nethermind/Nethermind.Db/IDbProvider.cs index 59bdcc4105c..96b8f43e3b9 100644 --- a/src/Nethermind/Nethermind.Db/IDbProvider.cs +++ b/src/Nethermind/Nethermind.Db/IDbProvider.cs @@ -6,6 +6,7 @@ using Autofac; using Microsoft.Extensions.DependencyInjection; using Nethermind.Core; +using Nethermind.Core.Container; namespace Nethermind.Db { @@ -36,7 +37,7 @@ public interface IDbProvider : IDisposable void ConfigureServiceCollection(ContainerBuilder sc) { - sc.AddSingleton(this); + sc.AddInstance(this); // TODO: Have hooks that automatically get these string[] dbNames = [ @@ -60,7 +61,7 @@ void ConfigureServiceCollection(ContainerBuilder sc) } IColumnsDb receiptColumnDb = GetColumnDb(DbNames.Receipts); - sc.AddSingleton>(receiptColumnDb); + sc.AddInstance>(receiptColumnDb); sc.AddKeyedSingleton(DbNames.Receipts, receiptColumnDb as ITunableDb ?? new NoopTunableDb()); } } diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 06d1efa79bc..4033570279d 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -15,6 +15,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Blockchain.Utils; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Timers; using Nethermind.Crypto; using Nethermind.Db; @@ -338,7 +339,7 @@ protected override void Load(ContainerBuilder builder) builder .AddSingleton() - .AddSingleton(No.BeaconSync) + .AddInstance(No.BeaconSync) .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index e54f37afbff..36f39e4f5fd 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -22,6 +22,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Exceptions; using Nethermind.Db; using Nethermind.Facade.Proxy; @@ -394,8 +395,8 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) if (!MergeEnabled) return; builder - .AddSingleton(_blockCacheService) - .AddSingleton(_invalidChainTracker); + .AddInstance(_blockCacheService) + .AddInstance(_invalidChainTracker); builder .RegisterModule(new MergeNetworkModule()); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs index ac3ad98313f..8d4365842e3 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Synchronization/MergeSynchronizer.cs @@ -8,6 +8,7 @@ using Autofac.Features.AttributeFilters; using Nethermind.Blockchain.Synchronization; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Logging; using Nethermind.Synchronization; using Nethermind.Synchronization.Blocks; diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs index e3591f32f32..fafdd958d52 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs @@ -24,6 +24,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.HealthChecks; using Nethermind.Network; @@ -132,8 +133,8 @@ public void ConfigureSynchronizationBuilder(ContainerBuilder builder) return; builder - .AddSingleton(_blockCacheService!) - .AddSingleton(_invalidChainTracker!); + .AddInstance(_blockCacheService!) + .AddInstance(_invalidChainTracker!); builder .RegisterModule(new MergeNetworkModule()); diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 3ad5bf853b0..d3dc679622c 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -50,6 +50,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Consensus.Scheduler; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Facade.Find; using Nethermind.Core.Test.Builders; using Nethermind.Init.Steps; @@ -125,21 +126,21 @@ public static NethermindApi ContextWithMocks() { NethermindApi api = ContextWithoutContainer(); api.ApiWithNetworkServiceContainer = new ContainerBuilder() - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) - .AddSingleton(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) + .AddInstance(Substitute.For()) .Build(); return api; diff --git a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs index 191654868d0..8953a7ae0c9 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/OldStyleFullSynchronizerTests.cs @@ -21,6 +21,7 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; @@ -70,21 +71,21 @@ public async Task Setup() IStateReader stateReader = new StateReader(trieStore, _codeDb, LimboLogs.Instance); ContainerBuilder builder = new ContainerBuilder() - .AddSingleton(nodeStorage) - .AddSingleton(MainnetSpecProvider.Instance) - .AddSingleton(Substitute.For()) - .AddSingleton(new NetworkConfig()) - .AddSingleton(_blockTree) - .AddSingleton(_receiptStorage) - .AddSingleton(_receiptStorage) - .AddSingleton(syncConfig) - .AddSingleton(Always.Valid) - .AddSingleton(Always.Valid) - .AddSingleton(Substitute.For()) - .AddSingleton(new ChainSpec()) - .AddSingleton(stateReader) - .AddSingleton(Policy.FullGossip) - .AddSingleton(LimboLogs.Instance); + .AddInstance(nodeStorage) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(Substitute.For()) + .AddInstance(new NetworkConfig()) + .AddInstance(_blockTree) + .AddInstance(_receiptStorage) + .AddInstance(_receiptStorage) + .AddInstance(syncConfig) + .AddInstance(Always.Valid) + .AddInstance(Always.Valid) + .AddInstance(Substitute.For()) + .AddInstance(new ChainSpec()) + .AddInstance(stateReader) + .AddInstance(Policy.FullGossip) + .AddInstance(LimboLogs.Instance); dbProvider.ConfigureServiceCollection(builder); builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs index 8e645cee8b4..343e6554c9f 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SyncThreadTests.cs @@ -39,6 +39,7 @@ using NUnit.Framework; using BlockTree = Nethermind.Blockchain.BlockTree; using Nethermind.Config; +using Nethermind.Core.Container; using Nethermind.Core.Specs; using Nethermind.Init.Steps; using Nethermind.Network.Config; @@ -352,23 +353,23 @@ private SyncTestContext CreateSyncManager(int index) ContainerBuilder builder = new ContainerBuilder(); builder - .AddSingleton(dbProvider) - .AddSingleton(Substitute.For()) - .AddSingleton(new NetworkConfig()) - .AddSingleton(new NodeStorage(dbProvider.StateDb)) - .AddSingleton(MainnetSpecProvider.Instance) - .AddSingleton(tree) - .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(syncConfig) - .AddSingleton(blockValidator) - .AddSingleton(sealValidator) - .AddSingleton(Substitute.For()) - .AddSingleton(new ChainSpec()) - .AddSingleton(Policy.FullGossip) - .AddSingleton(stateReader) - .AddSingleton(receiptStorage) - .AddSingleton(logManager); + .AddInstance(dbProvider) + .AddInstance(Substitute.For()) + .AddInstance(new NetworkConfig()) + .AddInstance(new NodeStorage(dbProvider.StateDb)) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(tree) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(syncConfig) + .AddInstance(blockValidator) + .AddInstance(sealValidator) + .AddInstance(Substitute.For()) + .AddInstance(new ChainSpec()) + .AddInstance(Policy.FullGossip) + .AddInstance(stateReader) + .AddInstance(receiptStorage) + .AddInstance(logManager); dbProvider.ConfigureServiceCollection(builder); builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); IContainer container = builder.Build(); diff --git a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs index 659a4b36275..d8879f0b05b 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/SynchronizerTests.cs @@ -17,6 +17,7 @@ using Nethermind.Consensus.Validators; using Nethermind.Core; using Nethermind.Core.Collections; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; @@ -335,26 +336,26 @@ ISyncConfig GetSyncConfig() => dbProvider.ConfigureServiceCollection(builder); builder - .AddSingleton(dbProvider) - .AddSingleton(nodeStorage) - .AddSingleton(new NetworkConfig()) - .AddSingleton(Substitute.For()) - .AddSingleton(MainnetSpecProvider.Instance) - .AddSingleton(BlockTree) - .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(NullReceiptStorage.Instance) - .AddSingleton(syncConfig) - .AddSingleton(poSSwitcher) - .AddSingleton(mergeConfig) - .AddSingleton(invalidChainTracker) - .AddSingleton(Substitute.For()) - .AddSingleton(new ChainSpec()) - .AddSingleton(reader) - .AddSingleton(Always.Valid) - .AddSingleton(Always.Valid) - .AddSingleton(Policy.FullGossip) - .AddSingleton(new BlockCacheService()) - .AddSingleton(_logManager); + .AddInstance(dbProvider) + .AddInstance(nodeStorage) + .AddInstance(new NetworkConfig()) + .AddInstance(Substitute.For()) + .AddInstance(MainnetSpecProvider.Instance) + .AddInstance(BlockTree) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(NullReceiptStorage.Instance) + .AddInstance(syncConfig) + .AddInstance(poSSwitcher) + .AddInstance(mergeConfig) + .AddInstance(invalidChainTracker) + .AddInstance(Substitute.For()) + .AddInstance(new ChainSpec()) + .AddInstance(reader) + .AddInstance(Always.Valid) + .AddInstance(Always.Valid) + .AddInstance(Policy.FullGossip) + .AddInstance(new BlockCacheService()) + .AddInstance(_logManager); builder.RegisterModule(new NetworkModule(new NetworkConfig(), syncConfig)); diff --git a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs index 68ef1ab1617..9143e6a059f 100644 --- a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs +++ b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs @@ -10,6 +10,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Extensions; using Nethermind.Logging; using Nethermind.Stats; From 4cf5b8a112b6a65e9335fa161b97ae53a70424b2 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 09:34:16 +0800 Subject: [PATCH 19/25] Addedcomponent keys --- src/Nethermind/Nethermind.Api/IApiWithStores.cs | 2 ++ .../ContainerBuilderExtensionsTests.cs | 7 ++++++- .../Nethermind.Core/Container/ComponentKeys.cs | 16 ++++++++++++++++ .../Container/ContainerBuilderExtensions.cs | 10 +++++++++- .../Nethermind.Network/Rlpx/RlpxHost.cs | 3 +++ 5 files changed, 36 insertions(+), 2 deletions(-) rename src/Nethermind/Nethermind.Core.Test/{ => Container}/ContainerBuilderExtensionsTests.cs (91%) create mode 100644 src/Nethermind/Nethermind.Core/Container/ComponentKeys.cs diff --git a/src/Nethermind/Nethermind.Api/IApiWithStores.cs b/src/Nethermind/Nethermind.Api/IApiWithStores.cs index 0c2b22135a4..ae7ff4f0e4a 100644 --- a/src/Nethermind/Nethermind.Api/IApiWithStores.cs +++ b/src/Nethermind/Nethermind.Api/IApiWithStores.cs @@ -27,6 +27,8 @@ public interface IApiWithStores : IBasicApi ILogFinder? LogFinder { get; set; } ISigner? EngineSigner { get; set; } ISignerStore? EngineSignerStore { get; set; } + + [ComponentKey(ComponentKey.NodeKey)] ProtectedPrivateKey? NodeKey { get; set; } IReceiptStorage? ReceiptStorage { get; set; } IReceiptFinder? ReceiptFinder { get; set; } diff --git a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs similarity index 91% rename from src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs rename to src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs index bed4017cf5a..d1b2c5567f9 100644 --- a/src/Nethermind/Nethermind.Core.Test/ContainerBuilderExtensionsTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Container/ContainerBuilderExtensionsTests.cs @@ -7,7 +7,7 @@ using Nethermind.Core.Container; using NUnit.Framework; -namespace Nethermind.Core.Test; +namespace Nethermind.Core.Test.Container; public class ContainerBuilderExtensionsTests { @@ -21,6 +21,7 @@ public void AddPropertiesFrom_CanAddProperties() sp.ResolveOptional().Should().NotBeNull(); sp.ResolveOptional().Should().BeNull(); + sp.ResolveOptionalKeyed(ComponentKey.NodeKey).Should().NotBeNull(); sp.ResolveOptional().Should().BeNull(); sp.ResolveOptional().Should().BeNull(); } @@ -80,6 +81,7 @@ 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 KeyedBaseService { get; set; } = new DeclaredInBase(); public DeclaredInBase BaseService { get; set; } = new DeclaredInBase(); } @@ -90,6 +92,9 @@ private interface ITestInterface : ITestInterfaceBase [SkipServiceCollection] Ignored IgnoredService { get; set; } + + [ComponentKey(ComponentKey.NodeKey)] + public DeclaredInBase KeyedBaseService { get; set; } } private interface ITestInterfaceBase diff --git a/src/Nethermind/Nethermind.Core/Container/ComponentKeys.cs b/src/Nethermind/Nethermind.Core/Container/ComponentKeys.cs new file mode 100644 index 00000000000..d638583c40b --- /dev/null +++ b/src/Nethermind/Nethermind.Core/Container/ComponentKeys.cs @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; + +namespace Nethermind.Core.Container; + +public enum ComponentKey +{ + NodeKey +} + +public class ComponentKeyAttribute(ComponentKey key) : Attribute +{ + public ComponentKey Key { get; } = key; +} diff --git a/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs index ab9c1b3aee8..560971cc336 100644 --- a/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs +++ b/src/Nethermind/Nethermind.Core/Container/ContainerBuilderExtensions.cs @@ -33,7 +33,15 @@ public static ContainerBuilder AddPropertiesFrom(this ContainerBuilder config object? val = propertyInfo.GetValue(source); if (val != null) { - configuration.RegisterInstance(val).As(propertyInfo.PropertyType); + ComponentKeyAttribute? componentKeyAttribute = propertyInfo.GetCustomAttribute(); + if (componentKeyAttribute != null) + { + configuration.RegisterInstance(val).Keyed(componentKeyAttribute.Key, propertyInfo.PropertyType); + } + else + { + configuration.RegisterInstance(val).As(propertyInfo.PropertyType); + } } } diff --git a/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs b/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs index 7292f7952ab..4478fddb068 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/RlpxHost.cs @@ -6,11 +6,13 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; +using Autofac.Features.AttributeFilters; using DotNetty.Common.Concurrency; using DotNetty.Handlers.Logging; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Crypto; @@ -47,6 +49,7 @@ public class RlpxHost : IRlpxHost public RlpxHost( IMessageSerializationService serializationService, + [KeyFilter(ComponentKey.NodeKey)] ProtectedPrivateKey nodeKey, INetworkConfig networkConfig, IHandshakeService handshakeService, From 962776034c0ea1d4cdc5846d2e496a5010a3dd91 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 11:24:06 +0800 Subject: [PATCH 20/25] Fix some tests --- .../Container/FallbackToFieldFromApiTests.cs | 20 ++++++++++++++++ .../Container/FallbackToFieldFromApi.cs | 24 ++++++++++++++++++- .../Rlpx/Handshake/HandshakeService.cs | 4 +++- .../Ethereum/ContextWithMocks.cs | 3 ++- .../Modules/BaseModuleTests.cs | 19 ++++++++------- .../Nethermind.Runner/Modules/BaseModule.cs | 3 --- 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs index c0f137056ef..ea110d53982 100644 --- a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs @@ -30,6 +30,19 @@ public void CanResolveFieldWithTypeWhenSetLater() container.Resolve().Should().NotBeNull(); } + [Test] + public void CanResolveFieldWithKey() + { + ContainerBuilder containerBuilder = new ContainerBuilder(); + containerBuilder.AddSingleton(); + containerBuilder.RegisterSource(new FallbackToFieldFromApi()); + + IContainer container = containerBuilder.Build(); + container.Resolve().NamedTargetService = new NamedTargetService(); + container.TryResolve(out NamedTargetService? _).Should().BeFalse(); + container.TryResolveKeyed(ComponentKey.NodeKey, out NamedTargetService? _).Should().BeFalse(); + } + [Test] public void ThrowExceptionIfTargetIsAlsoRegisterec() { @@ -46,11 +59,14 @@ public void ThrowExceptionIfTargetIsAlsoRegisterec() public interface IApi { + [ComponentKey(ComponentKey.NodeKey)] + public NamedTargetService NamedTargetService { get; set; } public TargetService TargetService { get; set; } } public class Api: IApi { + public NamedTargetService NamedTargetService { get; set; } = null!; public TargetService TargetService { get; set; } = null!; } @@ -58,4 +74,8 @@ public class TargetService { } + public class NamedTargetService + { + } + } diff --git a/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs index 4d64e71b0d1..db45b2dea32 100644 --- a/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs +++ b/src/Nethermind/Nethermind.Core/Container/FallbackToFieldFromApi.cs @@ -46,7 +46,7 @@ public IEnumerable RegistrationsFor(Service service, Fun throw new ArgumentNullException(nameof(registrationAccessor)); } - TypedService? ts = service as TypedService; + IServiceWithType? ts = service as IServiceWithType; if (ts == null || ts.ServiceType == typeof(string)) { return Enumerable.Empty(); @@ -75,11 +75,33 @@ public IEnumerable RegistrationsFor(Service service, Fun return Enumerable.Empty(); } + ComponentKeyAttribute? keyAttribute = property.GetCustomAttribute(); + if (keyAttribute is not null) + { + if (ts is not KeyedService keyedService) + { + // not a keyed service + return Enumerable.Empty(); + } + + if (!keyedService.ServiceKey.Equals(keyAttribute.Key)) + { + // Different key + return Enumerable.Empty(); + } + } + IRegistrationBuilder builder = RegistrationBuilder.ForDelegate(serviceType, (ctx, reg) => { TApi baseT = ctx.Resolve(); return property.GetValue(baseT)!; }); + + if (keyAttribute is not null) + { + return new[] { builder.Keyed(keyAttribute.Key, serviceType).CreateRegistration() }; + } + return new[] { builder.CreateRegistration() }; } diff --git a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs index fe7a046c3a9..55baa206b1b 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using Autofac.Features.AttributeFilters; using DotNetty.Buffers; using DotNetty.Common.Utilities; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Crypto; @@ -34,7 +36,7 @@ public HandshakeService( IEciesCipher eciesCipher, ICryptoRandom cryptoRandom, IEcdsa ecdsa, - ProtectedPrivateKey privateKey, + [KeyFilter(ComponentKey.NodeKey)] ProtectedPrivateKey privateKey, ILogManager logManager) : this(messageSerializationService, eciesCipher, cryptoRandom, ecdsa, privateKey.Unprotect(), logManager) { diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs index 80b18b3d144..9b03d4b11ed 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/ContextWithMocks.cs @@ -79,7 +79,6 @@ public static NethermindApi ContextWithMocks(INetworkConfig? networkConfig = nul .AddInstance(Substitute.For()); // need more complete chainspec to use ISpecProvider containerConfigurer?.Invoke(containerBuilder); - IContainer container = containerBuilder.Build(); var api = container.Resolve(); @@ -131,6 +130,8 @@ public static NethermindApi ContextWithMocks(INetworkConfig? networkConfig = nul api.BadBlocksStore = Substitute.For(); api.WorldStateManager = new ReadOnlyWorldStateManager(api.DbProvider, Substitute.For(), LimboLogs.Instance); api.NodeStorageFactory = new NodeStorageFactory(INodeStorage.KeyScheme.HalfPath, LimboLogs.Instance); + api.NodeKey = new ProtectedPrivateKey(TestItem.PrivateKeyA, Path.GetTempPath()); + api.ConfigProvider.GetConfig().Returns(syncConfig ?? new SyncConfig()); // The default get config substitute set nullable string to empty string causing issues. return (NethermindApi)api; } diff --git a/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs b/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs index 802f8a5a239..c14a0323b49 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Modules/BaseModuleTests.cs @@ -5,6 +5,7 @@ using FluentAssertions; using Nethermind.Api; using Nethermind.Config; +using Nethermind.Core.Container; using Nethermind.Logging; using Nethermind.Runner.Modules; using Nethermind.Serialization.Json; @@ -28,15 +29,15 @@ public void Can_Resolve() configProvider.GetConfig().Returns(new InitConfig()); logManager.GetClassLogger(typeof(TestClass)).Returns(LimboLogs.Instance.GetClassLogger()); - ContainerBuilder builder = new ContainerBuilder(); - builder.RegisterInstance(configProvider); - builder.RegisterInstance(processExitSource); - builder.RegisterInstance(chainSpec); - builder.RegisterInstance(jsonSerializer); - builder.RegisterInstance(logManager); - builder.RegisterModule(new BaseModule()); - - using IContainer container = builder.Build(); + using IContainer container = new ContainerBuilder() + .AddInstance(configProvider) + .AddInstance(processExitSource) + .AddInstance(chainSpec) + .AddInstance(jsonSerializer) + .AddInstance(logManager) + .AddModule(new BaseModule()) + .AddSingleton() + .Build(); TestClass testObj = container.Resolve(); testObj.Logger.Should().NotBeNull(); diff --git a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs index 52a0178395d..416a7e454a1 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/BaseModule.cs @@ -37,9 +37,6 @@ protected override void Load(ContainerBuilder builder) { base.Load(builder); - // Maybe this should not be used? as it can be error prone. - builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); - builder.RegisterSource(new ConfigRegistrationSource()); LoggerMiddleware.Configure(builder); From d3e89c25a13a24a9df6cbfeab24d9557b6752ae0 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 11:33:29 +0800 Subject: [PATCH 21/25] Minor cleanup --- .../Blockchain/TestBlockchain.cs | 5 +-- .../Steps/IEthereumRunnerStep.cs | 5 +-- .../AuRaMergeEngineModuleTests.cs | 18 +++++---- .../Steps/EthereumStepsManagerTests.cs | 38 +++++++++---------- .../Ethereum/Api/ApiBuilder.cs | 38 +++++++++---------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs index 0560d782177..cda827eb468 100644 --- a/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs +++ b/src/Nethermind/Nethermind.Core.Test/Blockchain/TestBlockchain.cs @@ -263,10 +263,9 @@ protected virtual async Task Build(ISpecProvider? specProvider = protected virtual void ConfigureContainer(ContainerBuilder builder) { - builder.RegisterModule(new BaseModule()); - builder.RegisterModule(new CoreModule()); - builder + .AddModule(new BaseModule()) + .AddModule(new CoreModule()) .AddInstance(SpecProvider) .AddInstance(LogManager) .AddInstance(new ConfigProvider()); diff --git a/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs b/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs index c36f3418a12..3ddff573e3c 100644 --- a/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs +++ b/src/Nethermind/Nethermind.Init/Steps/IEthereumRunnerStep.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Autofac; using Autofac.Features.AttributeFilters; +using Nethermind.Core.Container; namespace Nethermind.Init.Steps { @@ -38,9 +39,7 @@ public static ContainerBuilder AddIStep(this ContainerBuilder builder, Type step .WithAttributeFiltering(); StepInfo info = new StepInfo(stepType, GetStepBaseType(stepType)); - builder.RegisterInstance(info); - - return builder; + return builder.AddInstance(info); } private static bool IsStepType(Type t) => !t.IsInterface && !t.IsAbstract && typeof(IStep).IsAssignableFrom((Type?)(Type?)t); diff --git a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs index 3b904bf5882..93d1ac7705d 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa.Test/AuRaMergeEngineModuleTests.cs @@ -21,6 +21,7 @@ using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Transactions; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; using Nethermind.Core.Test.Blockchain; @@ -123,15 +124,16 @@ protected override Task Build(ISpecProvider? specProvider = null protected override void ConfigureContainer(ContainerBuilder builder) { base.ConfigureContainer(builder); - builder.RegisterInstance(new ChainSpec - { - AuRa = new() + builder + .AddInstance(new ChainSpec { - WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") - }, - Parameters = new() - }); - builder.RegisterModule(new AuraModule()); + AuRa = new() + { + WithdrawalContractAddress = new("0xbabe2bed00000000000000000000000000000003") + }, + Parameters = new() + }) + .AddModule(new AuraModule()); } protected override IBlockProcessor CreateBlockProcessor() diff --git a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs index 793327cb84c..6400a9b64f5 100644 --- a/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/Ethereum/Steps/EthereumStepsManagerTests.cs @@ -9,6 +9,7 @@ using FluentAssertions; using FluentAssertions.Execution; using Nethermind.Api; +using Nethermind.Core.Container; using Nethermind.Init.Steps; using Nethermind.Logging; using Nethermind.Runner.Modules; @@ -82,11 +83,10 @@ public async Task With_failing_steps() private static ContainerBuilder CreateBaseContainerBuilder() { - var builder = new ContainerBuilder(); - builder.RegisterInstance(LimboLogs.Instance).AsImplementedInterfaces(); - builder.RegisterModule(new BaseModule()); - builder.RegisterModule(new RunnerModule()); - return builder; + return new ContainerBuilder() + .AddInstance(LimboLogs.Instance) + .AddModule(new BaseModule()) + .AddModule(new RunnerModule()); } private static IContainer CreateEmptyContainer() @@ -97,23 +97,23 @@ private static IContainer CreateEmptyContainer() private static IContainer CreateNethermindApi() { - ContainerBuilder builder = CreateBaseContainerBuilder(); - builder.AddIStep(typeof(StepLong)); - builder.AddIStep(typeof(StepForever)); - builder.AddIStep(typeof(StepA)); - builder.AddIStep(typeof(StepB)); - builder.AddIStep(typeof(StepCStandard)); - return builder.Build(); + return CreateBaseContainerBuilder() + .AddIStep(typeof(StepLong)) + .AddIStep(typeof(StepForever)) + .AddIStep(typeof(StepA)) + .AddIStep(typeof(StepB)) + .AddIStep(typeof(StepCStandard)) + .Build(); } private static IContainer CreateAuraApi() { - ContainerBuilder builder = CreateBaseContainerBuilder(); - builder.AddIStep(typeof(StepLong)); - builder.AddIStep(typeof(StepForever)); - builder.AddIStep(typeof(StepA)); - builder.AddIStep(typeof(StepB)); - builder.AddIStep(typeof(StepCAuRa)); - return builder.Build(); + return CreateBaseContainerBuilder() + .AddIStep(typeof(StepLong)) + .AddIStep(typeof(StepForever)) + .AddIStep(typeof(StepA)) + .AddIStep(typeof(StepB)) + .AddIStep(typeof(StepCAuRa)) + .Build(); } } diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 86bfd346e51..6e93378b103 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -52,18 +52,17 @@ public IContainer Create(IEnumerable plugins) throw new NotSupportedException("Creation of multiple APIs not supported."); } - ContainerBuilder containerBuilder = new ContainerBuilder(); - containerBuilder.RegisterInstance(_configProvider).SingleInstance(); - containerBuilder.RegisterInstance(_processExitSource).SingleInstance(); - containerBuilder.RegisterInstance(_jsonSerializer).SingleInstance(); - containerBuilder.RegisterInstance(_logManager).SingleInstance(); - containerBuilder.RegisterInstance(chainSpec).SingleInstance(); - - containerBuilder.RegisterModule(new BaseModule()); - containerBuilder.RegisterModule(new CoreModule()); - containerBuilder.RegisterModule(new RunnerModule()); - containerBuilder.RegisterModule(new NetworkModule(_configProvider.GetConfig(), _configProvider.GetConfig())); - containerBuilder.RegisterModule(new DbModule()); + ContainerBuilder containerBuilder = new ContainerBuilder() + .AddInstance(_configProvider) + .AddInstance(_processExitSource) + .AddInstance(_jsonSerializer) + .AddInstance(_logManager) + .AddInstance(chainSpec) + .AddModule(new BaseModule()) + .AddModule(new CoreModule()) + .AddModule(new RunnerModule()) + .AddModule(new NetworkModule(_configProvider.GetConfig(), _configProvider.GetConfig())) + .AddModule(new DbModule()); ApplyPluginModule(plugins, chainSpec, containerBuilder); return containerBuilder.Build(); @@ -71,13 +70,14 @@ public IContainer Create(IEnumerable plugins) private void ApplyPluginModule(IEnumerable plugins, ChainSpec chainSpec, ContainerBuilder containerBuilder) { - ContainerBuilder pluginLoaderBuilder = new ContainerBuilder(); - pluginLoaderBuilder.RegisterInstance(_configProvider).SingleInstance(); - pluginLoaderBuilder.RegisterInstance(_processExitSource).SingleInstance(); - pluginLoaderBuilder.RegisterInstance(_jsonSerializer).SingleInstance(); - pluginLoaderBuilder.RegisterInstance(_logManager).SingleInstance(); - pluginLoaderBuilder.RegisterInstance(chainSpec).SingleInstance(); - pluginLoaderBuilder.RegisterModule(new BaseModule()); + ContainerBuilder pluginLoaderBuilder = new ContainerBuilder() + .AddInstance(_configProvider) + .AddInstance(_processExitSource) + .AddInstance(_jsonSerializer) + .AddInstance(_logManager) + .AddInstance(chainSpec) + .AddModule(new BaseModule()); + foreach (Type plugin in plugins) { pluginLoaderBuilder.RegisterType(plugin) From 4e64380adbfc5cf040c4ac03bc87ac6c1f74ec73 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 11:37:28 +0800 Subject: [PATCH 22/25] Fix ambiguous ProtectedPrivateKey --- src/Nethermind/Nethermind.Api/IBasicApi.cs | 1 + .../Nethermind.Network.Discovery/CompositeDiscoveryApp.cs | 4 +++- .../Nethermind.Network/Rlpx/Handshake/HandshakeService.cs | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Api/IBasicApi.cs b/src/Nethermind/Nethermind.Api/IBasicApi.cs index f96efd59989..7f86a540935 100644 --- a/src/Nethermind/Nethermind.Api/IBasicApi.cs +++ b/src/Nethermind/Nethermind.Api/IBasicApi.cs @@ -40,6 +40,7 @@ public interface IBasicApi IFileSystem FileSystem { get; set; } IKeyStore? KeyStore { get; set; } ILogManager LogManager { get; set; } + [SkipServiceCollection] ProtectedPrivateKey? OriginalSignerKey { get; set; } IReadOnlyList Plugins { get; } [SkipServiceCollection] diff --git a/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs b/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs index f7013d14c6b..f25e44e670f 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/CompositeDiscoveryApp.cs @@ -3,11 +3,13 @@ using System.Net.Sockets; using System.Runtime.InteropServices; +using Autofac.Features.AttributeFilters; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using Nethermind.Api; using Nethermind.Core; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Crypto; using Nethermind.Db; @@ -48,7 +50,7 @@ public class CompositeDiscoveryApp : IDiscoveryApp private IDiscoveryApp? _v5; private INodeSource _compositeNodeSource = null!; - public CompositeDiscoveryApp(ProtectedPrivateKey? nodeKey, + public CompositeDiscoveryApp([KeyFilter(ComponentKey.NodeKey)] ProtectedPrivateKey? nodeKey, INetworkConfig networkConfig, IDiscoveryConfig discoveryConfig, IInitConfig initConfig, IEthereumEcdsa? ethereumEcdsa, IMessageSerializationService? serializationService, ILogManager? logManager, ITimestamper? timestamper, ICryptoRandom? cryptoRandom, diff --git a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs index fe7a046c3a9..55baa206b1b 100644 --- a/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs +++ b/src/Nethermind/Nethermind.Network/Rlpx/Handshake/HandshakeService.cs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using Autofac.Features.AttributeFilters; using DotNetty.Buffers; using DotNetty.Common.Utilities; +using Nethermind.Core.Container; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Crypto; @@ -34,7 +36,7 @@ public HandshakeService( IEciesCipher eciesCipher, ICryptoRandom cryptoRandom, IEcdsa ecdsa, - ProtectedPrivateKey privateKey, + [KeyFilter(ComponentKey.NodeKey)] ProtectedPrivateKey privateKey, ILogManager logManager) : this(messageSerializationService, eciesCipher, cryptoRandom, ecdsa, privateKey.Unprotect(), logManager) { From 7986dc2c4305d6d95e8d7336649becdac21d9aee Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 11:54:22 +0800 Subject: [PATCH 23/25] Add back aura plugin tests --- .../Nethermind.AuRa.Test/AuRaPluginTests.cs | 41 +++++++++++++++++++ .../Nethermind.AuRa.Test.csproj | 1 + 2 files changed, 42 insertions(+) create mode 100644 src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs diff --git a/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs b/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs new file mode 100644 index 00000000000..58be05444e2 --- /dev/null +++ b/src/Nethermind/Nethermind.AuRa.Test/AuRaPluginTests.cs @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using FluentAssertions; +using Microsoft.FSharp.Core; +using Nethermind.Api; +using Nethermind.Config; +using Nethermind.Consensus.AuRa; +using Nethermind.Consensus.AuRa.InitializationSteps; +using Nethermind.Core; +using Nethermind.Core.Container; +using Nethermind.Core.Test.Builders; +using Nethermind.Logging; +using Nethermind.Serialization.Json; +using Nethermind.Specs.ChainSpecStyle; +using NUnit.Framework; + +namespace Nethermind.AuRa.Test +{ + public class AuRaPluginTests + { + [Test] + public void Init_when_not_AuRa_doesnt_trow() + { + ChainSpec chainSpec = new ChainSpec() + { + SealEngineType = SealEngineType.AuRa + }; + AuRaPlugin auRaPlugin = new(chainSpec); + + NethermindApi api = Runner.Test.Ethereum.Build.ContextWithMocks(containerConfigurer: (builder) => + { + builder.AddModule(auRaPlugin.ContainerModule!); + }); + + Action init = () => auRaPlugin.Init(api); + init.Should().NotThrow(); + } + } +} diff --git a/src/Nethermind/Nethermind.AuRa.Test/Nethermind.AuRa.Test.csproj b/src/Nethermind/Nethermind.AuRa.Test/Nethermind.AuRa.Test.csproj index aa8bb0c1427..0b0c1dd3230 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Nethermind.AuRa.Test.csproj +++ b/src/Nethermind/Nethermind.AuRa.Test/Nethermind.AuRa.Test.csproj @@ -25,6 +25,7 @@ + From 11a687b02a0ff87fd55b1e6afde2df24ee0bbd57 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Fri, 18 Oct 2024 12:37:45 +0800 Subject: [PATCH 24/25] Whitespace --- .../Nethermind.Analytics/AnalyticsPlugin.cs | 2 +- .../Container/FallbackToFieldFromApiTests.cs | 2 +- .../EthStatsPluginTests.cs | 2 +- .../Steps/InitializeNetwork.cs | 20 +++++++++---------- .../Nethermind.Merge.AuRa/AuRaMergePlugin.cs | 2 +- .../OptimismPoSSwitcher.cs | 2 +- .../Nethermind.Runner/Modules/DbModule.cs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs index 71df7df3ce1..27c415208fe 100644 --- a/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs +++ b/src/Nethermind/Nethermind.Analytics/AnalyticsPlugin.cs @@ -26,7 +26,7 @@ public class AnalyticsPlugin(IAnalyticsConfig analyticsConfig, IInitConfig initC public string Author => "Nethermind"; - public bool Enabled =>initConfig.WebSocketsEnabled && + public bool Enabled => initConfig.WebSocketsEnabled && (analyticsConfig.PluginsEnabled || analyticsConfig.StreamBlocks || analyticsConfig.StreamTransactions); diff --git a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs index ea110d53982..15e0c5b0df6 100644 --- a/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Container/FallbackToFieldFromApiTests.cs @@ -64,7 +64,7 @@ public interface IApi public TargetService TargetService { get; set; } } - public class Api: IApi + public class Api : IApi { public NamedTargetService NamedTargetService { get; set; } = null!; public TargetService TargetService { get; set; } = null!; diff --git a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs index 832ac20ec64..3ec5c01fd2e 100644 --- a/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs +++ b/src/Nethermind/Nethermind.EthStats.Test/EthStatsPluginTests.cs @@ -20,7 +20,7 @@ public class EthStatsPluginTests public void Setup() { _context = Build.ContextWithMocks(); - _plugin = new EthStatsPlugin(new EthStatsConfig() { Enabled = true}); + _plugin = new EthStatsPlugin(new EthStatsConfig() { Enabled = true }); } [TearDown] diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 023ddd59e8b..4493be952a8 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -111,16 +111,16 @@ private async Task Initialize(CancellationToken cancellationToken) SyncedTxGossipPolicy txGossipPolicy = _api.BaseContainer.Resolve(); ISyncServer _ = _api.BaseContainer.Resolve(); IDiscoveryApp discoveryApp = _api.BaseContainer.Resolve(); - IPeerPool peerPool = _api.BaseContainer.Resolve(); - IPeerManager peerManager = _api.BaseContainer.Resolve(); - ISessionMonitor sessionMonitor = _api.BaseContainer.Resolve(); - IRlpxHost rlpxHost = _api.BaseContainer.Resolve(); - IStaticNodesManager staticNodesManager = _api.BaseContainer.Resolve(); - Func nodeSourceToDiscV4Feeder = _api.BaseContainer.Resolve>(); - IProtocolsManager protocolsManager = _api.BaseContainer.Resolve(); - SnapCapabilitySwitcher snapCapabilitySwitcher = _api.BaseContainer.Resolve(); - ISyncPeerPool syncPeerPool = _api.BaseContainer.Resolve(); - ISynchronizer synchronizer = _api.BaseContainer.Resolve(); + IPeerPool peerPool = _api.BaseContainer.Resolve(); + IPeerManager peerManager = _api.BaseContainer.Resolve(); + ISessionMonitor sessionMonitor = _api.BaseContainer.Resolve(); + IRlpxHost rlpxHost = _api.BaseContainer.Resolve(); + IStaticNodesManager staticNodesManager = _api.BaseContainer.Resolve(); + Func nodeSourceToDiscV4Feeder = _api.BaseContainer.Resolve>(); + IProtocolsManager protocolsManager = _api.BaseContainer.Resolve(); + SnapCapabilitySwitcher snapCapabilitySwitcher = _api.BaseContainer.Resolve(); + ISyncPeerPool syncPeerPool = _api.BaseContainer.Resolve(); + ISynchronizer synchronizer = _api.BaseContainer.Resolve(); _api.TxGossipPolicy.Policies.Add(txGossipPolicy); diff --git a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs index c69476e82a2..4bb51f2b410 100644 --- a/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.AuRa/AuRaMergePlugin.cs @@ -88,7 +88,7 @@ protected override IBlockFinalizationManager InitializeMergeFinilizationManager( _poSSwitcher); } - private class AuraMergeModule: Module + private class AuraMergeModule : Module { protected override void Load(ContainerBuilder builder) { diff --git a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs index ef1b39f97b2..be848008989 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismPoSSwitcher.cs @@ -9,7 +9,7 @@ public class OptimismPoSSwitcher(ISpecProvider specProvider, long bedrockBlockNumber) : IPoSSwitcher { - public OptimismPoSSwitcher(ISpecProvider specProvider, ChainSpec chainSpec): this(specProvider, chainSpec.Optimism.BedrockBlockNumber) + public OptimismPoSSwitcher(ISpecProvider specProvider, ChainSpec chainSpec) : this(specProvider, chainSpec.Optimism.BedrockBlockNumber) { } diff --git a/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs b/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs index 1d37554089b..d4745e5bf4c 100644 --- a/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs +++ b/src/Nethermind/Nethermind.Runner/Modules/DbModule.cs @@ -8,7 +8,7 @@ namespace Nethermind.Runner.Modules; -public class DbModule: Module +public class DbModule : Module { protected override void Load(ContainerBuilder builder) { From 18ad3f596429983b98341cc8e9cb56ffcf672632 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Mon, 28 Oct 2024 19:09:59 +0800 Subject: [PATCH 25/25] Add unit test for resolve --- .../Steps/InitializeNetwork.cs | 13 ++-- .../EthereumRunnerTests.cs | 76 +++++++++++++++++++ .../Ethereum/Api/ApiBuilder.cs | 3 - 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs index 4493be952a8..f419e6f4db2 100644 --- a/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs +++ b/src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs @@ -94,9 +94,6 @@ private async Task Initialize(CancellationToken cancellationToken) NetworkDiagTracer.Start(_api.LogManager); } - if (_api.ChainSpec.SealEngineType == SealEngineType.Clique) - _syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself? - int maxPeersCount = _networkConfig.ActivePeersMaxCount; Network.Metrics.PeerLimit = maxPeersCount; @@ -106,8 +103,7 @@ private async Task Initialize(CancellationToken cancellationToken) await plugin.InitSynchronization(); } - // TODO: This whole thing can be injected into `InitializeNetwork`, but the container then - // need to be put at a higher level. + // TODO: Plugins can change something in `InitSynchronization`, so these need to be delayed SyncedTxGossipPolicy txGossipPolicy = _api.BaseContainer.Resolve(); ISyncServer _ = _api.BaseContainer.Resolve(); IDiscoveryApp discoveryApp = _api.BaseContainer.Resolve(); @@ -305,6 +301,13 @@ protected override void Load(ContainerBuilder builder) { base.Load(builder); + builder + .RegisterBuildCallback(ctx => + { + if (ctx.Resolve().SealEngineType == SealEngineType.Clique) + syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself? + }); + builder.RegisterModule(new SynchronizerModule(syncConfig)); builder diff --git a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs index 11054575346..5b1f3c99b34 100644 --- a/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs +++ b/src/Nethermind/Nethermind.Runner.Test/EthereumRunnerTests.cs @@ -7,14 +7,21 @@ using System.Collections.Concurrent; using System.IO; using System.IO.Abstractions; +using System.Net; using System.Runtime.Loader; using System.Threading; using System.Threading.Tasks; using Autofac; using Nethermind.Api; +using Nethermind.Blockchain.Receipts; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; +using Nethermind.Consensus.Scheduler; +using Nethermind.Consensus.Validators; +using Nethermind.Core.Test.Builders; using Nethermind.Core.Test.IO; +using Nethermind.Crypto; +using Nethermind.Db; using Nethermind.Db.Rocks.Config; using Nethermind.EthStats; using Nethermind.JsonRpc; @@ -24,7 +31,17 @@ using Nethermind.Network.Config; using Nethermind.Runner.Ethereum; using Nethermind.Db.Blooms; +using Nethermind.Init.Steps; +using Nethermind.Network; +using Nethermind.Network.Discovery; +using Nethermind.Network.Rlpx; using Nethermind.Runner.Ethereum.Api; +using Nethermind.State; +using Nethermind.Synchronization; +using Nethermind.Synchronization.ParallelSync; +using Nethermind.Synchronization.Peers; +using Nethermind.Trie; +using Nethermind.Trie.Pruning; using Nethermind.TxPool; using NSubstitute; using NUnit.Framework; @@ -98,6 +115,65 @@ public async Task Smoke_cancel((string file, ConfigProvider configProvider) test await SmokeTest(testCase.configProvider, testIndex, 30430, true); } + [TestCaseSource(nameof(ChainSpecRunnerTests))] + public void BuildTest((string file, ConfigProvider configProvider) testCase, int _) + { + if (testCase.configProvider is null) + { + // some weird thing, not worth investigating + return; + } + + using IContainer container = new ApiBuilder(testCase.configProvider, Substitute.For(), LimboLogs.Instance) + .Create(Array.Empty()); + + { + // Ideally, we don't have any of there blocks. + INethermindApi nethermindApi = container.Resolve(); + nethermindApi.BlockTree = Build.A.BlockTree().OfChainLength(1).TestObject; + nethermindApi.StateReader = Substitute.For(); + nethermindApi.NodeStorageFactory = new NodeStorageFactory(INodeStorage.KeyScheme.Current, LimboLogs.Instance); + nethermindApi.DbProvider = TestMemDbProvider.Init(); + nethermindApi.ReceiptStorage = Substitute.For(); + nethermindApi.ReceiptFinder = Substitute.For(); + nethermindApi.BlockValidator = Substitute.For(); + nethermindApi.NodeKey = new ProtectedPrivateKey(TestItem.PrivateKeyA, Path.GetTempPath()); + nethermindApi.EthereumEcdsa = new EthereumEcdsa(0); + nethermindApi.BackgroundTaskScheduler = Substitute.For(); + nethermindApi.TxPool = Substitute.For(); + nethermindApi.TrieStore = Substitute.For(); + + IIPResolver ipResolver = Substitute.For(); + ipResolver.ExternalIp.Returns(IPAddress.Loopback); + nethermindApi.IpResolver = ipResolver; + + INetworkConfig networkConfig = container.Resolve(); + networkConfig.ExternalIp = "127.0.0.1"; + networkConfig.LocalIp = "127.0.0.1"; + } + + container.Resolve(); + foreach (StepInfo loadStep in container.Resolve().LoadSteps()) + { + container.Resolve(loadStep.StepType); + } + + // TODO: Ideally, these should not be here and declared in the constructor of the steps. But until we stop + // resolving things manually because of steps manually updating api, we can't really do much. + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + container.Resolve>(); + container.Resolve(); + container.Resolve(); + container.Resolve(); + } + private static async Task SmokeTest(ConfigProvider configProvider, int testIndex, int basePort, bool cancel = false) { Type type1 = typeof(ITxPoolConfig); diff --git a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs index 6e93378b103..9f06dd8a3b4 100644 --- a/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs +++ b/src/Nethermind/Nethermind.Runner/Ethereum/Api/ApiBuilder.cs @@ -4,17 +4,14 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading; using Autofac; using Nethermind.Api; using Nethermind.Api.Extensions; using Nethermind.Blockchain.Synchronization; using Nethermind.Config; -using Nethermind.Consensus; using Nethermind.Core; using Nethermind.Core.Container; -using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Init.Steps; using Nethermind.Logging; using Nethermind.Network.Config;