public Task Start() { if (_logger.IsDebug) { _logger.Debug("Initializing JSON RPC"); } var hostVariable = Environment.GetEnvironmentVariable("NETHERMIND_URL"); var host = string.IsNullOrWhiteSpace(hostVariable) ? $"http://{_initConfig.HttpHost}:{_initConfig.HttpPort}" : hostVariable; if (_logger.IsInfo) { _logger.Info($"Running server, url: {host}"); } var webHost = WebHost.CreateDefaultBuilder() .ConfigureServices(s => { s.AddSingleton(_configurationProvider); s.AddSingleton(_jsonRpcProcessor); s.AddSingleton(_webSocketsManager); }) .UseStartup <Startup>() .UseUrls(host) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Information); logging.ClearProviders(); logging.AddProvider(new CustomMicrosoftLoggerProvider(_logManager)); }) .Build(); var modules = GetModules(_initConfig.JsonRpcEnabledModules)?.ToList(); if (modules != null && modules.Any()) { _jsonRpcConfig.EnabledModules = modules; } _webHost = webHost; _webHost.Start(); if (_logger.IsInfo) { _logger.Info($"JSON RPC : {host}"); } if (_logger.IsInfo) { _logger.Info($"RPC modules : {string.Join(", ", _moduleProvider.GetEnabledModules().Select(m => m.ModuleType.ToString()).OrderBy(x => x))}"); } return(Task.CompletedTask); }
public async Task StopAsync() { try { await(_webHost?.StopAsync() ?? Task.CompletedTask); if (_logger.IsInfo) { _logger.Info("JSON RPC service stopped"); } } catch (Exception e) { if (_logger.IsInfo) { _logger.Info($"Error when stopping JSON RPC service: {e}"); } } }
public void Run(string[] args) { var(app, buildConfigProvider, getDbBasePath) = BuildCommandLineApp(); ManualResetEventSlim appClosed = new ManualResetEventSlim(true); app.OnExecute(async() => { appClosed.Reset(); var configProvider = buildConfigProvider(); var initConfig = configProvider.GetConfig <IInitConfig>(); LogManager.Configuration = new XmlLoggingConfiguration("NLog.config".GetApplicationResourcePath()); _logger = new NLogLogger(initConfig.LogFileName, initConfig.LogDirectory); LogMemoryConfiguration(); var pathDbPath = getDbBasePath(); if (!string.IsNullOrWhiteSpace(pathDbPath)) { var newDbPath = Path.Combine(pathDbPath, initConfig.BaseDbPath); if (_logger.IsDebug) { _logger.Debug($"Adding prefix to baseDbPath, new value: {newDbPath}, old value: {initConfig.BaseDbPath}"); } initConfig.BaseDbPath = newDbPath ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "db"); } Console.Title = initConfig.LogFileName; Console.CancelKeyPress += ConsoleOnCancelKeyPress; var serializer = new EthereumJsonSerializer(); if (_logger.IsInfo) { _logger.Info($"Nethermind config:\n{serializer.Serialize(initConfig, true)}\n"); } _cancelKeySource = new TaskCompletionSource <object>(); await StartRunners(configProvider); await _cancelKeySource.Task; Console.WriteLine("Closing, please wait until all functions are stopped properly..."); StopAsync().Wait(); Console.WriteLine("All done, goodbye!"); appClosed.Set(); return(0); }); app.Execute(args); appClosed.Wait(); }
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(); }
private static IConfigProvider BuildConfigProvider( CommandLineApplication app, CommandOption loggerConfigSource, CommandOption logLevelOverride, CommandOption configsDirectory, CommandOption configFile) { ILogger logger = SimpleConsoleLogger.Instance; if (loggerConfigSource.HasValue()) { string nLogPath = loggerConfigSource.Value(); logger.Info($"Loading NLog configuration file from {nLogPath}."); try { LogManager.Configuration = new XmlLoggingConfiguration(nLogPath); } catch (Exception e) { logger.Info($"Failed to load NLog configuration from {nLogPath}. {e}"); } } else { logger.Info($"Loading standard NLog.config file from {"NLog.config".GetApplicationResourcePath()}."); Stopwatch stopwatch = Stopwatch.StartNew(); LogManager.Configuration = new XmlLoggingConfiguration("NLog.config".GetApplicationResourcePath()); stopwatch.Stop(); logger.Info($"NLog.config loaded in {stopwatch.ElapsedMilliseconds}ms."); } // TODO: dynamically switch log levels from CLI! if (logLevelOverride.HasValue()) { NLogConfigurator.ConfigureLogLevels(logLevelOverride); } ConfigProvider configProvider = new ConfigProvider(); Dictionary <string, string> configArgs = new Dictionary <string, string>(); foreach (CommandOption commandOption in app.Options) { if (commandOption.HasValue()) { configArgs.Add(commandOption.LongName, commandOption.Value()); } } IConfigSource argsSource = new ArgsConfigSource(configArgs); configProvider.AddSource(argsSource); configProvider.AddSource(new EnvConfigSource()); string configDir = configsDirectory.HasValue() ? configsDirectory.Value() : DefaultConfigsDirectory; string configFilePath = configFile.HasValue() ? configFile.Value() : DefaultConfigFile; string?configPathVariable = Environment.GetEnvironmentVariable("NETHERMIND_CONFIG"); if (!string.IsNullOrWhiteSpace(configPathVariable)) { configFilePath = configPathVariable; } if (!PathUtils.IsExplicitlyRelative(configFilePath)) { if (configDir == DefaultConfigsDirectory) { configFilePath = configFilePath.GetApplicationResourcePath(); } else { configFilePath = Path.Combine(configDir, string.Concat(configFilePath)); } } if (!Path.HasExtension(configFilePath) && !configFilePath.Contains(Path.DirectorySeparatorChar)) { string redirectedConfigPath = Path.Combine(configDir, string.Concat(configFilePath, ".cfg")); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } if (!Path.HasExtension(configFilePath)) { configFilePath = string.Concat(configFilePath, ".cfg"); } // Fallback to "{executingDirectory}/configs/{configFile}" if "configs" catalog was not specified. if (!File.Exists(configFilePath)) { string configName = Path.GetFileName(configFilePath); string?configDirectory = Path.GetDirectoryName(configFilePath); string redirectedConfigPath = Path.Combine(configDirectory ?? string.Empty, configDir, configName); configFilePath = redirectedConfigPath; if (!File.Exists(configFilePath)) { throw new InvalidOperationException($"Configuration: {configFilePath} was not found."); } } logger.Info($"Reading config file from {configFilePath}"); configProvider.AddSource(new JsonConfigSource(configFilePath)); configProvider.Initialize(); logger.Info("Configuration initialized."); return(configProvider); }