public Global( ITorManager torManager, IDataDirProvider dataDirProvider, Config config, UiConfig uiConfig, ChaincaseWalletManager walletManager, BitcoinStore bitcoinStore, ChaincaseSynchronizer synchronizer, FeeProviders feeProviders ) { _torManager = torManager; _dataDirProvider = dataDirProvider; _config = config; _uiConfig = uiConfig; _walletManager = walletManager; _bitcoinStore = bitcoinStore; _synchronizer = synchronizer; _feeProviders = feeProviders; using (BenchmarkLogger.Measure()) { StoppingCts = new CancellationTokenSource(); Logger.InitializeDefaults(Path.Combine(DataDir, "Logs.txt")); _uiConfig.LoadOrCreateDefaultFile(); } }
public async Task InitializeNoWalletAsync(CancellationToken cancellationToken = default) { AddressManager = null; Logger.LogDebug($"Global.InitializeNoWalletAsync(): Waiting for a lock"); try { InitializationStarted = true; Logger.LogDebug($"Global.InitializeNoWalletAsync(): Got lock"); Cache = new MemoryCache(new MemoryCacheOptions { SizeLimit = 1_000, ExpirationScanFrequency = TimeSpan.FromSeconds(30) }); var bstoreInitTask = BitcoinStore.InitializeAsync(); var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager"); AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat"); var addrManTask = InitializeAddressManagerBehaviorAsync(); var blocksFolderPath = Path.Combine(DataDir, $"Blocks{Network}"); var userAgent = Constants.UserAgents.RandomElement(); var connectionParameters = new NodeConnectionParameters { UserAgent = userAgent }; if (Config.UseTor) { Synchronizer = new ChaincaseSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.TorSocks5EndPoint); } else { Synchronizer = new ChaincaseSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null); } #region TorProcessInitialization if (Config.UseTor) { await TorManager.StartAsync(ensureRunning : false, DataDir); Logger.LogInfo($"{nameof(TorManager)} is initialized."); } Logger.LogInfo($"Global.InitializeNoWalletAsync():{nameof(TorManager)} is initialized."); #endregion TorProcessInitialization #region BitcoinStoreInitialization await bstoreInitTask.ConfigureAwait(false); // Make sure that the height of the wallets will not be better than the current height of the filters. WalletManager.SetMaxBestHeight(BitcoinStore.IndexStore.SmartHeaderChain.TipHeight); #endregion BitcoinStoreInitialization #region FeeProviderInitialization // Mirrors #region BitcoinCoreInitialization in WalletWasabi var feeProviderList = new List <IFeeProvider> { Synchronizer }; FeeProviders = new FeeProviders(feeProviderList); #endregion FeeProviderInitialization #region MempoolInitialization connectionParameters.TemplateBehaviors.Add(BitcoinStore.CreateUntrustedP2pBehavior()); #endregion MempoolInitialization #region AddressManagerInitialization AddressManagerBehavior addressManagerBehavior = await addrManTask.ConfigureAwait(false); connectionParameters.TemplateBehaviors.Add(addressManagerBehavior); #endregion AddressManagerInitialization #region P2PInitialization if (Network == Network.RegTest) { Nodes = new NodesGroup(Network, requirements: Constants.NodeRequirements); try { EndPoint bitcoinCoreEndpoint = Config.GetBitcoinP2pEndPoint(); Node node = await Node.ConnectAsync(NBitcoin.Network.RegTest, bitcoinCoreEndpoint).ConfigureAwait(false); Nodes.ConnectedNodes.Add(node); RegTestMempoolServingNode = await Node.ConnectAsync(NBitcoin.Network.RegTest, bitcoinCoreEndpoint).ConfigureAwait(false); RegTestMempoolServingNode.Behaviors.Add(BitcoinStore.CreateUntrustedP2pBehavior()); } catch (SocketException ex) { Logger.LogError(ex); } } else { if (Config.UseTor) { // onlyForOnionHosts: false - Connect to clearnet IPs through Tor, too. connectionParameters.TemplateBehaviors.Add(new SocksSettingsBehavior(Config.TorSocks5EndPoint, onlyForOnionHosts: false, networkCredential: null, streamIsolation: true)); // allowOnlyTorEndpoints: true - Connect only to onions and don't connect to clearnet IPs at all. // This of course makes the first setting unneccessary, but it's better if that's around, in case someone wants to tinker here. connectionParameters.EndpointConnector = new DefaultEndpointConnector(allowOnlyTorEndpoints: Network == Network.Main); await AddKnownBitcoinFullNodeAsHiddenServiceAsync(AddressManager).ConfigureAwait(false); } Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements); Nodes.MaximumNodeConnection = 12; RegTestMempoolServingNode = null; } Nodes.Connect(); Logger.LogInfo("Global.InitializeNoWalletAsync(): Start connecting to nodes..."); var regTestMempoolServingNode = RegTestMempoolServingNode; if (regTestMempoolServingNode != null) { regTestMempoolServingNode.VersionHandshake(); Logger.LogInfo("Global.InitializeNoWalletAsync(): Start connecting to mempool serving regtest node..."); } #endregion P2PInitialization #region SynchronizerInitialization var requestInterval = TimeSpan.FromSeconds(30); if (Network == Network.RegTest) { requestInterval = TimeSpan.FromSeconds(5); } int maxFiltSyncCount = Network == Network.Main ? 1000 : 10000; // On testnet, filters are empty, so it's faster to query them together Synchronizer.Start(requestInterval, TimeSpan.FromMinutes(5), maxFiltSyncCount); Logger.LogInfo("Global.InitializeNoWalletAsync(): Start synchronizing filters..."); #endregion SynchronizerInitialization TransactionBroadcaster = new TransactionBroadcaster(Network, BitcoinStore, Synchronizer, Nodes, WalletManager, null); CoinJoinProcessor = new CoinJoinProcessor(Synchronizer, WalletManager, null); #region Blocks provider var blockProvider = new CachedBlockProvider( new SmartBlockProvider( new P2pBlockProvider(Nodes, null, Synchronizer, Config.ServiceConfiguration, Network), Cache), new FileSystemBlockRepository(blocksFolderPath, Network)); #endregion Blocks provider WalletManager.RegisterServices(BitcoinStore, Synchronizer, Nodes, Config.ServiceConfiguration, FeeProviders, blockProvider); Initialized(this, EventArgs.Empty); IsInitialized = true; }
public StatusViewModel(Global global, ChaincaseWalletManager walletManager, Config config, UiConfig uiConfig, BitcoinStore bitcoinStore, ChaincaseSynchronizer synchronizer) { _global = global; _walletManager = walletManager; _bitcoinStore = bitcoinStore; _Config = config; _uiConfig = uiConfig; _synchronizer = synchronizer; Backend = BackendStatus.NotConnected; Tor = TorStatus.NotRunning; Peers = 0; BtcPrice = "$0"; ActiveStatuses = new StatusSet(); UseTor = _Config.UseTor; // Do not make it dynamic, because if you change this config settings only next time will it activate. if (_global.IsInitialized) { OnAppInitialized(this, new AppInitializedEventArgs(_global)); } else { _global.Initialized += OnAppInitialized; } _status = ActiveStatuses.WhenAnyValue(x => x.CurrentStatus) .Select(x => x.ToString()) .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.Status) .DisposeWith(Disposables); // Set number of peers currently connected Peers = Tor == TorStatus.NotRunning ? 0 : Nodes.Count; // Subscribe to downloading block activity Observable.FromEventPattern <bool>(typeof(P2pBlockProvider), nameof(P2pBlockProvider.DownloadingBlockChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => DownloadingBlock = x.EventArgs) .DisposeWith(Disposables); // Calculate progress precentage bool progressReset = true; _progressPercent = this.WhenAnyValue(x => x.ActiveStatuses.CurrentStatus, x => x.Peers) .Select(tup => { var(status, peers) = tup; if (peers == 0 && progressReset) { progressReset = false; return(0.01); } switch (status.Type) { case StatusType.Ready: progressReset = true; return(1); case StatusType.Synchronizing: return(status.Percentage / 200.0 + 0.3); case StatusType.Connecting: default: return(0.3); } }) .ToProperty(this, x => x.ProgressPercent); IDisposable walletCheckingInterval = null; Observable.FromEventPattern <bool>(typeof(Wallet), nameof(Wallet.InitializingChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => { if (x.EventArgs) { TryAddStatus(StatusType.WalletLoading); if (walletCheckingInterval is null) { walletCheckingInterval = Observable.Interval(TimeSpan.FromSeconds(1)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { var wallet = _walletManager.CurrentWallet; if (wallet is { }) { var startingHeight = SmartHeader.GetStartingHeader(wallet.Network).Height; if (wallet.LastProcessedFilter?.Header?.Height is uint lastProcessedFilterHeight && lastProcessedFilterHeight > startingHeight && _bitcoinStore?.SmartHeaderChain?.TipHeight is uint tipHeight && tipHeight > startingHeight) { var allFilters = tipHeight - startingHeight; var processedFilters = lastProcessedFilterHeight - startingHeight; var perc = allFilters == 0 ? 100 : ((decimal)processedFilters / allFilters * 100); TryAddStatus(StatusType.WalletProcessingFilters, (ushort)perc); } var txProcessor = wallet.TransactionProcessor; if (txProcessor is { }) { var perc = txProcessor.QueuedTxCount == 0 ? 100 : ((decimal)txProcessor.QueuedProcessedTxCount / txProcessor.QueuedTxCount * 100); TryAddStatus(StatusType.WalletProcessingTransactions, (ushort)perc); } }