Пример #1
0
        public static async Task MainAsync(string[] args)
        {
            try
            {
                var comparer = new CommandlineArgumentComparer();

                var isRegTest = args.Contains("regtest", comparer);
                var isTestNet = args.Contains("testnet", comparer);
                var isStratis = args.Contains("stratis", comparer);
                var isLight   = args.Contains("light", comparer);

                var    useRegistration = args.Contains("registration", comparer);
                var    useTumblebit    = args.Contains("tumblebit", comparer);
                var    useTor          = !args.Contains("noTor", comparer);
                string registrationStoreDirectoryPath = args.GetValueOf("-storedir");

                TumblerProtocolType tumblerProtocol;
                try
                {
                    string tumblerProtocolString = args.GetValueOf("-tumblerProtocol");
                    if (!isRegTest && (tumblerProtocolString != null || !useTor))
                    {
                        Console.WriteLine("Options -TumblerProtocol and -NoTor can only be used in combination with -RegTest switch.");
                        return;
                    }

                    if (tumblerProtocolString != null)
                    {
                        tumblerProtocol = Enum.Parse <TumblerProtocolType>(tumblerProtocolString, true);
                    }
                    else
                    {
                        tumblerProtocol = TumblerProtocolType.Tcp;
                    }

                    if (useTor && tumblerProtocol == TumblerProtocolType.Http)
                    {
                        Console.WriteLine("TumblerProtocol can only be changed to Http when Tor is disabled. Please use -NoTor switch to disable Tor.");
                        return;
                    }
                }
                catch
                {
                    Console.WriteLine($"Incorrect tumbling prococol specified; the valid values are {TumblerProtocolType.Tcp} and {TumblerProtocolType.Http}");
                    return;
                }

                var agent = "Breeze";

                NodeSettings nodeSettings;

                if (isStratis)
                {
                    //if (NodeSettings.PrintHelp(args, Network.StratisMain))
                    //    return;

                    Network network;
                    if (isRegTest)
                    {
                        network = Network.StratisRegTest;
                    }
                    else if (isTestNet)
                    {
                        args    = args.Append("-addnode=51.141.28.47").ToArray();      // TODO: fix this temp hack
                        network = Network.StratisTest;
                    }
                    else
                    {
                        network = Network.StratisMain;
                    }

                    nodeSettings = new NodeSettings(network, ProtocolVersion.ALT_PROTOCOL_VERSION, agent, args: args, loadConfiguration: false);
                }
                else
                {
                    nodeSettings = new NodeSettings(agent: agent, args: args, loadConfiguration: false);
                }

                IFullNodeBuilder fullNodeBuilder = null;

                if (isLight)
                {
                    fullNodeBuilder = new FullNodeBuilder()
                                      .UseNodeSettings(nodeSettings)
                                      .UseLightWallet()
                                      .UseWatchOnlyWallet()
                                      .UseBlockNotification()
                                      .UseTransactionNotification()
                                      .UseApi();
                }
                else
                {
                    fullNodeBuilder = new FullNodeBuilder()
                                      .UseNodeSettings(nodeSettings);

                    if (isStratis)
                    {
                        fullNodeBuilder.UsePosConsensus();
                    }
                    else
                    {
                        fullNodeBuilder.UsePowConsensus();
                    }

                    fullNodeBuilder.UseBlockStore()
                    .UseMempool()
                    .UseBlockNotification()
                    .UseTransactionNotification()
                    .UseWallet()
                    .UseWatchOnlyWallet();

                    if (isStratis)
                    {
                        fullNodeBuilder.AddPowPosMining();
                    }
                    else
                    {
                        fullNodeBuilder.AddMining();
                    }

                    fullNodeBuilder.AddRPC()
                    .UseApi();
                }

                if (useRegistration)
                {
                    //fullNodeBuilder.UseInterNodeCommunication();
                    fullNodeBuilder.UseRegistration();
                }

                // Need this to happen for both TB and non-TB daemon
                string dataDir = nodeSettings.DataDir;
                if (string.IsNullOrEmpty(dataDir))
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        dataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StratisNode");
                    }
                    else
                    {
                        dataDir = Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".stratisnode");
                    }
                }

                string logDir = Path.Combine(dataDir, nodeSettings.Network.RootFolderName, nodeSettings.Network.Name, "Logs");
                Logs.Configure(new FuncLoggerFactory(i => new DualLogger(i, (a, b) => true, false)), logDir);

                // Start NTumbleBit logging to the console
                SetupTumbleBitConsoleLogs(nodeSettings);

                // Currently TumbleBit is bitcoin only
                if (useTumblebit)
                {
                    if (string.IsNullOrEmpty(registrationStoreDirectoryPath))
                    {
                        string networkName;
                        if (isRegTest)
                        {
                            networkName = "StratisRegTest";
                        }
                        else if (isTestNet)
                        {
                            networkName = "StratisTest";
                        }
                        else
                        {
                            networkName = "StratisMain";
                        }

                        registrationStoreDirectoryPath = Path.Combine(dataDir, "stratis", networkName, "registrationHistory.json");
                    }

                    // Those settings are not in NodeSettings yet, so get it directly from the args
                    ConfigurationOptionWrapper <object> registrationStoreDirectory = new ConfigurationOptionWrapper <object>("RegistrationStoreDirectory", registrationStoreDirectoryPath);
                    ConfigurationOptionWrapper <object> torOption             = new ConfigurationOptionWrapper <object>("Tor", useTor);
                    ConfigurationOptionWrapper <object> tumblerProtocolOption = new ConfigurationOptionWrapper <object>("TumblerProtocol", tumblerProtocol);
                    ConfigurationOptionWrapper <object> useDummyAddressOption = new ConfigurationOptionWrapper <object>("UseDummyAddress", true);

                    ConfigurationOptionWrapper <object>[] tumblebitConfigurationOptions = { registrationStoreDirectory, torOption, tumblerProtocolOption, useDummyAddressOption };


                    // We no longer pass the URI in via the command line, the registration feature selects a random one
                    fullNodeBuilder.UseTumbleBit(tumblebitConfigurationOptions);
                }

                IFullNode node = fullNodeBuilder.Build();

                // Add logging to NLog
                SetupTumbleBitNLogs(nodeSettings);

                // Start Full Node - this will also start the API.
                await node.RunAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine("There was a problem initializing the node. Details: '{0}'", ex.Message);
            }
        }
Пример #2
0
        public static void Main(string[] args)
        {
            var comparer          = new CommandlineArgumentComparer();
            var isRegTest         = args.Contains("regtest", comparer);
            var isTestNet         = args.Contains("testnet", comparer);
            var forceRegistration = args.Contains("forceRegistration", comparer);

            var useTor = !args.Contains("noTor", comparer);

            TumblerProtocolType?tumblerProtocol = null;

            try
            {
                string tumblerProtocolString = args.Where(a => a.StartsWith("-tumblerProtocol=")).Select(a => a.Substring("-tumblerProtocol=".Length).Replace("\"", "")).FirstOrDefault();
                if (!isRegTest && (tumblerProtocolString != null || !useTor))
                {
                    Console.WriteLine("Options -TumblerProtocol and -NoTor can only be used in combination with -RegTest switch.");
                    return;
                }

                if (tumblerProtocolString != null)
                {
                    tumblerProtocol = Enum.Parse <TumblerProtocolType>(tumblerProtocolString, true);
                }

                if (useTor && tumblerProtocol.HasValue && tumblerProtocol.Value == TumblerProtocolType.Http)
                {
                    Console.WriteLine("TumblerProtocol can only be changed to Http when Tor is disabled. Please use -NoTor switch to disable Tor.");
                    return;
                }
            }
            catch
            {
                Console.WriteLine($"Incorrect tumbling prococol specified; the valid values are {TumblerProtocolType.Tcp} and {TumblerProtocolType.Http}");
                return;
            }

            var serviceProvider = new ServiceCollection()
                                  .AddLogging()
                                  .AddSingleton <ITumblerService, TumblerService>()
                                  .BuildServiceProvider();

            serviceProvider
            .GetService <ILoggerFactory>()
            .AddConsole(LogLevel.Debug);

            // TODO: It is messy having both a BreezeServer logger and an NTumbleBit logger
            var logger = serviceProvider.GetService <ILoggerFactory>()
                         .CreateLogger <Program>();

            logger.LogInformation("{Time} Reading Breeze server configuration", DateTime.Now);

            // Check OS-specific default config path for the config file. Create default file if it does not exist
            string configDir = BreezeConfiguration.GetDefaultDataDir("BreezeServer");

            if (isRegTest)
            {
                configDir = Path.Combine(configDir, "ImpleumRegTest");
            }
            else if (isTestNet)
            {
                configDir = Path.Combine(configDir, "ImpleumTest");
            }
            else
            {
                configDir = Path.Combine(configDir, "ImpleumMain");
            }

            string configPath = Path.Combine(configDir, "breeze.conf");

            logger.LogInformation("{Time} Configuration file path {Path}", DateTime.Now, configPath);

            BreezeConfiguration config = new BreezeConfiguration(configPath);

            if (!useTor)
            {
                config.UseTor = false;
            }

            logger.LogInformation("{Time} Pre-initialising server to obtain parameters for configuration", DateTime.Now);

            var preTumblerConfig = serviceProvider.GetService <ITumblerService>();

            preTumblerConfig.StartTumbler(config, true, torMandatory: !isRegTest, tumblerProtocol: tumblerProtocol);

            string configurationHash = preTumblerConfig.runtime.ClassicTumblerParameters.GetHash().ToString();
            string onionAddress      = preTumblerConfig.runtime.TorUri.Host.Substring(0, 16);

            NTumbleBit.RsaKey tumblerKey = preTumblerConfig.runtime.TumblerKey;

            // No longer need this instance of the class
            if (config.UseTor)
            {
                preTumblerConfig.runtime.TorConnection.Dispose();
            }
            preTumblerConfig = null;

            string regStorePath = Path.Combine(configDir, "registrationHistory.json");

            logger.LogInformation("{Time} Registration history path {Path}", DateTime.Now, regStorePath);
            logger.LogInformation("{Time} Checking node registration", DateTime.Now);

            BreezeRegistration registration = new BreezeRegistration();

            if (forceRegistration || !registration.CheckBreezeRegistration(config, regStorePath, configurationHash, onionAddress, tumblerKey))
            {
                logger.LogInformation("{Time} Creating or updating node registration", DateTime.Now);
                var regTx = registration.PerformBreezeRegistration(config, regStorePath, configurationHash, onionAddress, tumblerKey);
                if (regTx != null)
                {
                    logger.LogInformation("{Time} Submitted transaction {TxId} via RPC for broadcast", DateTime.Now, regTx.GetHash().ToString());
                }
                else
                {
                    logger.LogInformation("{Time} Unable to broadcast transaction via RPC", DateTime.Now);
                    Environment.Exit(0);
                }
            }
            else
            {
                logger.LogInformation("{Time} Node registration has already been performed", DateTime.Now);
            }

            // Perform collateral balance check and report the result
            Money collateralShortfall;

            if (registration.VerifyCollateral(config, out collateralShortfall))
            {
                logger.LogInformation($"{{Time}} The collateral address {config.TumblerEcdsaKeyAddress} has sufficient funds.", DateTime.Now);
            }
            else
            {
                logger.LogWarning($"{{Time}} The collateral address {config.TumblerEcdsaKeyAddress} doesn't have enough funds. Collateral requirement is {RegistrationParameters.MASTERNODE_COLLATERAL_THRESHOLD} but only {collateralShortfall} is available at the collateral address. This is expected if you have only just run the masternode for the first time. Please send funds to the collateral address no later than {RegistrationParameters.WINDOW_PERIOD_BLOCK_COUNT} blocks after the registration transaction.", DateTime.Now);
            }

            logger.LogInformation("{Time} Starting Tumblebit server", DateTime.Now);

            // The TimeStamp and BlockSignature flags could be set to true when the Stratis network is instantiated.
            // We need to set it to false here to ensure compatibility with the Bitcoin protocol.
            Transaction.TimeStamp = false;
            Block.BlockSignature  = false;

            var tumbler = serviceProvider.GetService <ITumblerService>();

            tumbler.StartTumbler(config, false, torMandatory: !isRegTest, tumblerProtocol: tumblerProtocol);
        }