public TumblerClientConfiguration LoadArgs(String[] args) { ConfigurationFile = args.Where(a => a.StartsWith("-conf=", StringComparison.Ordinal)).Select(a => a.Substring("-conf=".Length).Replace("\"", "")).FirstOrDefault(); DataDir = args.Where(a => a.StartsWith("-datadir=", StringComparison.Ordinal)).Select(a => a.Substring("-datadir=".Length).Replace("\"", "")).FirstOrDefault(); if (DataDir != null && ConfigurationFile != null) { var isRelativePath = Path.GetFullPath(ConfigurationFile).Length > ConfigurationFile.Length; if (isRelativePath) { ConfigurationFile = Path.Combine(DataDir, ConfigurationFile); } } Network = args.Contains("-testnet", StringComparer.OrdinalIgnoreCase) ? Network.TestNet : args.Contains("-regtest", StringComparer.OrdinalIgnoreCase) ? Network.RegTest : null; if (ConfigurationFile != null) { AssetConfigFileExists(); var configTemp = TextFileConfiguration.Parse(File.ReadAllText(ConfigurationFile)); Network = Network ?? (configTemp.GetOrDefault <bool>("testnet", false) ? Network.TestNet : configTemp.GetOrDefault <bool>("regtest", false) ? Network.RegTest : null); } Network = Network ?? Network.Main; if (DataDir == null) { DataDir = DefaultDataDirectory.GetDefaultDirectory("NTumbleBit", Network); } if (ConfigurationFile == null) { ConfigurationFile = GetDefaultConfigurationFile(DataDir, Network); } Logs.Configuration.LogInformation("Network: " + Network); Logs.Configuration.LogInformation("Data directory set to " + DataDir); Logs.Configuration.LogInformation("Configuration file set to " + ConfigurationFile); if (!Directory.Exists(DataDir)) { throw new ConfigurationException("Data directory does not exists"); } var consoleConfig = new TextFileConfiguration(args); var config = TextFileConfiguration.Parse(File.ReadAllText(ConfigurationFile)); consoleConfig.MergeInto(config, true); config.AddAlias("server", "tumbler.server"); OnlyMonitor = config.GetOrDefault <bool>("onlymonitor", false); Cooperative = config.GetOrDefault <bool>("cooperative", true); TumblerServer = config.GetOrDefault("tumbler.server", null as TumblerUrlBuilder); TorPath = config.GetOrDefault <string>("torpath", "tor"); RPCArgs = RPCArgs.Parse(config, Network); if (!OnlyMonitor && TumblerServer == null) { throw new ConfigException("tumbler.server not configured"); } try { var key = config.GetOrDefault("outputwallet.extpubkey", null as string); if (key != null) { OutputWallet.RootKey = new BitcoinExtPubKey(key, Network); } } catch { throw new ConfigException("outputwallet.extpubkey is not configured correctly"); } OutputWallet.KeyPath = new KeyPath("0"); string keyPathString = config.GetOrDefault("outputwallet.keypath", null as string); if (keyPathString != null) { try { OutputWallet.KeyPath = new KeyPath(keyPathString); } catch { throw new ConfigException("outputwallet.keypath is not configured correctly"); } } if (OutputWallet.KeyPath.ToString().Contains("'")) { throw new ConfigException("outputwallet.keypath should not contain any hardened derivation"); } if (OutputWallet.RootKey != null && OutputWallet.RootKey.Network != Network) { throw new ConfigException("outputwallet.extpubkey is pointing an incorrect network"); } OutputWallet.RPCArgs = RPCArgs.Parse(config, Network, "outputwallet"); AliceConnectionSettings = ConnectionSettingsBase.ParseConnectionSettings("alice", config); BobConnectionSettings = ConnectionSettingsBase.ParseConnectionSettings("bob", config); AllowInsecure = config.GetOrDefault <bool>("allowinsecure", IsTest(Network)); RPCClient rpc = null; try { rpc = RPCArgs.ConfigureRPCClient(Network); } catch { throw new ConfigException("Please, fix rpc settings in " + ConfigurationFile); } DBreezeRepository = new DBreezeRepository(Path.Combine(DataDir, "db2")); Tracker = new Tracker(DBreezeRepository, Network); Services = ExternalServices.CreateFromRPCClient(rpc, DBreezeRepository, Tracker, true); if (OutputWallet.RootKey != null && OutputWallet.KeyPath != null) { DestinationWallet = new ClientDestinationWallet(OutputWallet.RootKey, OutputWallet.KeyPath, DBreezeRepository, Network); } else if (OutputWallet.RPCArgs != null) { try { DestinationWallet = new RPCDestinationWallet(OutputWallet.RPCArgs.ConfigureRPCClient(Network)); } catch { throw new ConfigException("Please, fix outputwallet rpc settings in " + ConfigurationFile); } } else { throw new ConfigException("Missing configuration for outputwallet"); } return(this); }
public async Task ConfigureAsync(TumblerClientConfiguration configuration, ClientInteraction interaction) { interaction = interaction ?? new AcceptAllClientInteraction(); Network = configuration.Network; TumblerServer = configuration.TumblerServer; BobSettings = configuration.BobConnectionSettings; AliceSettings = configuration.AliceConnectionSettings; AllowInsecure = configuration.AllowInsecure; await SetupTorAsync(interaction, configuration.TorPath).ConfigureAwait(false); RPCClient rpc = null; try { rpc = configuration.RPCArgs.ConfigureRPCClient(configuration.Network); } catch { throw new ConfigException("Please, fix rpc settings in " + configuration.ConfigurationFile); } var dbreeze = new DBreezeRepository(Path.Combine(configuration.DataDir, "db2")); Cooperative = configuration.Cooperative; Repository = dbreeze; _Disposables.Add(dbreeze); Tracker = new Tracker(dbreeze, Network); Services = ExternalServices.CreateFromRPCClient(rpc, dbreeze, Tracker); if (configuration.OutputWallet.RootKey != null && configuration.OutputWallet.KeyPath != null) { DestinationWallet = new ClientDestinationWallet(configuration.OutputWallet.RootKey, configuration.OutputWallet.KeyPath, dbreeze, configuration.Network); } else if (configuration.OutputWallet.RPCArgs != null) { try { DestinationWallet = new RPCDestinationWallet(configuration.OutputWallet.RPCArgs.ConfigureRPCClient(Network)); } catch { throw new ConfigException("Please, fix outputwallet rpc settings in " + configuration.ConfigurationFile); } } else { throw new ConfigException("Missing configuration for outputwallet"); } TumblerParameters = dbreeze.Get <ClassicTumbler.ClassicTumblerParameters>("Configuration", configuration.TumblerServer.Uri.AbsoluteUri); if (TumblerParameters != null && TumblerParameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { TumblerParameters = null; } if (!configuration.OnlyMonitor) { var client = CreateTumblerClient(0); if (TumblerParameters == null) { Logs.Configuration.LogInformation("Downloading tumbler information of " + configuration.TumblerServer.Uri.AbsoluteUri); var parameters = Retry(3, () => client.GetTumblerParameters()); if (parameters == null) { throw new ConfigException("Unable to download tumbler's parameters"); } if (parameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { throw new ConfigException("The tumbler returned an invalid configuration"); } var standardCycles = new StandardCycles(configuration.Network); var standardCycle = standardCycles.GetStandardCycle(parameters); if (standardCycle == null || !parameters.IsStandard()) { Logs.Configuration.LogWarning("This tumbler has non standard parameters"); if (!AllowInsecure) { throw new ConfigException("This tumbler has non standard parameters"); } standardCycle = null; } await interaction.ConfirmParametersAsync(parameters, standardCycle).ConfigureAwait(false); Repository.UpdateOrInsert("Configuration", TumblerServer.Uri.AbsoluteUri, parameters, (o, n) => n); TumblerParameters = parameters; Logs.Configuration.LogInformation("Tumbler parameters saved"); } Logs.Configuration.LogInformation($"Using tumbler {TumblerServer.Uri.AbsoluteUri}"); } }