Exemple #1
0
        public static async Task InitializeWalletServiceAsync(KeyManager keyManager)
        {
            ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
            WalletService  = new WalletService(keyManager, Synchronizer, ChaumianClient, MemPoolService, Nodes, DataDir, Config.ServiceConfiguration);

            ChaumianClient.Start();
            Logger.LogInfo("Start Chaumian CoinJoin service...");

            using (CancelWalletServiceInitialization = new CancellationTokenSource())
            {
                Logger.LogInfo("Starting WalletService...");
                await WalletService.InitializeAsync(CancelWalletServiceInitialization.Token);

                Logger.LogInfo("WalletService started.");
            }
            CancelWalletServiceInitialization      = null;        // Must make it null explicitly, because dispose won't make it null.
            WalletService.Coins.CollectionChanged += Coins_CollectionChanged;
        }
Exemple #2
0
        public static async Task InitializeNoWalletAsync()
        {
            WalletService  = null;
            ChaumianClient = null;
            AddressManager = null;
            TorManager     = null;

            #region ConfigInitialization

            Config = new Config(Path.Combine(DataDir, "Config.json"));
            await Config.LoadOrCreateDefaultFileAsync();

            Logger.LogInfo <Config>("Config is successfully initialized.");

            #endregion ConfigInitialization

            BitcoinStore = new BitcoinStore();
            var bstoreInitTask = BitcoinStore.InitializeAsync(Path.Combine(DataDir, "BitcoinStore"), Network);
            var hwiInitTask    = HwiProcessManager.InitializeAsync(DataDir, Network);

            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");
            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            if (Config.UseTor.Value)
            {
                Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
            }
            else
            {
                Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null);
            }

            UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);

            #region ProcessKillSubscription

            AppDomain.CurrentDomain.ProcessExit += async(s, e) => await TryDesperateDequeueAllCoinsAsync();

            Console.CancelKeyPress += async(s, e) =>
            {
                e.Cancel = true;
                Logger.LogWarning("Process was signaled for killing.", nameof(Global));

                KillRequested = true;
                await TryDesperateDequeueAllCoinsAsync();

                Dispatcher.UIThread.PostLogException(() =>
                {
                    Application.Current?.MainWindow?.Close();
                });
            };

            #endregion ProcessKillSubscription

            #region TorProcessInitialization

            if (Config.UseTor.Value)
            {
                TorManager = new TorProcessManager(Config.GetTorSocks5EndPoint(), TorLogsFile);
            }
            else
            {
                TorManager = TorProcessManager.Mock();
            }
            TorManager.Start(false, DataDir);

            var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");
            TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

            Logger.LogInfo <TorProcessManager>($"{nameof(TorProcessManager)} is initialized.");

            #endregion TorProcessInitialization

            #region AddressManagerInitialization

            var needsToDiscoverPeers = true;
            if (Network == Network.RegTest)
            {
                AddressManager = new AddressManager();
                Logger.LogInfo <AddressManager>($"Fake {nameof(AddressManager)} is initialized on the RegTest.");
            }
            else
            {
                try
                {
                    AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);

                    // The most of the times we don't need to discover new peers. Instead, we can connect to
                    // some of those that we already discovered in the past. In this case we assume that we
                    // assume that discovering new peers could be necessary if out address manager has less
                    // than 500 addresses. A 500 addresses could be okay because previously we tried with
                    // 200 and only one user reported he/she was not able to connect (there could be many others,
                    // of course).
                    // On the other side, increasing this number forces users that do not need to discover more peers
                    // to spend resources (CPU/bandwith) to discover new peers.
                    needsToDiscoverPeers = Config.UseTor == true || AddressManager.Count < 500;
                    Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
                }
                catch (DirectoryNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (FileNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (OverflowException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/712
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(OverflowException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
                catch (FormatException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/880
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(FormatException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
            }

            var addressManagerBehavior = new AddressManagerBehavior(AddressManager)
            {
                Mode = needsToDiscoverPeers ? AddressManagerBehaviorMode.Discover : AddressManagerBehaviorMode.None
            };
            connectionParameters.TemplateBehaviors.Add(addressManagerBehavior);

            #endregion AddressManagerInitialization

            #region MempoolInitialization

            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            #endregion MempoolInitialization

            #region HwiProcessInitialization

            try
            {
                await hwiInitTask;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, nameof(Global));
            }

            #endregion HwiProcessInitialization

            #region BitcoinStoreInitialization

            await bstoreInitTask;

            #endregion BitcoinStoreInitialization

            #region P2PInitialization

            if (Network == Network.RegTest)
            {
                Nodes = new NodesGroup(Network, requirements: Constants.NodeRequirements);
                try
                {
                    Node node = await Node.ConnectAsync(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    Nodes.ConnectedNodes.Add(node);

                    RegTestMemPoolServingNode = await Node.ConnectAsync(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    RegTestMemPoolServingNode.Behaviors.Add(new MemPoolBehavior(MemPoolService));
                }
                catch (SocketException ex)
                {
                    Logger.LogError(ex, nameof(Global));
                }
            }
            else
            {
                if (Config.UseTor is true)
                {
                    // onlyForOnionHosts: false - Connect to clearnet IPs through Tor, too.
                    connectionParameters.TemplateBehaviors.Add(new SocksSettingsBehavior(Config.GetTorSocks5EndPoint(), 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);
                }
                Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements);

                RegTestMemPoolServingNode = null;
            }

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            if (RegTestMemPoolServingNode != null)
            {
                RegTestMemPoolServingNode.VersionHandshake();
                Logger.LogInfo("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("Start synchronizing filters...");

            #endregion SynchronizerInitialization

            Initialized = true;
        }
Exemple #3
0
        public Global(string dataDir, string torLogsFile, Config config, UiConfig uiConfig, WalletManager walletManager)
        {
            using (BenchmarkLogger.Measure())
            {
                CrashReporter = new CrashReporter();
                StoppingCts   = new CancellationTokenSource();
                DataDir       = dataDir;
                Config        = config;
                UiConfig      = uiConfig;
                TorSettings   = new TorSettings(DataDir, torLogsFile, distributionFolderPath: EnvironmentHelpers.GetFullBaseDirectory());

                Logger.InitializeDefaults(Path.Combine(DataDir, "Logs.txt"));

                HostedServices = new HostedServices();
                WalletManager  = walletManager;

                LegalDocuments = LegalDocuments.TryLoadAgreed(DataDir);

                WalletManager.OnDequeue += WalletManager_OnDequeue;
                WalletManager.WalletRelevantTransactionProcessed += WalletManager_WalletRelevantTransactionProcessed;

                var networkWorkFolderPath = Path.Combine(DataDir, "BitcoinStore", Network.ToString());
                var transactionStore      = new AllTransactionStore(networkWorkFolderPath, Network);
                var indexStore            = new IndexStore(Path.Combine(networkWorkFolderPath, "IndexStore"), Network, new SmartHeaderChain());
                var mempoolService        = new MempoolService();
                var blocks = new FileSystemBlockRepository(Path.Combine(networkWorkFolderPath, "Blocks"), Network);

                BitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);

                SingleInstanceChecker = new SingleInstanceChecker(Network);

                if (Config.UseTor)
                {
                    Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.TorSocks5EndPoint);
                }
                else
                {
                    Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null);
                }
            }
        }
Exemple #4
0
        public async Task InitializeNoWalletAsync()
        {
            InitializationStarted = true;
            AddressManager        = null;
            TorManager            = null;
            var cancel = StoppingCts.Token;

            try
            {
                await SingleInstanceChecker.CheckAsync().ConfigureAwait(false);

                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 WasabiSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.TorSocks5EndPoint);
                }
                else
                {
                    Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null);
                }

                HostedServices.Register(new UpdateChecker(TimeSpan.FromMinutes(7), Synchronizer), "Software Update Checker");

                #region ProcessKillSubscription

                AppDomain.CurrentDomain.ProcessExit += async(s, e) => await DisposeAsync().ConfigureAwait(false);

                Console.CancelKeyPress += async(s, e) =>
                {
                    e.Cancel = true;
                    Logger.LogWarning("Process was signaled for killing.", nameof(Global));
                    await DisposeAsync().ConfigureAwait(false);
                };

                #endregion ProcessKillSubscription

                cancel.ThrowIfCancellationRequested();

                #region TorProcessInitialization

                if (Config.UseTor)
                {
                    TorManager = new TorProcessManager(Config.TorSocks5EndPoint, TorLogsFile);
                }
                else
                {
                    TorManager = TorProcessManager.Mock();
                }
                TorManager.Start(false, DataDir);

                var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");
                TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

                Logger.LogInfo($"{nameof(TorProcessManager)} is initialized.");

                #endregion TorProcessInitialization

                cancel.ThrowIfCancellationRequested();

                #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

                cancel.ThrowIfCancellationRequested();

                #region BitcoinCoreInitialization

                try
                {
                    if (Config.StartLocalBitcoinCoreOnStartup)
                    {
                        BitcoinCoreNode = await CoreNode
                                          .CreateAsync(
                            new CoreNodeParams(
                                Network,
                                BitcoinStore.MempoolService,
                                HostedServices,
                                Config.LocalBitcoinCoreDataDir,
                                tryRestart : false,
                                tryDeleteDataDir : false,
                                EndPointStrategy.Default(Network, EndPointType.P2p),
                                EndPointStrategy.Default(Network, EndPointType.Rpc),
                                txIndex : null,
                                prune : null,
                                userAgent : $"/WasabiClient:{Constants.ClientVersion}/",
                                Cache),
                            cancel)
                                          .ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex);
                }

                await HostedServices.StartAllAsync(cancel).ConfigureAwait(false);

                var feeProviderList = new List <IFeeProvider>
                {
                    Synchronizer
                };

                var rpcFeeProvider = HostedServices.FirstOrDefault <RpcFeeProvider>();
                if (rpcFeeProvider is { })
Exemple #5
0
        public static void InitializeNoWallet()
        {
            WalletService  = null;
            ChaumianClient = null;

            AppDomain.CurrentDomain.ProcessExit += async(s, e) => await TryDesperateDequeueAllCoinsAsync();

            Console.CancelKeyPress += async(s, e) =>
            {
                e.Cancel = true;
                Logger.LogWarning("Process was signaled for killing.", nameof(Global));
                await TryDesperateDequeueAllCoinsAsync();

                Dispatcher.UIThread.Post(() =>
                {
                    Application.Current.MainWindow.Close();
                });
            };

            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");

            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            AddressManager = null;
            TorManager     = null;

            TorManager = new TorProcessManager(Config.GetTorSocks5EndPoint(), TorLogsFile);
            TorManager.Start(false, DataDir);
            var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");

            TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

            Logger.LogInfo <TorProcessManager>($"{nameof(TorProcessManager)} is initialized.");

            var needsToDiscoverPeers = true;

            if (Network == Network.RegTest)
            {
                AddressManager = new AddressManager();
                Logger.LogInfo <AddressManager>($"Fake {nameof(AddressManager)} is initialized on the RegTest.");
            }
            else
            {
                try
                {
                    AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);

                    // The most of the times we don't need to discover new peers. Instead, we can connect to
                    // some of those that we already discovered in the past. In this case we assume that we
                    // assume that discovering new peers could be necessary if out address manager has less
                    // than 500 addresses. A 500 addresses could be okay because previously we tried with
                    // 200 and only one user reported he/she was not able to connect (there could be many others,
                    // of course).
                    // On the other side, increasing this number forces users that do not need to discover more peers
                    // to spend resources (CPU/bandwith) to discover new peers.
                    needsToDiscoverPeers = AddressManager.Count < 500;
                    Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
                }
                catch (DirectoryNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (FileNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (OverflowException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/712
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(OverflowException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
                catch (FormatException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/880
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(FormatException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
            }

            var addressManagerBehavior = new AddressManagerBehavior(AddressManager)
            {
                Mode = needsToDiscoverPeers ? AddressManagerBehaviorMode.Discover : AddressManagerBehaviorMode.None
            };

            connectionParameters.TemplateBehaviors.Add(addressManagerBehavior);
            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            if (Network == Network.RegTest)
            {
                Nodes = new NodesGroup(Network, requirements: Constants.NodeRequirements);
                try
                {
                    Node node = Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));
                    Nodes.ConnectedNodes.Add(node);

                    RegTestMemPoolServingNode = Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    RegTestMemPoolServingNode.Behaviors.Add(new MemPoolBehavior(MemPoolService));
                }
                catch (SocketException ex)
                {
                    Logger.LogError(ex, nameof(Global));
                }
            }
            else
            {
                Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements);

                RegTestMemPoolServingNode = null;
            }

            Synchronizer = new WasabiSynchronizer(Network, IndexFilePath, Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());

            UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            if (!(RegTestMemPoolServingNode is null))
            {
                RegTestMemPoolServingNode.VersionHandshake();
                Logger.LogInfo("Start connecting to mempool serving regtest node...");
            }

            var requestInterval = TimeSpan.FromSeconds(30);

            if (Network == Network.RegTest)
            {
                requestInterval = TimeSpan.FromSeconds(5);
            }
            Synchronizer.Start(requestInterval, TimeSpan.FromMinutes(5), 1000);
            Logger.LogInfo("Start synchronizing filters...");
        }
Exemple #6
0
        public static async Task InitializeWalletServiceAsync(KeyManager keyManager)
        {
            using (CancelWalletServiceInitialization = new CancellationTokenSource())
            {
                var token = CancelWalletServiceInitialization.Token;
                while (!Initialized)
                {
                    await Task.Delay(100, token);
                }

                if (Config.UseTor.Value)
                {
                    ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, () => Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
                }
                else
                {
                    ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, Config.GetFallbackBackendUri(), null);
                }
                WalletService = new WalletService(BitcoinStore, keyManager, Synchronizer, ChaumianClient, MemPoolService, Nodes, DataDir, Config.ServiceConfiguration);

                ChaumianClient.Start();
                Logger.LogInfo("Start Chaumian CoinJoin service...");

                Logger.LogInfo("Starting WalletService...");
                await WalletService.InitializeAsync(token);

                Logger.LogInfo("WalletService started.");

                token.ThrowIfCancellationRequested();
                WalletService.Coins.CollectionChanged += Coins_CollectionChanged;
            }
            CancelWalletServiceInitialization = null;             // Must make it null explicitly, because dispose won't make it null.
        }
Exemple #7
0
        public async Task InitializeNoWalletAsync()
        {
            try
            {
                WalletService  = null;
                ChaumianClient = null;
                AddressManager = null;
                TorManager     = null;

                #region ConfigInitialization

                Config = new Config(Path.Combine(DataDir, "Config.json"));
                await Config.LoadOrCreateDefaultFileAsync();

                Logger.LogInfo($"{nameof(Config)} is successfully initialized.");

                #endregion ConfigInitialization

                BitcoinStore = new BitcoinStore();
                var bstoreInitTask           = BitcoinStore.InitializeAsync(Path.Combine(DataDir, "BitcoinStore"), Network);
                var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");

                AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
                var addrManTask = InitializeAddressManagerBehaviorAsync();

                var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
                var connectionParameters = new NodeConnectionParameters {
                    UserAgent = "/Satoshi:0.18.1/"
                };

                if (Config.UseTor)
                {
                    Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.TorSocks5EndPoint);
                }
                else
                {
                    Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null);
                }

                HostedServices.Register(new UpdateChecker(TimeSpan.FromMinutes(7), Synchronizer.WasabiClient), "Software Update Checker");

                #region ProcessKillSubscription

                AppDomain.CurrentDomain.ProcessExit += async(s, e) => await TryDesperateDequeueAllCoinsAsync();

                Console.CancelKeyPress += async(s, e) =>
                {
                    e.Cancel = true;
                    Logger.LogWarning("Process was signaled for killing.");

                    KillRequested = true;
                    await TryDesperateDequeueAllCoinsAsync();

                    Dispatcher.UIThread.PostLogException(() =>
                    {
                        var window = (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).MainWindow;
                        window?.Close();
                    });
                    await DisposeAsync();

                    Logger.LogSoftwareStopped("Wasabi");
                };

                #endregion ProcessKillSubscription

                #region TorProcessInitialization

                if (Config.UseTor)
                {
                    TorManager = new TorProcessManager(Config.TorSocks5EndPoint, TorLogsFile);
                }
                else
                {
                    TorManager = TorProcessManager.Mock();
                }
                TorManager.Start(false, DataDir);

                var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");
                TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

                Logger.LogInfo($"{nameof(TorProcessManager)} is initialized.");

                #endregion TorProcessInitialization

                #region BitcoinStoreInitialization

                await bstoreInitTask;

                #endregion BitcoinStoreInitialization

                #region BitcoinCoreInitialization

                try
                {
                    if (Config.StartLocalBitcoinCoreOnStartup)
                    {
                        BitcoinCoreNode = await CoreNode
                                          .CreateAsync(
                            new CoreNodeParams(
                                Network,
                                BitcoinStore.MempoolService,
                                HostedServices,
                                Config.LocalBitcoinCoreDataDir,
                                tryRestart : false,
                                tryDeleteDataDir : false,
                                EndPointStrategy.Default(Network, EndPointType.P2p),
                                EndPointStrategy.Default(Network, EndPointType.Rpc),
                                txIndex : null,
                                prune : null,
                                userAgent : $"/WasabiClient:{Constants.ClientVersion.ToString()}/"),
                            CancellationToken.None)
                                          .ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex);
                }

                await HostedServices.StartAllAsync(StoppingCts.Token).ConfigureAwait(false);

                var feeProviderList = new List <IFeeProvider>
                {
                    Synchronizer
                };

                var rpcFeeProvider = HostedServices.FirstOrDefault <RpcFeeProvider>();
                if (rpcFeeProvider is { })
                {
                    feeProviderList.Insert(0, rpcFeeProvider);
                }

                FeeProviders = new FeeProviders(feeProviderList);

                #endregion BitcoinCoreInitialization

                #region MempoolInitialization

                connectionParameters.TemplateBehaviors.Add(BitcoinStore.CreateUntrustedP2pBehavior());

                #endregion MempoolInitialization

                #region AddressManagerInitialization

                AddressManagerBehavior addressManagerBehavior = await addrManTask;
                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(Network.RegTest, bitcoinCoreEndpoint).ConfigureAwait(false);

                        Nodes.ConnectedNodes.Add(node);

                        RegTestMempoolServingNode = await Node.ConnectAsync(Network.RegTest, bitcoinCoreEndpoint).ConfigureAwait(false);

                        RegTestMempoolServingNode.Behaviors.Add(BitcoinStore.CreateUntrustedP2pBehavior());
                    }
                    catch (SocketException ex)
                    {
                        Logger.LogError(ex);
                    }
                }
                else
                {
                    if (Config.UseTor is true)
                    {
                        // 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 do not connect to clearnet IPs at all.
                        // This of course makes the first setting unnecessary, 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);
                    }
                    Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements);

                    RegTestMempoolServingNode = null;
                }

                Nodes.Connect();
                Logger.LogInfo("Start connecting to nodes...");

                var regTestMempoolServingNode = RegTestMempoolServingNode;
                if (regTestMempoolServingNode is { })
Exemple #8
0
        public async Task InitializeWalletServiceAsync(KeyManager keyManager)
        {
            using (_cancelWalletServiceInitialization = new CancellationTokenSource())
            {
                var token = _cancelWalletServiceInitialization.Token;
                while (!Initialized)
                {
                    await Task.Delay(100, token);
                }

                if (Config.UseTor)
                {
                    ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, () => Config.GetCurrentBackendUri(), Config.TorSocks5EndPoint);
                }
                else
                {
                    ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, Config.GetFallbackBackendUri(), null);
                }

                try
                {
                    keyManager.CorrectBlockHeights(BitcoinStore.HashChain); // Block heights are wrong sometimes. It's a hack. We have to retroactively fix existing wallets, but also we have to figure out where we ruin the block heights.
                }
                catch (Exception ex)                                        // Whatever this is not critical, but let's log it.
                {
                    Logger.LogWarning(ex, nameof(Global));
                }

                WalletService = new WalletService(BitcoinStore, keyManager, Synchronizer, ChaumianClient, MempoolService, Nodes, DataDir, Config.ServiceConfiguration);

                ChaumianClient.Start();
                Logger.LogInfo("Start Chaumian CoinJoin service...");

                Logger.LogInfo($"Starting {nameof(WalletService)}...");
                await WalletService.InitializeAsync(token);

                Logger.LogInfo($"{nameof(WalletService)} started.");

                token.ThrowIfCancellationRequested();
                WalletService.Coins.CollectionChanged += Coins_CollectionChanged;
            }
            _cancelWalletServiceInitialization = null;             // Must make it null explicitly, because dispose won't make it null.
        }
Exemple #9
0
        public static async Task InitializeNoWalletAsync()
        {
            WalletService  = null;
            ChaumianClient = null;
            AddressManager = null;
            TorManager     = null;

            #region ConfigInitialization

            Config = new Config(Path.Combine(DataDir, "Config.json"));
            await Config.LoadOrCreateDefaultFileAsync();

            Logger.LogInfo <Config>("Config is successfully initialized.");

            #endregion ConfigInitialization

            BitcoinStore = new BitcoinStore();
            var bstoreInitTask           = BitcoinStore.InitializeAsync(Path.Combine(DataDir, "BitcoinStore"), Network);
            var hwiInitTask              = HwiProcessManager.InitializeAsync(DataDir, Network);
            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");
            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var addrManTask = InitializeAddressManagerBehaviorAsync();

            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            if (Config.UseTor.Value)
            {
                Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, () => Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
            }
            else
            {
                Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, Config.GetFallbackBackendUri(), null);
            }

            UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);

            #region ProcessKillSubscription

            AppDomain.CurrentDomain.ProcessExit += async(s, e) => await TryDesperateDequeueAllCoinsAsync();

            Console.CancelKeyPress += async(s, e) => { e.Cancel = true; await StopAndExitAsync(); };

            #endregion ProcessKillSubscription

            #region TorProcessInitialization

            if (Config.UseTor.Value)
            {
                TorManager = new TorProcessManager(Config.GetTorSocks5EndPoint(), TorLogsFile);
            }
            else
            {
                TorManager = TorProcessManager.Mock();
            }
            TorManager.Start(false, DataDir);

            var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");
            TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

            Logger.LogInfo <TorProcessManager>($"{nameof(TorProcessManager)} is initialized.");

            #endregion TorProcessInitialization

            #region MempoolInitialization

            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            #endregion MempoolInitialization

            #region HwiProcessInitialization

            try
            {
                await hwiInitTask;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, nameof(Global));
            }

            #endregion HwiProcessInitialization

            #region BitcoinStoreInitialization

            await bstoreInitTask;

            #endregion BitcoinStoreInitialization

            #region AddressManagerInitialization

            AddressManagerBehavior addressManagerBehavior = await addrManTask;
            connectionParameters.TemplateBehaviors.Add(addressManagerBehavior);

            #endregion AddressManagerInitialization

            #region P2PInitialization

            if (Network == Network.RegTest)
            {
                Nodes = new NodesGroup(Network, requirements: Constants.NodeRequirements);
                try
                {
                    Node node = await Node.ConnectAsync(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    Nodes.ConnectedNodes.Add(node);

                    RegTestMemPoolServingNode = await Node.ConnectAsync(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    RegTestMemPoolServingNode.Behaviors.Add(new MemPoolBehavior(MemPoolService));
                }
                catch (SocketException ex)
                {
                    Logger.LogError(ex, nameof(Global));
                }
            }
            else
            {
                if (Config.UseTor is true)
                {
                    // onlyForOnionHosts: false - Connect to clearnet IPs through Tor, too.
                    connectionParameters.TemplateBehaviors.Add(new SocksSettingsBehavior(Config.GetTorSocks5EndPoint(), 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);
                }
                Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements);

                RegTestMemPoolServingNode = null;
            }

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            if (RegTestMemPoolServingNode != null)
            {
                RegTestMemPoolServingNode.VersionHandshake();
                Logger.LogInfo("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("Start synchronizing filters...");

            #endregion SynchronizerInitialization

            #region JsonRpcServerInitialization

            var jsonRpcServerConfig = new JsonRpcServerConfiguration(Config);
            if (jsonRpcServerConfig.IsEnabled)
            {
                RpcServer = new JsonRpcServer(jsonRpcServerConfig);
                RpcServer.Start();
            }

            #endregion JsonRpcServerInitialization

            Initialized = true;
        }
Exemple #10
0
        public Global(string dataDir, string torLogsFile, Config config, UiConfig uiConfig, WalletManager walletManager)
        {
            using (BenchmarkLogger.Measure())
            {
                StoppingCts = new CancellationTokenSource();
                DataDir     = dataDir;
                Config      = config;
                UiConfig    = uiConfig;
                TorSettings = new TorSettings(DataDir, torLogsFile, distributionFolderPath: EnvironmentHelpers.GetFullBaseDirectory());

                HostedServices = new HostedServices();
                WalletManager  = walletManager;

                WalletManager.OnDequeue += WalletManager_OnDequeue;
                WalletManager.WalletRelevantTransactionProcessed += WalletManager_WalletRelevantTransactionProcessed;

                var networkWorkFolderPath = Path.Combine(DataDir, "BitcoinStore", Network.ToString());
                var transactionStore      = new AllTransactionStore(networkWorkFolderPath, Network);
                var indexStore            = new IndexStore(Path.Combine(networkWorkFolderPath, "IndexStore"), Network, new SmartHeaderChain());
                var mempoolService        = new MempoolService();
                var blocks = new FileSystemBlockRepository(Path.Combine(networkWorkFolderPath, "Blocks"), Network);

                BitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);

                HttpClientFactory httpClientFactory = Config.UseTor
                                        ? new HttpClientFactory(Config.TorSocks5EndPoint, backendUriGetter: () => Config.GetCurrentBackendUri())
                                        : new HttpClientFactory(torEndPoint: null, backendUriGetter: () => Config.GetFallbackBackendUri());

                Synchronizer = new WasabiSynchronizer(Network, BitcoinStore, httpClientFactory);
                LegalChecker = new(DataDir);
            }
        }
Exemple #11
0
        public static void InitializeNoWallet()
        {
            WalletService  = null;
            ChaumianClient = null;

            AppDomain.CurrentDomain.ProcessExit += async(s, e) => await TryDesperateDequeueAllCoinsAsync();

            Console.CancelKeyPress += async(s, e) =>
            {
                e.Cancel = true;
                Logger.LogWarning("Process was signaled for killing.", nameof(Global));
                await TryDesperateDequeueAllCoinsAsync();

                Dispatcher.UIThread.Post(() =>
                {
                    Application.Current.MainWindow.Close();
                });
            };

            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");

            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            AddressManager = null;
            TorManager     = null;

            TorManager = new TorProcessManager(Config.GetTorSocks5EndPoint(), TorLogsFile);
            TorManager.Start(false, DataDir);
            var fallbackRequestTestUri = new Uri(Config.GetFallbackBackendUri(), "/api/software/versions");

            TorManager.StartMonitor(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), DataDir, fallbackRequestTestUri);

            Logger.LogInfo <TorProcessManager>($"{nameof(TorProcessManager)} is initialized.");

            var needsToDiscoverPeers = true;

            if (Network == Network.RegTest)
            {
                AddressManager = new AddressManager();
                Logger.LogInfo <AddressManager>($"Fake {nameof(AddressManager)} is initialized on the RegTest.");
            }
            else
            {
                try
                {
                    AddressManager       = AddressManager.LoadPeerFile(AddressManagerFilePath);
                    needsToDiscoverPeers = AddressManager.Count < 200;
                    Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
                }
                catch (DirectoryNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (FileNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (OverflowException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/712
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(OverflowException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
                catch (FormatException ex)
                {
                    // https://github.com/zkSNACKs/WalletWasabi/issues/880
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} has thrown `{nameof(FormatException)}`. Attempting to autocorrect.");
                    File.Delete(AddressManagerFilePath);
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} autocorrection is successful.");
                }
            }

            var addressManagerBehavior = new AddressManagerBehavior(AddressManager);

            addressManagerBehavior.Mode = needsToDiscoverPeers ? AddressManagerBehaviorMode.Discover : AddressManagerBehaviorMode.None;
            connectionParameters.TemplateBehaviors.Add(addressManagerBehavior);
            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            if (Network == Network.RegTest | Network.Name == "chaincoin-reg")             //todopw: extend
            {
                Nodes = new NodesGroup(Network, requirements: Constants.NodeRequirements);
                try
                {
                    // todopw: extend
                    Node node;
                    if (Network.Name == "chaincoin-reg")
                    {
                        node = Node.Connect(NBitcoin.Altcoins.Chaincoin.Instance.Regtest, new IPEndPoint(IPAddress.Loopback, 18444));
                    }
                    else
                    {
                        node = Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));
                    }
                    Nodes.ConnectedNodes.Add(node);

                    RegTestMemPoolServingNode = Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));

                    RegTestMemPoolServingNode.Behaviors.Add(new MemPoolBehavior(MemPoolService));
                }
                catch (SocketException ex)
                {
                    Logger.LogError(ex, nameof(Global));
                }
            }
            else
            {
                Nodes = new NodesGroup(Network, connectionParameters, requirements: Constants.NodeRequirements);

                RegTestMemPoolServingNode = null;
            }

            // todopw: Error UpdateChecker just chc - No connection could be made because the target machine actively refused it 127.0.0.1:37127
            Synchronizer = new WasabiSynchronizer(Network, IndexFilePath, Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());

            UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            if (!(RegTestMemPoolServingNode is null))
            {
                RegTestMemPoolServingNode.VersionHandshake();
                Logger.LogInfo("Start connecting to mempool serving regtest node...");
            }

            var requestInterval = TimeSpan.FromSeconds(30);

            if (Network == Network.RegTest || Network.Name == "chaincoin-reg")              // todopw: extend
            {
                requestInterval = TimeSpan.FromSeconds(5);
            }
            Synchronizer.Start(requestInterval, TimeSpan.FromMinutes(5), 1000);
            Logger.LogInfo("Start synchronizing filters...");
        }
Exemple #12
0
        public static void Initialize(Config config)
        {
            WalletService  = null;
            ChaumianClient = null;

            Config = Guard.NotNull(nameof(config), config);

            string blindingPubKeyFile = Path.Combine(DataDir, $"BlindingPubKey{Network}.json");

            if (File.Exists(blindingPubKeyFile))
            {
                string blindingPubKeyJson = "";
                blindingPubKeyJson = File.ReadAllText(blindingPubKeyFile);
                BlindingPubKey     = BlindingRsaPubKey.CreateFromJson(blindingPubKeyJson);
            }
            else
            {
                if (Network == Network.Main)
                {
                    BlindingPubKey = new BlindingRsaPubKey(new BigInteger("16421152619146079007287475569112871971988560541093277613438316709041030720662622782033859387192362542996510605015506477964793447620206674394713753349543444988246276357919473682408472170521463339860947351211455351029147665615454176157348164935212551240942809518428851690991984017733153078846480521091423447691527000770982623947706172997649440619968085147635776736938871139581019988225202983052255684151711253254086264386774936200194229277914886876824852466823571396538091430866082004097086602287294474304344865162932126041736158327600847754258634325228417149098062181558798532036659383679712667027126535424484318399849"), new BigInteger("65537"));
                }
                else
                {
                    BlindingPubKey = new BlindingRsaPubKey(new BigInteger("19473594448380717274202325076521698699373476167359253614775896809797414915031772455344343455269320444157176520539924715307970060890094127521516100754263825112231545354422893125394219335109864514907655429499954825469485252969706079992227103439161156022844535556626007277544637236136559868400854764962522288139619969507311597914908752685925185380735570791798593290356424409633800092336087046668579610273133131498947353719917407262847070395909920415822288443947309434039008038907229064999576278651443575362470457496666718250346530518268694562965606704838796709743032825816642704620776596590683042135764246115456630753521"), new BigInteger("65537"));
                }
                Directory.CreateDirectory(DataDir);
                File.WriteAllText(blindingPubKeyFile, BlindingPubKey.ToJson());
            }

            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");

            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            AddressManager = null;
            try
            {
                AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);
                Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
            }
            catch (DirectoryNotFoundException ex)
            {
                Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                Logger.LogTrace <AddressManager>(ex);
                AddressManager = new AddressManager();
            }
            catch (FileNotFoundException ex)
            {
                Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                Logger.LogTrace <AddressManager>(ex);
                AddressManager = new AddressManager();
            }

            connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));
            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            Nodes = new NodesGroup(Network, connectionParameters,
                                   new NodeRequirement
            {
                RequiredServices = NodeServices.Network,
                MinVersion       = Constants.ProtocolVersion_WITNESS_VERSION
            });

            var indexFilePath = Path.Combine(DataDir, $"Index{Network}.dat");

            IndexDownloader = new IndexDownloader(Network, indexFilePath, Config.GetCurrentBackendUri());

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            IndexDownloader.Synchronize(requestInterval: TimeSpan.FromSeconds(21));
            Logger.LogInfo("Start synchronizing filters...");
        }
Exemple #13
0
        public static void Initialize(Config config)
        {
            WalletService  = null;
            ChaumianClient = null;

            Config = Guard.NotNull(nameof(config), config);

            var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");

            AddressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{Network}.dat");
            var blocksFolderPath     = Path.Combine(DataDir, $"Blocks{Network}");
            var connectionParameters = new NodeConnectionParameters();

            AddressManager = null;

            if (Network == Network.RegTest)
            {
                AddressManager = new AddressManager();
                Logger.LogInfo <AddressManager>($"Fake {nameof(AddressManager)} is initialized on the RegTest.");
            }
            else
            {
                try
                {
                    AddressManager = AddressManager.LoadPeerFile(AddressManagerFilePath);
                    Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{AddressManagerFilePath}`.");
                }
                catch (DirectoryNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
                catch (FileNotFoundException ex)
                {
                    Logger.LogInfo <AddressManager>($"{nameof(AddressManager)} did not exist at `{AddressManagerFilePath}`. Initializing new one.");
                    Logger.LogTrace <AddressManager>(ex);
                    AddressManager = new AddressManager();
                }
            }

            connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));
            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            if (Network == Network.RegTest)
            {
                Nodes = new NodesGroup(Network,
                                       requirements: new NodeRequirement
                {
                    RequiredServices = NodeServices.Network,
                    MinVersion       = Constants.ProtocolVersion_WITNESS_VERSION
                });
                Nodes.ConnectedNodes.Add(Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444)));

                RegTestMemPoolServingNode = Node.Connect(Network.RegTest, new IPEndPoint(IPAddress.Loopback, 18444));
                RegTestMemPoolServingNode.Behaviors.Add(new MemPoolBehavior(MemPoolService));
            }
            else
            {
                Nodes = new NodesGroup(Network, connectionParameters,
                                       new NodeRequirement
                {
                    RequiredServices = NodeServices.Network,
                    MinVersion       = Constants.ProtocolVersion_WITNESS_VERSION
                });

                RegTestMemPoolServingNode = null;
            }

            var indexFilePath = Path.Combine(DataDir, $"Index{Network}.dat");

            IndexDownloader = new IndexDownloader(Network, indexFilePath, Config.GetCurrentBackendUri());

            UpdateChecker = new UpdateChecker(IndexDownloader.WasabiClient);

            Nodes.Connect();
            Logger.LogInfo("Start connecting to nodes...");

            if (RegTestMemPoolServingNode != null)
            {
                RegTestMemPoolServingNode.VersionHandshake();
                Logger.LogInfo("Start connecting to mempool serving regtest node...");
            }

            IndexDownloader.Synchronize(requestInterval: TimeSpan.FromSeconds(21));
            Logger.LogInfo("Start synchronizing filters...");
        }
Exemple #14
0
        public Global(string dataDir, Config config, UiConfig uiConfig, WalletManager walletManager)
        {
            using (BenchmarkLogger.Measure())
            {
                DataDir     = dataDir;
                Config      = config;
                UiConfig    = uiConfig;
                TorSettings = new TorSettings(DataDir, distributionFolderPath: EnvironmentHelpers.GetFullBaseDirectory(), Config.TerminateTorOnExit, Environment.ProcessId);

                HostedServices = new HostedServices();
                WalletManager  = walletManager;

                WalletManager.OnDequeue += WalletManager_OnDequeue;
                WalletManager.WalletRelevantTransactionProcessed += WalletManager_WalletRelevantTransactionProcessed;

                var networkWorkFolderPath = Path.Combine(DataDir, "BitcoinStore", Network.ToString());
                var transactionStore      = new AllTransactionStore(networkWorkFolderPath, Network);
                var indexStore            = new IndexStore(Path.Combine(networkWorkFolderPath, "IndexStore"), Network, new SmartHeaderChain());
                var mempoolService        = new MempoolService();
                var blocks = new FileSystemBlockRepository(Path.Combine(networkWorkFolderPath, "Blocks"), Network);

                BitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);

                if (Config.UseTor)
                {
                    BackendHttpClientFactory  = new HttpClientFactory(TorSettings.SocksEndpoint, backendUriGetter: () => Config.GetCurrentBackendUri());
                    ExternalHttpClientFactory = new HttpClientFactory(TorSettings.SocksEndpoint, backendUriGetter: null);
                }
                else
                {
                    BackendHttpClientFactory  = new HttpClientFactory(torEndPoint: null, backendUriGetter: () => Config.GetFallbackBackendUri());
                    ExternalHttpClientFactory = new HttpClientFactory(torEndPoint: null, backendUriGetter: null);
                }

                Synchronizer           = new WasabiSynchronizer(BitcoinStore, BackendHttpClientFactory);
                LegalChecker           = new(DataDir);
                TransactionBroadcaster = new TransactionBroadcaster(Network, BitcoinStore, BackendHttpClientFactory, WalletManager);
            }
        }