Exemplo n.º 1
0
        public static async Task InitializeNoWalletAsync()
        {
            WalletService  = null;
            ChaumianClient = null;
            AddressManager = null;
            TorManager     = null;

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

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

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

            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();
                });
            };

            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)
            {
                TorManager = new TorProcessManager(Config.GetTorSocks5EndPoint(), TorLogsFile);
            }
            else
            {
                TorManager = TorProcessManager.Mock();
            }
            TorManager.Start(false, DataDir);

            try
            {
                await HwiProcessManager.EnsureHwiInstalledAsync(DataDir, Network);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, nameof(Global));
            }

            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 = 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);
            MemPoolService = new MemPoolService();
            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(MemPoolService));

            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;
            }

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

            UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);

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

            if (RegTestMemPoolServingNode != 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);
            }

            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...");
        }
Exemplo n.º 2
0
        public async Task TestServicesAsync(string networkString)
        {
            var network          = Network.GetNetwork(networkString);
            var blocksToDownload = new HashSet <uint256>();

            if (network == Network.Main)
            {
                blocksToDownload.Add(new uint256("00000000000000000037c2de35bd85f3e57f14ddd741ce6cee5b28e51473d5d0"));
                blocksToDownload.Add(new uint256("000000000000000000115315a43cb0cdfc4ea54a0e92bed127f4e395e718d8f9"));
                blocksToDownload.Add(new uint256("00000000000000000011b5b042ad0522b69aae36f7de796f563c895714bbd629"));
            }
            else if (network == Network.TestNet)
            {
                blocksToDownload.Add(new uint256("0000000097a664c4084b49faa6fd4417055cb8e5aac480abc31ddc57a8208524"));
                blocksToDownload.Add(new uint256("000000009ed5b82259ecd2aa4cd1f119db8da7a70e7ea78d9c9f603e01f93bcc"));
                blocksToDownload.Add(new uint256("00000000e6da8c2da304e9f5ad99c079df2c3803b49efded3061ecaf206ddc66"));
            }
            else
            {
                throw new NotSupportedException(network.ToString());
            }

            var            addressManagerFolderPath = Path.Combine(SharedFixture.DataDir, "AddressManager");
            var            addressManagerFilePath   = Path.Combine(addressManagerFolderPath, $"AddressManager{network}.dat");
            var            blocksFolderPath         = Path.Combine(SharedFixture.DataDir, "Blocks", network.ToString());
            var            connectionParameters     = new NodeConnectionParameters();
            AddressManager 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));
            var memPoolService = new MemPoolService();

            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(memPoolService));

            var nodes = new NodesGroup(network, connectionParameters,
                                       new NodeRequirement
            {
                RequiredServices = NodeServices.Network,
                MinVersion       = Helpers.Constants.ProtocolVersion_WITNESS_VERSION
            });

            KeyManager    keyManager    = KeyManager.CreateNew(out _, "password");
            WalletService walletService = new WalletService(
                keyManager,
                new IndexDownloader(network, Path.Combine(SharedFixture.DataDir, nameof(TestServicesAsync), "IndexDownloader.txt"), new Uri("http://localhost:12345")),
                new CcjClient(network, new BlindingRsaKey().PubKey, keyManager, new Uri("http://localhost:12345")),
                memPoolService,
                nodes,
                SharedFixture.DataDir);

            Assert.True(Directory.Exists(blocksFolderPath));

            try
            {
                nodes.ConnectedNodes.Added         += ConnectedNodes_Added;
                nodes.ConnectedNodes.Removed       += ConnectedNodes_Removed;
                memPoolService.TransactionReceived += MemPoolService_TransactionReceived;

                nodes.Connect();
                // Using the interlocked, not because it makes sense in this context, but to
                // set an example that these values are often concurrency sensitive
                var times = 0;
                while (Interlocked.Read(ref _nodeCount) < 3)
                {
                    if (times > 4200)                     // 7 minutes
                    {
                        throw new TimeoutException($"Connection test timed out.");
                    }
                    await Task.Delay(100);

                    times++;
                }

                times = 0;
                while (Interlocked.Read(ref _mempoolTransactionCount) < 3)
                {
                    if (times > 3000)                     // 3 minutes
                    {
                        throw new TimeoutException($"{nameof(MemPoolService)} test timed out.");
                    }
                    await Task.Delay(100);

                    times++;
                }

                foreach (var hash in blocksToDownload)
                {
                    using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3)))
                    {
                        var block = await walletService.GetOrDownloadBlockAsync(hash, cts.Token);

                        Assert.True(File.Exists(Path.Combine(blocksFolderPath, hash.ToString())));
                        Logger.LogInfo <P2pTests>($"Full block is downloaded: {hash}.");
                    }
                }
            }
            finally
            {
                nodes.ConnectedNodes.Added         -= ConnectedNodes_Added;
                nodes.ConnectedNodes.Removed       -= ConnectedNodes_Removed;
                memPoolService.TransactionReceived -= MemPoolService_TransactionReceived;

                // So next test will download the block.
                foreach (var hash in blocksToDownload)
                {
                    await walletService?.DeleteBlockAsync(hash);
                }
                walletService?.Dispose();

                if (Directory.Exists(blocksFolderPath))
                {
                    Directory.Delete(blocksFolderPath, recursive: true);
                }

                IoHelpers.EnsureContainingDirectoryExists(addressManagerFilePath);
                addressManager?.SavePeerFile(addressManagerFilePath, network);
                Logger.LogInfo <P2pTests>($"Saved {nameof(AddressManager)} to `{addressManagerFilePath}`.");
                nodes?.Dispose();
            }
        }
Exemplo n.º 3
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);

            addressManagerBehavior.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...");
        }
Exemplo n.º 4
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);

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

            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;
            }

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

            UpdateChecker = new UpdateChecker(IndexDownloader.WasabiClient);

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

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

            IndexDownloader.Synchronize(requestInterval: TimeSpan.FromSeconds(21));
            Logger.LogInfo("Start synchronizing filters...");
        }
Exemplo n.º 5
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...");
        }
Exemplo n.º 6
0
        public static void InitializeNoWallet()
        {
            WalletService  = null;
            ChaumianClient = null;

            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;
            }

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

            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...");
        }
Exemplo n.º 7
0
        public 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 {
                UserAgent = "/Satoshi:0.18.0/"
            };

            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();
                });
                await DisposeAsync();

                Logger.LogInfo($"Wasabi stopped gracefully.", Logger.InstanceGuid.ToString());
            };

            #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

            Initialized = true;
        }
Exemplo n.º 8
0
        public async Task TestServicesAsync(string networkString)
        {
            var network          = Network.GetNetwork(networkString);
            var blocksToDownload = new HashSet <uint256>();

            if (network == Network.Main)
            {
                blocksToDownload.Add(new uint256("00000000000000000037c2de35bd85f3e57f14ddd741ce6cee5b28e51473d5d0"));
                blocksToDownload.Add(new uint256("000000000000000000115315a43cb0cdfc4ea54a0e92bed127f4e395e718d8f9"));
                blocksToDownload.Add(new uint256("00000000000000000011b5b042ad0522b69aae36f7de796f563c895714bbd629"));
            }
            else if (network == Network.TestNet)
            {
                blocksToDownload.Add(new uint256("0000000097a664c4084b49faa6fd4417055cb8e5aac480abc31ddc57a8208524"));
                blocksToDownload.Add(new uint256("000000009ed5b82259ecd2aa4cd1f119db8da7a70e7ea78d9c9f603e01f93bcc"));
                blocksToDownload.Add(new uint256("00000000e6da8c2da304e9f5ad99c079df2c3803b49efded3061ecaf206ddc66"));
            }
            else
            {
                throw new NotSupportedException(network.ToString());
            }

            var manager    = KeyManager.CreateNew(out Mnemonic mnemonic, "password");
            var dataFolder = Path.Combine(SharedFixture.DataDir, nameof(TestServicesAsync));

            Directory.CreateDirectory(SharedFixture.DataDir);

            var             addressManagerFilePath = Path.Combine(SharedFixture.DataDir, $"AddressManager{network}.dat");
            var             blocksFolderPath       = Path.Combine(SharedFixture.DataDir, $"Blocks{network}");
            var             connectionParameters   = new NodeConnectionParameters();
            AddressManager  addressManager         = null;
            BlockDownloader downloader             = null;

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

                connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager));
                var memPoolService = new MemPoolService();
                connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(memPoolService));

                using (var nodes = new NodesGroup(network, connectionParameters,
                                                  new NodeRequirement
                {
                    RequiredServices = NodeServices.Network,
                    MinVersion = ProtocolVersion.WITNESS_VERSION
                }))
                {
                    downloader = new BlockDownloader(nodes, blocksFolderPath);
                    Assert.True(Directory.Exists(blocksFolderPath));
                    downloader.Start();
                    foreach (var hash in blocksToDownload)
                    {
                        downloader.QueToDownload(hash);
                    }
                    var wallet = new WalletService(dataFolder, network, manager, nodes, memPoolService);
                    try
                    {
                        nodes.ConnectedNodes.Added         += ConnectedNodes_Added;
                        nodes.ConnectedNodes.Removed       += ConnectedNodes_Removed;
                        memPoolService.TransactionReceived += MemPoolService_TransactionReceived;

                        nodes.Connect();
                        // Using the interlocked, not because it makes sense in this context, but to
                        // set an example that these values are often concurrency sensitive
                        var times = 0;
                        while (Interlocked.Read(ref _nodeCount) < 3)
                        {
                            if (times > 4200)                             // 7 minutes
                            {
                                throw new TimeoutException($"Connection test timed out.");
                            }
                            await Task.Delay(100);

                            times++;
                        }

                        times = 0;
                        while (Interlocked.Read(ref _mempoolTransactionCount) < 3)
                        {
                            if (times > 3000)                             // 3 minutes
                            {
                                throw new TimeoutException($"{nameof(MemPoolService)} test timed out.");
                            }
                            await Task.Delay(100);

                            times++;
                        }

                        foreach (var hash in blocksToDownload)
                        {
                            times = 0;
                            while (downloader.GetBlock(hash) == null)
                            {
                                if (times > 1800)                                 // 3 minutes
                                {
                                    throw new TimeoutException($"{nameof(BlockDownloader)} test timed out.");
                                }
                                await Task.Delay(100);

                                times++;
                            }
                            Assert.True(File.Exists(Path.Combine(blocksFolderPath, hash.ToString())));
                            Logger.LogInfo <WalletTests>($"Full block is downloaded: {hash}.");
                        }
                    }
                    finally
                    {
                        nodes.ConnectedNodes.Added         -= ConnectedNodes_Added;
                        nodes.ConnectedNodes.Removed       -= ConnectedNodes_Removed;
                        memPoolService.TransactionReceived -= MemPoolService_TransactionReceived;
                    }
                }
            }
            finally
            {
                downloader?.Stop();

                // So next test will download the block.
                foreach (var hash in blocksToDownload)
                {
                    downloader.TryRemove(hash);
                }
                Directory.Delete(blocksFolderPath, recursive: true);

                addressManager?.SavePeerFile(addressManagerFilePath, network);
                Logger.LogInfo <WalletTests>($"Saved {nameof(AddressManager)} to `{addressManagerFilePath}`.");
            }
        }
Exemplo n.º 9
0
        public async Task TestServicesAsync(string networkString)
        {
            var network          = Network.GetNetwork(networkString);
            var blocksToDownload = new HashSet <uint256>();

            if (network == Network.Main)
            {
                blocksToDownload.Add(new uint256("00000000000000000037c2de35bd85f3e57f14ddd741ce6cee5b28e51473d5d0"));
                blocksToDownload.Add(new uint256("000000000000000000115315a43cb0cdfc4ea54a0e92bed127f4e395e718d8f9"));
                blocksToDownload.Add(new uint256("00000000000000000011b5b042ad0522b69aae36f7de796f563c895714bbd629"));
            }
            else if (network == Network.TestNet)
            {
                blocksToDownload.Add(new uint256("0000000097a664c4084b49faa6fd4417055cb8e5aac480abc31ddc57a8208524"));
                blocksToDownload.Add(new uint256("000000009ed5b82259ecd2aa4cd1f119db8da7a70e7ea78d9c9f603e01f93bcc"));
                blocksToDownload.Add(new uint256("00000000e6da8c2da304e9f5ad99c079df2c3803b49efded3061ecaf206ddc66"));
            }
            else
            {
                throw new NotSupportedException(network.ToString());
            }

            var            addressManagerFolderPath = Path.Combine(Global.Instance.DataDir, "AddressManager");
            var            addressManagerFilePath   = Path.Combine(addressManagerFolderPath, $"AddressManager{network}.dat");
            var            blocksFolderPath         = Path.Combine(Global.Instance.DataDir, "Blocks", network.ToString());
            var            connectionParameters     = new NodeConnectionParameters();
            AddressManager addressManager           = null;

            try
            {
                addressManager = await NBitcoinHelpers.LoadAddressManagerFromPeerFileAsync(addressManagerFilePath);

                Logger.LogInfo <AddressManager>($"Loaded {nameof(AddressManager)} from `{addressManagerFilePath}`.");
            }
            catch (DirectoryNotFoundException)
            {
                addressManager = new AddressManager();
            }
            catch (FileNotFoundException)
            {
                addressManager = new AddressManager();
            }
            catch (OverflowException)
            {
                File.Delete(addressManagerFilePath);
                addressManager = new AddressManager();
            }
            catch (FormatException)
            {
                File.Delete(addressManagerFilePath);
                addressManager = new AddressManager();
            }

            connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager));
            var memPoolService = new MemPoolService();

            connectionParameters.TemplateBehaviors.Add(new MemPoolBehavior(memPoolService));

            var nodes = new NodesGroup(network, connectionParameters, requirements: Constants.NodeRequirements);

            BitcoinStore bitcoinStore = new BitcoinStore();
            await bitcoinStore.InitializeAsync(Path.Combine(Global.Instance.DataDir, nameof(TestServicesAsync)), network);

            KeyManager         keyManager    = KeyManager.CreateNew(out _, "password");
            WasabiSynchronizer syncer        = new WasabiSynchronizer(network, bitcoinStore, new Uri("http://localhost:12345"), Global.Instance.TorSocks5Endpoint);
            WalletService      walletService = new WalletService(
                bitcoinStore,
                keyManager,
                syncer,
                new CcjClient(syncer, network, keyManager, new Uri("http://localhost:12345"), Global.Instance.TorSocks5Endpoint),
                memPoolService,
                nodes,
                Global.Instance.DataDir,
                new ServiceConfiguration(50, 2, 21, 50, new IPEndPoint(IPAddress.Loopback, network.DefaultPort), Money.Coins(0.0001m)));

            Assert.True(Directory.Exists(blocksFolderPath));

            try
            {
                memPoolService.TransactionReceived += MemPoolService_TransactionReceived;

                nodes.Connect();
                var times = 0;
                while (nodes.ConnectedNodes.Count < 3)
                {
                    if (times > 4200)                     // 7 minutes
                    {
                        throw new TimeoutException($"Connection test timed out.");
                    }
                    await Task.Delay(100);

                    times++;
                }

                times = 0;
                while (Interlocked.Read(ref _mempoolTransactionCount) < 3)
                {
                    if (times > 3000)                     // 3 minutes
                    {
                        throw new TimeoutException($"{nameof(MemPoolService)} test timed out.");
                    }
                    await Task.Delay(100);

                    times++;
                }

                foreach (var hash in blocksToDownload)
                {
                    using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3)))
                    {
                        var block = await walletService.GetOrDownloadBlockAsync(hash, cts.Token);

                        Assert.True(File.Exists(Path.Combine(blocksFolderPath, hash.ToString())));
                        Logger.LogInfo <P2pTests>($"Full block is downloaded: {hash}.");
                    }
                }
            }
            finally
            {
                nodes.ConnectedNodes.Added         -= ConnectedNodes_Added;
                nodes.ConnectedNodes.Removed       -= ConnectedNodes_Removed;
                memPoolService.TransactionReceived -= MemPoolService_TransactionReceived;

                // So next test will download the block.
                foreach (var hash in blocksToDownload)
                {
                    await walletService?.DeleteBlockAsync(hash);
                }
                if (walletService != null)
                {
                    await walletService.StopAsync();
                }

                if (Directory.Exists(blocksFolderPath))
                {
                    Directory.Delete(blocksFolderPath, recursive: true);
                }

                IoHelpers.EnsureContainingDirectoryExists(addressManagerFilePath);
                addressManager?.SavePeerFile(addressManagerFilePath, network);
                Logger.LogInfo <P2pTests>($"Saved {nameof(AddressManager)} to `{addressManagerFilePath}`.");
                nodes?.Dispose();

                await syncer?.StopAsync();
            }
        }