Example #1
0
        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);
        }
Example #2
0
 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}");
         }
     }
 }
Example #3
0
        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();
        }
Example #4
0
        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");
                }
            }
        }
Example #5
0
        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();
        }
Example #6
0
        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);
        }