private static void Coordinator_CoinJoinBroadcasted(object sender, Transaction tx) { try { lock (UpdateUnversionedLock) { Money volume = tx.GetIndistinguishableOutputs(includeSingle: false).Sum(x => x.count * x.value); TotalVolume += volume; UnversionedWebBuilder.UpdateMixedTextHtml(TotalVolume); if (Last5CoinJoins.Count > 4) { Last5CoinJoins.RemoveLast(); } Last5CoinJoins.Insert(0, tx.GetHash().ToString()); UnversionedWebBuilder.UpdateCoinJoinsHtml(Last5CoinJoins); } } catch (Exception ex) { Logger.LogWarning(ex, nameof(Program)); } }
#pragma warning disable IDE1006 // Naming Styles public static async Task Main(string[] args) #pragma warning restore IDE1006 // Naming Styles { try { Logger.InitializeDefaults(Path.Combine(Global.DataDir, "Logs.txt")); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; var configFilePath = Path.Combine(Global.DataDir, "Config.json"); var config = new Config(configFilePath); await config.LoadOrCreateDefaultFileAsync(); Logger.LogInfo <Config>("Config is successfully initialized."); var roundConfigFilePath = Path.Combine(Global.DataDir, "CcjRoundConfig.json"); var roundConfig = new CcjRoundConfig(roundConfigFilePath); await roundConfig.LoadOrCreateDefaultFileAsync(); Logger.LogInfo <CcjRoundConfig>("RoundConfig is successfully initialized."); var rpc = new RPCClient( credentials: new RPCCredentialString { UserPassword = new NetworkCredential(config.BitcoinRpcUser, config.BitcoinRpcPassword) }, network: config.Network); await Global.InitializeAsync(config, roundConfig, rpc); try { Directory.CreateDirectory(UnversionedWebBuilder.UnversionedFolder); UnversionedWebBuilder.CreateDownloadTextWithVersionHtml(); UnversionedWebBuilder.CloneAndUpdateOnionIndexHtml(); string[] allLines = File.ReadAllLines(Global.Coordinator.CoinJoinsFilePath); foreach (string line in allLines) { try { var txHash = new uint256(line); Transaction tx = Global.RpcClient.GetRawTransaction(txHash); var volume = tx.GetIndistinguishableOutputs(includeSingle: false).Sum(x => x.count * x.value); TotalVolume += volume; } catch (Exception ex) { Logger.LogWarning(ex, nameof(Program)); } } UnversionedWebBuilder.UpdateMixedTextHtml(TotalVolume); Last5CoinJoins = allLines.TakeLast(5).Reverse().ToList(); UnversionedWebBuilder.UpdateCoinJoinsHtml(Last5CoinJoins); Global.Coordinator.CoinJoinBroadcasted += Coordinator_CoinJoinBroadcasted; } catch (Exception ex) { Logger.LogWarning(ex, nameof(Program)); } var endPoint = "http://localhost:37127/"; using (var host = WebHost.CreateDefaultBuilder(args) .UseStartup <Startup>() .UseUrls(endPoint) .Build()) { await host.RunAsync(); } } catch (Exception ex) { Logger.LogCritical <Program>(ex); } }
#pragma warning disable IDE1006 // Naming Styles public static async Task Main(string[] args) #pragma warning restore IDE1006 // Naming Styles { try { Logger.InitializeDefaults(Path.Combine(Global.DataDir, "Logs.txt")); Logger.LogStarting("Wasabi Backend"); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; var configFilePath = Path.Combine(Global.DataDir, "Config.json"); var config = new Config(configFilePath); await config.LoadOrCreateDefaultFileAsync(); Logger.LogInfo <Config>("Config is successfully initialized."); var roundConfigFilePath = Path.Combine(Global.DataDir, "CcjRoundConfig.json"); var roundConfig = new CcjRoundConfig(roundConfigFilePath); await roundConfig.LoadOrCreateDefaultFileAsync(); Logger.LogInfo <CcjRoundConfig>("RoundConfig is successfully initialized."); var rpc = new RPCClient( credentials: RPCCredentialString.Parse(config.BitcoinRpcConnectionString), network: config.Network); await Global.InitializeAsync(config, roundConfig, rpc); try { Directory.CreateDirectory(UnversionedWebBuilder.UnversionedFolder); UnversionedWebBuilder.CreateDownloadTextWithVersionHtml(); UnversionedWebBuilder.CloneAndUpdateOnionIndexHtml(); var getTxTasks = new List <Task <Transaction> >(); var batch = Global.RpcClient.PrepareBatch(); if (File.Exists(Global.Coordinator.CoinJoinsFilePath)) { string[] allLines = File.ReadAllLines(Global.Coordinator.CoinJoinsFilePath); foreach (string txId in allLines) { getTxTasks.Add(batch.GetRawTransactionAsync(uint256.Parse(txId))); } var waiting = Task.WhenAll(getTxTasks); await batch.SendBatchAsync(); await waiting; foreach (var task in getTxTasks) { try { var tx = await task; var volume = tx.GetIndistinguishableOutputs(includeSingle: false).Sum(x => x.count * x.value); TotalVolume += volume; } catch (Exception ex) { Logger.LogWarning(ex, nameof(Program)); } } UnversionedWebBuilder.UpdateMixedTextHtml(TotalVolume); Last5CoinJoins = allLines.TakeLast(5).Reverse().ToList(); UnversionedWebBuilder.UpdateCoinJoinsHtml(Last5CoinJoins); } Global.Coordinator.CoinJoinBroadcasted += Coordinator_CoinJoinBroadcasted; } catch (Exception ex) { Logger.LogWarning(ex, nameof(Program)); } var endPoint = "http://localhost:37127/"; using (var host = WebHost.CreateDefaultBuilder(args) .UseStartup <Startup>() .UseUrls(endPoint) .Build()) { await host.RunAsync(); } } catch (Exception ex) { Logger.LogCritical <Program>(ex); } // Note: Don't do finally here. Dispose in Startup.cs. }