public static Type GetDirectInterfaceImplementation(this Type interfaceType) { if (!interfaceType.IsInterface) { throw new NotSupportedException($"GetDirectInterfaceImplementation method is only allowed to use on interface types, got {interfaceType} instead"); } TypeDiscovery typeDiscovery = new TypeDiscovery(); Type[] baseInterfaces = interfaceType.GetInterfaces(); IEnumerable <Type> implementations = typeDiscovery.FindNethermindTypes(interfaceType).Where(i => i.IsClass); foreach (Type implementation in implementations) { List <Type> interfaces = implementation.GetInterfaces().ToList(); interfaces.RemoveAll(i => baseInterfaces.Contains(i)); if (interfaces.Contains(interfaceType) && interfaces.Count() == 1) { return(implementation); } } throw new InvalidOperationException($"Couldn't find direct implementation of {interfaceType} interface"); }
public static List <RuleInformation> DiscoverRules(IEnumerable <Assembly> assemblies) { var list = new List <RuleInformation>(); foreach (Assembly assembly in assemblies) { string cacheKey = assembly.FullName; if (_ruleCache.ContainsKey(cacheKey)) { //pull from cache list.AddRange(_ruleCache[cacheKey]); } else { //discover var discovered = TypeDiscovery.DiscoverTypes <RuleDiscoveryAttribute>(new Assembly[] { assembly }); foreach (var rule in discovered) { list.Add(Map(rule)); } //add to cache _ruleCache[cacheKey] = list; } } return(list); }
public void Register_and_update_metrics_should_not_throw_exception() { MetricsConfig metricsConfig = new() { Enabled = true }; List <Type> knownMetricsTypes = new() { typeof(Nethermind.Mev.Metrics), typeof(Nethermind.TxPool.Metrics), typeof(Nethermind.Blockchain.Metrics), typeof(Nethermind.Consensus.AuRa.Metrics), typeof(Nethermind.Evm.Metrics), typeof(Nethermind.JsonRpc.Metrics), typeof(Nethermind.Db.Metrics), typeof(Nethermind.Network.Metrics), typeof(Init.Metrics), typeof(Nethermind.Synchronization.Metrics), typeof(Nethermind.Trie.Metrics), typeof(Nethermind.Trie.Pruning.Metrics), }; MetricsUpdater metricsUpdater = new(metricsConfig); MonitoringService monitoringService = new(metricsUpdater, metricsConfig, LimboLogs.Instance); List <Type> metrics = new TypeDiscovery().FindNethermindTypes(nameof(Metrics)).ToList(); metrics.AddRange(knownMetricsTypes); Assert.DoesNotThrow(() => { foreach (Type metric in metrics) { monitoringService.RegisterMetrics(metric); } metricsUpdater.UpdateMetrics(null); }); }
public void Test() { IList <BuildStepAttribute> steps = TypeDiscovery.DiscoveryBuildSteps(typeof(Car)); foreach (BuildStepAttribute step in steps) { Trace.WriteLine(step.Sequence + " " + step.Times); } }
public CryptoFactory(IEnumerable <Assembly> extraAssemblies) { IEnumerable <Type> types = TypeDiscovery.Interface(typeof(ICryptoFactory), extraAssemblies); foreach (Type type in types) { Add(() => Activator.CreateInstance(type) as ICryptoFactory); } }
protected static void ResetMongoDb() { MongoDbDriverHelper.ResetDriver(); EntityMapping.RemoveAllDefinitions(); EntityMapping.RemoveAllMappingProcessors(); EntityMapping.AddMappingProcessors(DefaultMappingPack.Instance.Processors); TypeDiscovery.ClearCache(); }
public IContainer RegisterAll <T>() { Type[] components; if (TypeDiscovery.Discover <T>(out components)) { components.ForEach(c => RegisterAsTransient <T>(c)); } return(this); }
public CryptoPolicy(IEnumerable <Assembly> extraAssemblies) { IEnumerable <Type> policyTypes = TypeDiscovery.Interface(typeof(ICryptoPolicy), extraAssemblies); foreach (Type policyType in policyTypes) { ICryptoPolicy instance = Activator.CreateInstance(policyType) as ICryptoPolicy; _policies.Add(instance.Name, instance); } }
protected static void ResetMongoDb() { MongoDbDriverHelper.ResetDriver(); EntityMapping.RemoveAllDefinitions(); EntityMapping.RemoveAllMappingProcessors(); EntityMapping.AddMappingProcessors(DefaultProcessors.CreateProcessors()); TypeDiscovery.ClearCache(); EntityIndexWriter.ClearCache(); }
public void Dispose() { Log.Dispose(); TypeDiscovery.Dispose(); DelegateDiscovery.Dispose(); DelegateDiscoveryGrouped.Dispose(); DelegateClassification.Dispose(); DelegateMethods.Dispose(); TypeClassification.Dispose(); CustomMethodDiscovery.Dispose(); Error.Dispose(); }
private IEnumerable <ConfigurationEntry> LoadCatalogue() { Type[] items; TypeDiscovery.Discover <ISupportConfigurationDiscovery>(out items); return(items.Select(i => { var target = (ISupportConfigurationDiscovery)Activator.CreateInstance(i); return target.GetConfigurationMetadata(); }).ToList()); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="profile"></param> /// <returns></returns> public bool Load(string name, out IRoleProfile profile) { profile = null; Type[] matchingTypes; if (!TypeDiscovery.Discover <IRoleProfile>(out matchingTypes)) { return(false); } var profileTypeName = (name.EndsWith("Profile")) ? name : name + "Profile"; var profileType = matchingTypes.First(candidateType => string.Compare(candidateType.Name, profileTypeName) == 0); profile = (IRoleProfile)Activator.CreateInstance(profileType); return(profile != null); }
public bool Load(out TI[] components) { components = new TI[0]; Type[] matchingTypes; if (!TypeDiscovery.Discover <TI>(out matchingTypes)) { return(false); } var candidates = from type in matchingTypes select(TI) Activator.CreateInstance(type); components = candidates.ToArray(); return(components.Length > 0); }
public void Setup() { // by pre-caching configs we make the tests do lot less work IEnumerable <Type> configTypes = new TypeDiscovery().FindNethermindTypes(typeof(IConfig)).Where(t => t.IsInterface).ToArray(); Parallel.ForEach(Resolve("*"), configFile => { ConfigProvider configProvider = GetConfigProviderFromFile(configFile); foreach (Type configType in configTypes) { configProvider.GetConfig(configType); } _cachedProviders.Add(configFile, configProvider); }); }
protected virtual void FindAndExecuteBootstrappers(Type configType, object config) { var bootstrapBuilderType = typeof(ISupportBootStrapping <>); var bootstrapperInterfaceType = bootstrapBuilderType.MakeGenericType(configType); Type[] bootstrapperTypes; if (!TypeDiscovery.Discover(bootstrapperInterfaceType, out bootstrapperTypes)) { return; } // found some... foreach (var bootstrapperType in bootstrapperTypes) { dynamic bootstrapper = Activator.CreateInstance(bootstrapperType); bootstrapperInterfaceType.GetMethod("Execute") .Invoke(bootstrapper, new[] { config }); } }
public IContainer RegisterAllWithInterception <T, TI>() { Type[] components; if (!TypeDiscovery.Discover <T>(out components)) { return(this); } var interceptorTypes = (from iType in ResolveAll <TI>() select iType.GetType()).ToArray(); components.ToList().ForEach(c => Instance.Register(Component.For(typeof(T)) .LifeStyle.Transient .ImplementedBy(c) .Interceptors(interceptorTypes))); return(this); }
public bool Load(out TI[] components) { components = new TI[0]; Type[] matchingTypes; if (!TypeDiscovery.Discover <TI>(out matchingTypes)) { return(false); } var candidates = from type in matchingTypes select(TI) Activator.CreateInstance(type) into instance select instance; var plugins = candidates.Cast <IPlugin>() .InitialisePlugins(); components = plugins.Cast <TI>().ToArray(); return(components.Length > 0); }
public async Task Execute(CancellationToken cancellationToken) { IMetricsConfig metricsConfig = _api.Config <IMetricsConfig>(); ILogger logger = _api.LogManager.GetClassLogger(); // hacky if (!string.IsNullOrEmpty(metricsConfig.NodeName)) { _api.LogManager.SetGlobalVariable("nodeName", metricsConfig.NodeName); } if (metricsConfig.Enabled) { Metrics.Version = VersionToMetrics.ConvertToNumber(ClientVersion.Version); MetricsUpdater metricsUpdater = new MetricsUpdater(metricsConfig); _api.MonitoringService = new MonitoringService(metricsUpdater, metricsConfig, _api.LogManager); var metrics = new TypeDiscovery().FindNethermindTypes(nameof(Metrics)); foreach (var metric in metrics) { _api.MonitoringService.RegisterMetrics(metric); } await _api.MonitoringService.StartAsync().ContinueWith(x => { if (x.IsFaulted && logger.IsError) { logger.Error("Error during starting a monitoring.", x.Exception); } }, cancellationToken); _api.DisposeStack.Push(Disposable.Create(() => _api.MonitoringService.StopAsync())); // do not await } else { if (logger.IsInfo) { logger.Info("Grafana / Prometheus metrics are disabled in configuration"); } } }
private static bool GetType <T>(string targetTypeName, out Type targetType) { targetType = null; Type[] matchingTypes; if (!TypeDiscovery.Discover <T>(t => t.Name.Equals(targetTypeName, StringComparison.OrdinalIgnoreCase), out matchingTypes)) { return(false); } if (matchingTypes.Count() != 1) { throw new InvalidOperationException(string.Format("Searching for type '{0}' named '{1}'; found {2} matches, expected only 1", typeof(T).Name, targetTypeName, matchingTypes.Count())); } targetType = matchingTypes.First(); return(true); }
public void TheTypeDiscoveryIsExecuted() { TypeDiscovery.Discover(_typeToDiscover, out _typesFound); }
public void FindMongoDbContext() { TypeDiscovery.FindTypeByDiscriminator("MongoDbContext", typeof(object)); TypeDiscovery.ClearCache(); }
public void FindString() { TypeDiscovery.FindTypeByDiscriminator("string", typeof(object)); TypeDiscovery.ClearCache(); }
public void FindLocalClass() { TypeDiscovery.FindTypeByDiscriminator("LocalClass", typeof(object)); TypeDiscovery.ClearCache(); }
// // Serialization of Fields within a Type: // private static bool IsIgnoredField(FieldInfo field) { return(TypeDiscovery.IsIgnoredType(field.FieldType) || field.GetCustomAttributes(typeof(SerializationIgnoreAttribute), true).Length != 0 || field.GetCustomAttributes(typeof(NonSerializedAttribute), true).Length != 0); }
public static GeneratorResult Run(Assembly[] assemblies, Type[] predefinedRoots, GeneratorReports reports, bool createAssembly, string outputAssemblyName) { var baseLocation = assemblies.First() .Location; // <- should probably use all passed assemblies as potential base locations (also detect accidently passing a system one) if (baseLocation == "") // <- loaded from embedded resources { baseLocation = null; } else { baseLocation = Path.GetDirectoryName(baseLocation); } #region Initial Reporting - Assembly Info if (reports != null) { reports.Log.WriteLine(DateTime.Now); reports.Log.WriteLine(); reports.Log.WriteLine("Initial Assemblies (" + assemblies.Count() + ")"); foreach (var a in assemblies) { reports.Log.WriteLine(" " + a); } reports.Log.WriteLine(); reports.Log.WriteLine("Base Location = " + baseLocation ?? "<<resources>>"); reports.Log.WriteLine(); } #endregion #region Search for [SerializationRoot] attributes var rootTypes = new HashSet <Type>(); foreach (var assembly in assemblies) { var types = assembly.GetTypes(); foreach (var type in types.Where(t => t.GetCustomAttributes(typeof(SerializationRootAttribute), false).Length > 0)) { rootTypes.Add(type); } } if (predefinedRoots != null) { foreach (var type in predefinedRoots) { rootTypes.Add(type); } } if (reports != null) { reports.Log.WriteLine("Initial roots (" + rootTypes.Count + ")"); foreach (var type in rootTypes) { reports.Log.WriteLine(" " + type); } reports.Log.WriteLine(); } #endregion #region Custom Method Discovery if (reports != null) { reports.Log.WriteLine("Running custom method discovery"); } var customMethodAssemblies = new HashSet <Assembly>(assemblies); customMethodAssemblies.Add(typeof(SerializeList) .Assembly); // <- Get the assembly that contains all our "built-in" serializers var customMethods = CustomMethodDiscovery.Run(customMethodAssemblies, reports != null ? reports.CustomMethodDiscovery : null, reports != null ? reports.Error : null); // Attach hard-coded array serializer methods: customMethods = SerializationMethodProviders.Combine(SerializeArray.CreateSerializationMethodProviders(), customMethods); #endregion #region Type Discovery - First Pass var td = new TypeDiscovery(customMethods, assemblies); if (reports != null) { reports.Log.WriteLine("Running Type Discovery - First Pass"); reports.TypeDiscovery.WriteLine("---------------------------"); reports.TypeDiscovery.WriteLine("TYPE DISCOVERY - FIRST PASS"); reports.TypeDiscovery.WriteLine("---------------------------"); reports.TypeDiscovery.WriteLine(); } td.DiscoverFromRoots(rootTypes, reports != null ? reports.TypeDiscovery : null, reports != null ? reports.Error : null); #endregion #region Delegate Discovery and Type Discovery Second Pass List <DelegateUsage> delegateDiscoveryResult = null; IEnumerable <Type> allDelegateTargetTypes = null; if (td.FoundDelegates) { Debug.WriteLine("IMPORTANT: Serializer generator is doing delegate discovery! May be undesireable."); #region Delegate Discovery if (reports != null) { reports.Log.WriteLine("Running Delegate Discovery"); } // Only search for delegates in our own assemblies: var delegateDiscoveryAssemblies = td.Assemblies.Where(a => a.IsOurAssembly(baseLocation)); if (reports != null) { reports.DelegateDiscovery.WriteLine("Searching in assemblies:"); foreach (var a in delegateDiscoveryAssemblies) { reports.DelegateDiscovery.WriteLine(" " + a); } reports.DelegateDiscovery.WriteLine(); reports.DelegateDiscovery.WriteLine(); } delegateDiscoveryResult = DelegateDiscovery.Run(delegateDiscoveryAssemblies, reports != null ? reports.DelegateDiscovery : null, reports != null ? reports.Error : null); if (reports != null) { DelegateDiscovery.WriteDelegateUsageGrouped(delegateDiscoveryResult, reports.DelegateDiscoveryGrouped); } #endregion #region Type Discovery - Second Pass if (reports != null) { reports.Log.WriteLine("Running Type Discovery - Second Pass"); reports.TypeDiscovery.WriteLine("----------------------------"); reports.TypeDiscovery.WriteLine("TYPE DISCOVERY - SECOND PASS"); reports.TypeDiscovery.WriteLine("----------------------------"); reports.TypeDiscovery.WriteLine(); } allDelegateTargetTypes = delegateDiscoveryResult.Select(du => du.targetType) .Where(t => t != null) // <- Disregard delegates with static targets .Distinct(); td.DiscoverFromRoots(allDelegateTargetTypes, reports != null ? reports.TypeDiscovery : null, reports != null ? reports.Error : null); #endregion } else { if (reports != null) { reports.Log.WriteLine("Was able to skip delegate discovery!"); } } #endregion #region Type Classification if (reports != null) { reports.Log.WriteLine("Running type classification"); } var tc = new TypeClassifier(td); tc.RunClassification(); if (reports != null) { tc.WriteReport(reports.TypeClassification, reports.Error); CustomMethodDiscovery.CheckForDerivedCustomInitializers(customMethods.ReferenceTypeInitializeMethods, tc.ReferenceTypes, reports.Error); } #endregion #region Delegate Classification Dictionary <Type, DelegateTypeInfo> delegateTypeTable = null; if (delegateDiscoveryResult != null) { var dc = new DelegateClassification(td.delegateFieldTypes, delegateDiscoveryResult); delegateTypeTable = dc.GenerateDelegateTypeTable(); if (reports != null) { dc.Report(reports.DelegateClassification, reports.Error); // NOTE: Any methods that appear in this list consitute a security risk, as they can be sent across the network! // Make sure that all these methods are "safe" (nothing that can, say, access the filesystem) foreach (var methodName in delegateTypeTable.SelectMany(dt => dt.Value.methodInfoList) .Select(mi => mi.method).Distinct() .Select(m => m.DeclaringType + "." + m.Name).OrderBy(s => s)) { reports.DelegateMethods.WriteLine(methodName); } } // Attach delegate serializer method generator // NOTE: Doing this after type discovery, which automatically ignores delegates anyway, but before IL generation, which requires the methods to call // NOTE: Generated delegate serializers come *after* custom methods, because the user may specify custom serialization for any given delegate customMethods = SerializationMethodProviders.Combine(customMethods, DelegateSerialization.CreateSerializationMethodProviders()); } #endregion #region Module Table var moduleTable = td.Assemblies.Where(a => a.IsOurAssembly(baseLocation)).SelectMany(a => a.GetModules()) .NetworkOrder(module => module.Name).ToList(); #endregion #region Report Final Log Info if (reports != null) { reports.Log.WriteLine(); reports.Log.WriteLine(); var outsideTypes = td.valueTypes.Concat(td.referenceTypes) .Select(t => (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>) ? t.GetGenericArguments()[0] : t)) .Where(t => !customMethods.HasTypeSerializer(t)) .Where(t => !t.Assembly.IsOurAssembly(baseLocation)); reports.Log.WriteLine("Types outside of \"" + baseLocation + "\" without custom serializers (" + outsideTypes.Count() + ")"); foreach (var type in outsideTypes) { reports.Log.WriteLine(" " + type); } reports.Log.WriteLine(); if (delegateDiscoveryResult != null) { var openConstructedDelegates = delegateDiscoveryResult.Where(d => d.delegateType.ContainsGenericParameters || d.delegateMethod.ContainsGenericParameters); reports.Log.WriteLine("Open constructed delegates (" + openConstructedDelegates.Count() + ")"); foreach (var d in openConstructedDelegates) { reports.Log.WriteLine(" " + d.delegateType + " -> " + d.delegateMethod + " -> " + (d.targetType != null ? d.targetType.ToString() : "(null)")); } reports.Log.WriteLine(); } reports.Log.WriteLine(); reports.Log.WriteLine("Assemblies (" + td.Assemblies.Count() + ")"); foreach (var a in td.Assemblies) { reports.Log.WriteLine(" " + a); } reports.Log.WriteLine(); reports.Log.WriteLine(); reports.Log.WriteLine("Module Table (" + moduleTable.Count() + ")"); foreach (var module in moduleTable) { reports.Log.WriteLine(" " + module); } reports.Log.WriteLine(); var notInInitialAssemblies = td.Assemblies.Where(a => a.IsOurAssembly(baseLocation)) .Where(a => !assemblies.Contains(a)); if (notInInitialAssemblies.Count() > 0) { reports.Error.WriteLine("WARNING: Visited assemblies in \"" + baseLocation + "\" that were not in initial list of assemblies (see log for suggested command line)"); reports.Error.WriteLine( " (It is possible that custom serialize methods, delegate instantiations, and derived types in these assemblies were missed)"); foreach (var a in notInInitialAssemblies) { reports.Error.WriteLine(" " + a); } reports.Error.WriteLine(); } reports.Log.WriteLine(); reports.Log.WriteLine("Suggested initial assemblies for command line:"); foreach (var a in td.Assemblies.Where(a => a.IsOurAssembly(baseLocation))) { reports.Log.Write("\"" + a.Location + "\" "); } reports.Log.WriteLine(); reports.Log.WriteLine(); // Final Counts: if (delegateDiscoveryResult != null) { reports.Log.WriteLine(); reports.Log.WriteLine("Delegate Usage Count = " + delegateDiscoveryResult.Count); reports.Log.WriteLine("Distinct Delegate Method Count = " + delegateDiscoveryResult.Select(du => du.delegateMethod).Distinct().Count()); reports.Log.WriteLine("Distinct Delegate Target Type Count = " + delegateDiscoveryResult.Select(du => du.targetType).Distinct().Count()); } reports.Log.WriteLine(); reports.Log.WriteLine("Total Serializable Type Count = " + (td.referenceTypes.Count + td.valueTypes.Count)); reports.Log.WriteLine(); reports.Log.WriteLine(); } #endregion #region Generate Assembly var serializerMethodGenerator = new SerializerMethodGenerator(tc, customMethods, allDelegateTargetTypes); GeneratorResult generatorResult; if (createAssembly) { if (reports != null) { reports.Log.WriteLine("Generating assembly..."); } #if NET40 || NET45 || NET462 var an = new AssemblyName(outputAssemblyName); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save); var moduleBuilder = assemblyBuilder.DefineDynamicModule(outputAssemblyName + ".dll"); var methodCreatorCreator = new MethodBuilderCreatorCreator(moduleBuilder, "GenSerialize"); generatorResult = serializerMethodGenerator.Generate(methodCreatorCreator); methodCreatorCreator.Finish(); assemblyBuilder.Save(outputAssemblyName + ".dll"); #else // https://github.com/dotnet/roslyn/issues/10881 // https://github.com/dotnet/corert/tree/master/src/ILVerify throw new NotSupportedException("Cannot convert dynamic assembly to disk bytes in Roslyn without parsing a syntax tree!"); AssemblyName an = new AssemblyName(outputAssemblyName); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndCollect); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(outputAssemblyName + ".dll"); var methodCreatorCreator = new MethodBuilderCreatorCreator(moduleBuilder, "GenSerialize"); generatorResult = serializerMethodGenerator.Generate(methodCreatorCreator); methodCreatorCreator.Finish(); Assembly assembly = moduleBuilder.Assembly; var compilation = CSharpCompilation.Create(outputAssemblyName); #endif } else { if (reports != null) { reports.Log.WriteLine("Generating dynamic methods..."); } var methodCreatorCreator = new DynamicMethodCreatorCreator(); generatorResult = serializerMethodGenerator.Generate(methodCreatorCreator); } if (reports != null) { reports.Log.WriteLine(); reports.Log.WriteLine("Done!"); } #endregion generatorResult.delegateTypeTable = delegateTypeTable; generatorResult.moduleTable = moduleTable; return(generatorResult); }
public void Overhead() { TypeDiscovery.ClearCache(); }
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(); }