public async Task Init() { if (_isInitialized) { throw new InvalidOperationException($"{nameof(PeerManager)} already initialized."); } _isInitialized = true; try { _bossGroup = new MultithreadEventLoopGroup(); _workerGroup = new MultithreadEventLoopGroup(); ServerBootstrap bootstrap = new(); bootstrap .Group(_bossGroup, _workerGroup) .Channel <TcpServerSocketChannel>() .ChildOption(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler("BOSS", LogLevel.TRACE)) .ChildHandler(new ActionChannelInitializer <ISocketChannel>(ch => { Session session = new(LocalPort, ch, _disconnectsAnalyzer, _logManager); session.RemoteHost = ((IPEndPoint)ch.RemoteAddress).Address.ToString(); session.RemotePort = ((IPEndPoint)ch.RemoteAddress).Port; InitializeChannel(ch, session); })); _bootstrapChannel = await bootstrap.BindAsync(LocalPort).ContinueWith(t => { if (t.IsFaulted) { AggregateException aggregateException = t.Exception; if (aggregateException?.InnerException is SocketException socketException && socketException.ErrorCode == 10048) { if (_logger.IsError) { _logger.Error($"Port {LocalPort} is in use. You can change the port used by adding: --{nameof(NetworkConfig).Replace("Config", "")}.{nameof(NetworkConfig.P2PPort)} 30303"); } } else { if (_logger.IsError) { _logger.Error($"{nameof(Init)} failed", t.Exception); } } return(null); } return(t.Result); }); if (_bootstrapChannel == null) { throw new NetworkingException($"Failed to initialize {nameof(_bootstrapChannel)}", NetworkExceptionType.Other); } }
protected async Task StartRunners(IConfigProvider configProvider) { IInitConfig initConfig = configProvider.GetConfig <IInitConfig>(); IJsonRpcConfig jsonRpcConfig = configProvider.GetConfig <IJsonRpcConfig>(); var metricOptions = configProvider.GetConfig <IMetricsConfig>(); var logManager = new NLogManager(initConfig.LogFileName, initConfig.LogDirectory); IRpcModuleProvider rpcModuleProvider = jsonRpcConfig.Enabled ? new RpcModuleProvider(configProvider.GetConfig <IJsonRpcConfig>(), logManager) : (IRpcModuleProvider)NullModuleProvider.Instance; var jsonSerializer = new EthereumJsonSerializer(); var webSocketsManager = new WebSocketsManager(); if (metricOptions.Enabled) { var intervalSeconds = metricOptions.IntervalSeconds; _monitoringService = new MonitoringService(new MetricsUpdater(intervalSeconds), metricOptions.PushGatewayUrl, ClientVersion.Description, metricOptions.NodeName, intervalSeconds, logManager); _monitoringService.RegisterMetrics(typeof(Nethermind.JsonRpc.Metrics)); _monitoringService.RegisterMetrics(typeof(Nethermind.Store.Metrics)); _monitoringService.RegisterMetrics(typeof(Nethermind.Evm.Metrics)); _monitoringService.RegisterMetrics(typeof(Nethermind.Blockchain.Metrics)); _monitoringService.RegisterMetrics(typeof(Nethermind.Network.Metrics)); await _monitoringService.StartAsync().ContinueWith(x => { if (x.IsFaulted && Logger.IsError) { Logger.Error("Error during starting a monitoring.", x.Exception); } }); } else { if (Logger.IsInfo) { Logger.Info("Monitoring is disabled"); } } INdmDataPublisher ndmDataPublisher = null; INdmConsumerChannelManager ndmConsumerChannelManager = null; INdmInitializer ndmInitializer = null; var ndmConfig = configProvider.GetConfig <INdmConfig>(); var ndmEnabled = ndmConfig.Enabled; if (ndmEnabled) { ndmDataPublisher = new NdmDataPublisher(); ndmConsumerChannelManager = new NdmConsumerChannelManager(); var initializerName = ndmConfig.InitializerName; if (Logger.IsInfo) { Logger.Info($"NDM initializer: {initializerName}"); } var ndmInitializerType = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes()) .FirstOrDefault(t => t.GetCustomAttribute <NdmInitializerAttribute>()?.Name == initializerName); var ndmModule = new NdmModule(); var ndmConsumersModule = new NdmConsumersModule(); ndmInitializer = new NdmInitializerFactory(ndmInitializerType, ndmModule, ndmConsumersModule, logManager).CreateOrFail(); } var grpcConfig = configProvider.GetConfig <IGrpcConfig>(); GrpcServer grpcServer = null; if (grpcConfig.Enabled) { grpcServer = new GrpcServer(jsonSerializer, logManager); if (ndmEnabled) { ndmConsumerChannelManager.Add(new GrpcNdmConsumerChannel(grpcServer)); } _grpcRunner = new GrpcRunner(grpcServer, grpcConfig, logManager); await _grpcRunner.Start().ContinueWith(x => { if (x.IsFaulted && Logger.IsError) { Logger.Error("Error during GRPC runner start", x.Exception); } }); } if (initConfig.WebSocketsEnabled) { if (ndmEnabled) { webSocketsManager.AddModule(new NdmWebSocketsModule(ndmConsumerChannelManager, ndmDataPublisher, jsonSerializer)); } } _ethereumRunner = new EthereumRunner(rpcModuleProvider, configProvider, logManager, grpcServer, ndmConsumerChannelManager, ndmDataPublisher, ndmInitializer, webSocketsManager, jsonSerializer, _monitoringService); await _ethereumRunner.Start().ContinueWith(x => { if (x.IsFaulted && Logger.IsError) { Logger.Error("Error during ethereum runner start", x.Exception); } }); if (jsonRpcConfig.Enabled) { rpcModuleProvider.Register(new SingletonModulePool <IWeb3Module>(new Web3Module(logManager), true)); var jsonRpcService = new JsonRpcService(rpcModuleProvider, logManager); var jsonRpcProcessor = new JsonRpcProcessor(jsonRpcService, jsonSerializer, jsonRpcConfig, logManager); if (initConfig.WebSocketsEnabled) { webSocketsManager.AddModule(new JsonRpcWebSocketsModule(jsonRpcProcessor, jsonSerializer)); } Bootstrap.Instance.JsonRpcService = jsonRpcService; Bootstrap.Instance.LogManager = logManager; Bootstrap.Instance.JsonSerializer = jsonSerializer; _jsonRpcRunner = new JsonRpcRunner(configProvider, rpcModuleProvider, logManager, jsonRpcProcessor, webSocketsManager); await _jsonRpcRunner.Start().ContinueWith(x => { if (x.IsFaulted && Logger.IsError) { Logger.Error("Error during jsonRpc runner start", x.Exception); } }); } else { if (Logger.IsInfo) { Logger.Info("Json RPC is disabled"); } } }
private static void Run(string[] args) { _logger.Info("Nethermind starting initialization."); AppDomain.CurrentDomain.ProcessExit += CurrentDomainOnProcessExit; IFileSystem fileSystem = new FileSystem();; PluginLoader pluginLoader = new PluginLoader( "plugins", fileSystem, typeof(CliquePlugin), typeof(EthashPlugin), typeof(NethDevPlugin)); pluginLoader.Load(SimpleConsoleLogManager.Instance); Type configurationType = typeof(IConfig); IEnumerable <Type> configTypes = new TypeDiscovery().FindNethermindTypes(configurationType) .Where(ct => ct.IsInterface); CommandLineApplication app = new CommandLineApplication { Name = "Nethermind.Runner" }; app.HelpOption("-?|-h|--help"); app.VersionOption("-v|--version", () => ClientVersion.Version, () => ClientVersion.Description); GlobalDiagnosticsContext.Set("version", ClientVersion.Version); CommandOption dataDir = app.Option("-dd|--datadir <dataDir>", "data directory", CommandOptionType.SingleValue); CommandOption configFile = app.Option("-c|--config <configFile>", "config file path", CommandOptionType.SingleValue); CommandOption dbBasePath = app.Option("-d|--baseDbPath <baseDbPath>", "base db path", CommandOptionType.SingleValue); CommandOption logLevelOverride = app.Option("-l|--log <logLevel>", "log level", CommandOptionType.SingleValue); CommandOption configsDirectory = app.Option("-cd|--configsDirectory <configsDirectory>", "configs directory", CommandOptionType.SingleValue); CommandOption loggerConfigSource = app.Option("-lcs|--loggerConfigSource <loggerConfigSource>", "path to the NLog config file", CommandOptionType.SingleValue); foreach (Type configType in configTypes.OrderBy(c => c.Name)) { if (configType == null) { continue; } ConfigCategoryAttribute?typeLevel = configType.GetCustomAttribute <ConfigCategoryAttribute>(); if (typeLevel?.HiddenFromDocs ?? false) { continue; } foreach (PropertyInfo propertyInfo in configType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .OrderBy(p => p.Name)) { ConfigItemAttribute?configItemAttribute = propertyInfo.GetCustomAttribute <ConfigItemAttribute>(); if (!(configItemAttribute?.HiddenFromDocs ?? false)) { app.Option($"--{configType.Name.Substring(1).Replace("Config", String.Empty)}.{propertyInfo.Name}", $"{(configItemAttribute == null ? "<missing documentation>" : configItemAttribute.Description + $" (DEFAULT: {configItemAttribute.DefaultValue})" ?? "<missing documentation>")}", CommandOptionType.SingleValue); } } } ManualResetEventSlim appClosed = new ManualResetEventSlim(true); app.OnExecute(async() => { appClosed.Reset(); IConfigProvider configProvider = BuildConfigProvider(app, loggerConfigSource, logLevelOverride, configsDirectory, configFile); IInitConfig initConfig = configProvider.GetConfig <IInitConfig>(); IKeyStoreConfig keyStoreConfig = configProvider.GetConfig <IKeyStoreConfig>(); Console.Title = initConfig.LogFileName; Console.CancelKeyPress += ConsoleOnCancelKeyPress; SetFinalDataDirectory(dataDir.HasValue() ? dataDir.Value() : null, initConfig, keyStoreConfig); NLogManager logManager = new(initConfig.LogFileName, initConfig.LogDirectory); _logger = logManager.GetClassLogger(); if (_logger.IsDebug) { _logger.Debug($"Nethermind version: {ClientVersion.Description}"); } ConfigureSeqLogger(configProvider); SetFinalDbPath(dbBasePath.HasValue() ? dbBasePath.Value() : null, initConfig); LogMemoryConfiguration(); EthereumJsonSerializer serializer = new(); if (_logger.IsDebug) { _logger.Debug($"Nethermind config:{Environment.NewLine}{serializer.Serialize(initConfig, true)}{Environment.NewLine}"); } ApiBuilder apiBuilder = new(configProvider, logManager); INethermindApi nethermindApi = apiBuilder.Create(); foreach (Type pluginType in pluginLoader.PluginTypes) { if (Activator.CreateInstance(pluginType) is INethermindPlugin plugin) { nethermindApi.Plugins.Add(plugin); } } EthereumRunner ethereumRunner = new EthereumRunner(nethermindApi); await ethereumRunner.Start(_processCloseCancellationSource.Token).ContinueWith(x => { if (x.IsFaulted && _logger.IsError) { _logger.Error("Error during ethereum runner start", x.Exception); } }); await Task.WhenAny(_cancelKeySource.Task, _processExit.Task); _logger.Info("Closing, please wait until all functions are stopped properly..."); await ethereumRunner.StopAsync(); _logger.Info("All done, goodbye!"); appClosed.Set(); return(0); }); app.Execute(args); appClosed.Wait(); }