/// <summary> /// Initializes a new instance of the object. /// </summary> /// <param name="network">The network the node runs on - regtest/testnet/mainnet.</param> /// <param name="protocolVersion">Supported protocol version for which to create the configuration.</param> /// <param name="agent">The nodes user agent that will be shared with peers.</param> /// <param name="args">The command-line arguments.</param> /// <param name="networksSelector">A selector class that delayed load a network for either - regtest/testnet/mainnet.</param> /// <exception cref="ConfigurationException">Thrown in case of any problems with the configuration file or command line arguments.</exception> /// <remarks> /// Processing depends on whether a configuration file is passed via the command line. /// There are two main scenarios here: /// - The configuration file is passed via the command line. In this case we need /// to read it earlier so that it can provide defaults for "testnet" and "regtest". /// - Alternatively, if the file name is not supplied then a network-specific file /// name would be determined. In this case we first need to determine the network. /// </remarks> public NodeSettings(Network network = null, ProtocolVersion protocolVersion = SupportedProtocolVersion, string agent = "ImpleumNode", string[] args = null, NetworksSelector networksSelector = null) { // Create the default logger factory and logger. var loggerFactory = new ExtendedLoggerFactory(); this.LoggerFactory = loggerFactory; this.LoggerFactory.AddConsoleWithFilters(); this.LoggerFactory.AddNLog(); this.Logger = this.LoggerFactory.CreateLogger(typeof(NodeSettings).FullName); // Record arguments. this.Network = network; this.ProtocolVersion = protocolVersion; this.Agent = agent; this.ConfigReader = new TextFileConfiguration(args ?? new string[] { }); // Log arguments. this.Logger.LogDebug("Arguments: network='{0}', protocolVersion='{1}', agent='{2}', args='{3}'.", this.Network == null ? "(None)" : this.Network.Name, this.ProtocolVersion, this.Agent, args == null ? "(None)" : string.Join(" ", args)); // By default, we look for a file named '<network>.conf' in the network's data directory, // but both the data directory and the configuration file path may be changed using the -datadir and -conf command-line arguments. this.ConfigurationFile = this.ConfigReader.GetOrDefault <string>("conf", null, this.Logger)?.NormalizeDirectorySeparator(); this.DataDir = this.ConfigReader.GetOrDefault <string>("datadir", null, this.Logger)?.NormalizeDirectorySeparator(); this.DataDirRoot = this.ConfigReader.GetOrDefault <string>("datadirroot", "ImpleumNode", this.Logger); // If the configuration file is relative then assume it is relative to the data folder and combine the paths. if (this.DataDir != null && this.ConfigurationFile != null) { bool isRelativePath = Path.GetFullPath(this.ConfigurationFile).Length > this.ConfigurationFile.Length; if (isRelativePath) { this.ConfigurationFile = Path.Combine(this.DataDir, this.ConfigurationFile); } } // If the configuration file has been specified on the command line then read it now // so that it can provide the defaults for testnet and regtest. if (this.ConfigurationFile != null) { // If the configuration file was specified on the command line then it must exist. if (!File.Exists(this.ConfigurationFile)) { throw new ConfigurationException($"Configuration file does not exist at {this.ConfigurationFile}."); } // Sets the ConfigReader based on the arguments and the configuration file if it exists. this.ReadConfigurationFile(); } // If the network is not known then derive it from the command line arguments. if (this.Network == null) { if (networksSelector == null) { throw new ConfigurationException("Network or NetworkSelector not provided."); } // Find out if we need to run on testnet or regtest from the config file. bool testNet = this.ConfigReader.GetOrDefault <bool>("testnet", false, this.Logger); bool regTest = this.ConfigReader.GetOrDefault <bool>("regtest", false, this.Logger); if (testNet && regTest) { throw new ConfigurationException("Invalid combination of regtest and testnet."); } this.Network = testNet ? networksSelector.Testnet() : regTest?networksSelector.Regtest() : networksSelector.Mainnet(); this.Logger.LogDebug("Network set to '{0}'.", this.Network.Name); } // Ensure the network being used is registered and we have the correct Network object reference. this.Network = NetworkRegistration.Register(this.Network); // Set the full data directory path. if (this.DataDir == null) { // Create the data directories if they don't exist. this.DataDir = this.CreateDefaultDataDirectories(Path.Combine(this.DataDirRoot, this.Network.RootFolderName), this.Network); } else { // Combine the data directory with the network's root folder and name. string directoryPath = Path.Combine(this.DataDir, this.Network.RootFolderName, this.Network.Name); this.DataDir = Directory.CreateDirectory(directoryPath).FullName; this.Logger.LogDebug("Data directory initialized with path {0}.", this.DataDir); } // Set the data folder. this.DataFolder = new DataFolder(this.DataDir); // Attempt to load NLog configuration from the DataFolder. loggerFactory.LoadNLogConfiguration(this.DataFolder); // Get the configuration file name for the network if it was not specified on the command line. if (this.ConfigurationFile == null) { this.ConfigurationFile = Path.Combine(this.DataDir, this.Network.DefaultConfigFilename); this.Logger.LogDebug("Configuration file set to '{0}'.", this.ConfigurationFile); if (File.Exists(this.ConfigurationFile)) { this.ReadConfigurationFile(); } } // Create the custom logger factory. this.Log = new LogSettings(); this.Log.Load(this.ConfigReader); this.LoggerFactory.AddFilters(this.Log, this.DataFolder); this.LoggerFactory.ConfigureConsoleFilters(this.LoggerFactory.GetConsoleSettings(), this.Log); // Load the configuration. this.LoadConfiguration(); }
/// <summary> /// Initializes a new instance of the object. /// </summary> /// <param name="masterNode">The masternode the server runs on</param> /// <param name="protocolVersion">Supported protocol version for which to create the configuration.</param> /// <param name="agent">The servers user agent that will be shared with peers.</param> /// <param name="args">The command-line arguments.</param> /// <exception cref="ConfigurationException"> /// Thrown in case of any problems with the configuration file or command line /// arguments. /// </exception> /// <remarks> /// Processing depends on whether a configuration file is passed via the command line. /// There are two main scenarios here: /// - The configuration file is passed via the command line. In this case we need /// to read it earlier so that it can provide defaults for "testnet" and "regtest". /// - Alternatively, if the file name is not supplied then a masternode-specific file /// name would be determined. In this case we first need to determine the masternode. /// </remarks> public ServerSettings(MasterNodeBase masterNode, ProtocolVersion protocolVersion = ProtocolVersion.PROTOCOL_VERSION, string agent = "x42", string[] args = null) { MasterNode = masterNode; // Create the default logger factory and logger. ExtendedLoggerFactory loggerFactory = new ExtendedLoggerFactory(); LoggerFactory = loggerFactory; LoggerFactory.AddConsoleWithFilters(); LoggerFactory.AddNLog(); Logger = LoggerFactory.CreateLogger(typeof(ServerSettings).FullName); ProtocolVersion = protocolVersion; Agent = agent; ConfigReader = new TextFileConfiguration(args ?? new string[] { }); // Log arguments. Logger.LogDebug("Arguments: masternode='{0}', protocolVersion='{1}', agent='{2}', args='{3}'.", string.IsNullOrEmpty(ServerName) ? "(None)" : ServerName, ProtocolVersion, Agent, args == null ? "(None)" : string.Join(" ", args)); // By default, we look for a file named '<masternode>.conf' in the masternode's data directory, // but both the data directory and the configuration file path may be changed using the -datadir and -conf command-line arguments. ConfigurationFile = ConfigReader.GetOrDefault <string>("conf", null, Logger)?.NormalizeDirectorySeparator(); DataDir = ConfigReader.GetOrDefault <string>("datadir", null, Logger)?.NormalizeDirectorySeparator(); DataDirRoot = ConfigReader.GetOrDefault("datadirroot", "x42Server", Logger); // If the configuration file is relative then assume it is relative to the data folder and combine the paths. if (DataDir != null && ConfigurationFile != null) { bool isRelativePath = Path.GetFullPath(ConfigurationFile).Length > ConfigurationFile.Length; if (isRelativePath) { ConfigurationFile = Path.Combine(DataDir, ConfigurationFile); } } // If the configuration file has been specified on the command line then read it now // so that it can provide the defaults for testnet and regtest. if (ConfigurationFile != null) { // If the configuration file was specified on the command line then it must exist. if (!File.Exists(ConfigurationFile)) { throw new ConfigurationException($"Configuration file does not exist at {ConfigurationFile}."); } // Sets the ConfigReader based on the arguments and the configuration file if it exists. ReadConfigurationFile(); } // Set the full data directory path. if (DataDir == null) { // Create the data directories if they don't exist. DataDir = CreateDefaultDataDirectories(ServerName); } else { // Combine the data directory with the masternode's root folder and name. string directoryPath = Path.Combine(DataDir, ServerName); DataDir = Directory.CreateDirectory(directoryPath).FullName; Logger.LogDebug("Data directory initialized with path {0}.", DataDir); } // Set the data folder. DataFolder = new DataFolder(DataDir); // Attempt to load NLog configuration from the DataFolder. loggerFactory.LoadNLogConfiguration(DataFolder); // Get the configuration file name for the masternode if it was not specified on the command line. if (ConfigurationFile == null) { ConfigurationFile = Path.Combine(DataDir, MasterNode.DefaultConfigFilename); Logger.LogDebug("Configuration file set to '{0}'.", ConfigurationFile); if (File.Exists(ConfigurationFile)) { ReadConfigurationFile(); } } // Create the custom logger factory. Log = new LogSettings(); Log.Load(ConfigReader); LoggerFactory.AddFilters(Log, DataFolder); LoggerFactory.ConfigureConsoleFilters(LoggerFactory.GetConsoleSettings(), Log); // Load the configuration. LoadConfiguration(); }