Example #1
0
        public Transaction PerformBreezeRegistration(BreezeConfiguration config, DBUtils db)
        {
            var network = Network.StratisMain;

            if (config.IsTestNet)
            {
                // TODO: Change to StratisTest when support is added to NStratis
                network = Network.TestNet;
            }

            RPCHelper     stratisHelper   = null;
            RPCClient     stratisRpc      = null;
            BitcoinSecret privateKeyEcdsa = null;

            try {
                stratisHelper   = new RPCHelper(network);
                stratisRpc      = stratisHelper.GetClient(config.RpcUser, config.RpcPassword, config.RpcUrl);
                privateKeyEcdsa = stratisRpc.DumpPrivKey(BitcoinAddress.Create(config.TumblerEcdsaKeyAddress));
            }
            catch (Exception e) {
                Console.WriteLine("ERROR: Unable to retrieve private key to fund registration transaction");
                Console.WriteLine("Is the wallet unlocked?");
                Console.WriteLine(e);
                Environment.Exit(0);
            }

            // Retrieve tumbler's parameters so that the registration details can be constructed
            //var tumblerApi = new TumblerApiAccess(config.TumblerApiBaseUrl);
            //string json = tumblerApi.GetParameters().Result;
            //var tumblerParameters = JsonConvert.DeserializeObject<TumblerParameters>(json);
            var registrationToken = new RegistrationToken(255, config.Ipv4Address, config.Ipv6Address, config.OnionAddress, config.Port, config.TumblerRsaKeyPath);
            var msgBytes          = registrationToken.GetRegistrationTokenBytes(privateKeyEcdsa);

            // Create the registration transaction using the bytes generated above
            var rawTx = CreateBreezeRegistrationTx(network, msgBytes, config.TxOutputValueSetting);

            var txUtils = new TransactionUtils();

            try {
                // Replace fundrawtransaction with C# implementation. The legacy wallet
                // software does not support the RPC call.
                var fundedTx = txUtils.FundRawTx(stratisRpc, rawTx, config.TxFeeValueSetting, BitcoinAddress.Create(config.TumblerEcdsaKeyAddress));
                var signedTx = stratisRpc.SendCommand("signrawtransaction", fundedTx.ToHex());
                var txToSend = new Transaction(((JObject)signedTx.Result)["hex"].Value <string>());

                db.UpdateOrInsert <string>("RegistrationTransactions", DateTime.Now.ToString("yyyyMMddHHmmss"), txToSend.ToHex(), (o, n) => n);
                stratisRpc.SendRawTransaction(txToSend);

                return(txToSend);
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: Unable to broadcast registration transaction");
                Console.WriteLine(e);
            }

            return(null);
        }
Example #2
0
        public static void Main(string[] args)
        {
            var serviceProvider = new ServiceCollection()
                                  .AddLogging()
                                  .AddSingleton <ITumblerService, TumblerService>()
                                  .BuildServiceProvider();

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

            // TODO: It is messy having both a BreezeD 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
            var configDir  = BreezeConfiguration.GetDefaultDataDir("BreezeD");
            var configPath = Path.Combine(configDir, "breeze.conf");

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

            var config = new BreezeConfiguration(configPath);

            var dbPath = Path.Combine(configDir, "db");

            logger.LogInformation("{Time} Database path {Path}", DateTime.Now, dbPath);

            var db = new DBUtils(dbPath);

            logger.LogInformation("{Time} Checking node registration on the blockchain", DateTime.Now);

            var registration = new BreezeRegistration();

            if (!registration.CheckBreezeRegistration(config, db))
            {
                logger.LogInformation("{Time} Creating or updating node registration", DateTime.Now);
                var regTx = registration.PerformBreezeRegistration(config, db);
                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);
            }

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

            db.UpdateOrInsert <string>("TumblerStartupLog", DateTime.Now.ToString("yyyyMMddHHmmss"), "Tumbler starting", (o, n) => n);

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

            tumbler.StartTumbler(config.IsTestNet);
        }
Example #3
0
        public bool CheckBreezeRegistration(BreezeConfiguration config, DBUtils db)
        {
            var network = Network.StratisMain;

            if (config.IsTestNet)
            {
                // TODO: Change to StratisTest when it is added to NStratis
                network = Network.TestNet;
            }

            // In order to determine if the registration sequence has been performed
            // before, and to see if a previous performance is still valid, interrogate
            // the database to see if any transactions have been recorded.

            var transactions = db.GetDictionary <string, string>("RegistrationTransactions");

            // If no transactions exist, the registration definitely needs to be done
            if (transactions == null || transactions.Count == 0)
            {
                return(false);
            }

            string highestKey = null;

            foreach (var txn in transactions)
            {
                // Find most recent transaction. Assume that the rowKeys are ordered
                // lexicographically.
                if (highestKey == null)
                {
                    highestKey = txn.Key;
                }

                if (String.Compare(txn.Key, highestKey) == 1)
                {
                    highestKey = txn.Key;
                }
            }

            var mostRecentTxn = new Transaction(transactions[highestKey]);

            // Decode transaction and check if the decoded bitstream matches the
            // current configuration

            // TODO: Check if transaction is actually confirmed on the blockchain?
            var registrationToken = new RegistrationToken();

            registrationToken.ParseTransaction(mostRecentTxn, network);

            if (!config.Ipv4Address.Equals(registrationToken.Ipv4Addr))
            {
                return(false);
            }

            if (!config.Ipv6Address.Equals(registrationToken.Ipv6Addr))
            {
                return(false);
            }

            if (config.OnionAddress != registrationToken.OnionAddress)
            {
                return(false);
            }

            if (config.Port != registrationToken.Port)
            {
                return(false);
            }

            return(true);
        }