public async Task <int> CountBlocksAsync()
 {
     using (await BlockFolderLock.LockAsync())
     {
         return(Directory.EnumerateFiles(BlocksFolderPath).Count());
     }
 }
        /// <remarks>
        /// Use it at reorgs.
        /// </remarks>
        public async Task DeleteBlockAsync(uint256 hash)
        {
            using (await BlockFolderLock.LockAsync())
            {
                var filePaths = Directory.EnumerateFiles(BlocksFolderPath);
                var fileNames = filePaths.Select(x => Path.GetFileName(x));
                var hashes    = fileNames.Select(x => new uint256(x));

                if (hashes.Contains(hash))
                {
                    File.Delete(Path.Combine(BlocksFolderPath, hash.ToString()));
                }
            }
        }
        /// <exception cref="OperationCanceledException"></exception>
        public async Task <Block> GetOrDownloadBlockAsync(uint256 hash, CancellationToken cancel)
        {
            // Try get the block
            using (await BlockFolderLock.LockAsync())
            {
                foreach (var filePath in Directory.EnumerateFiles(BlocksFolderPath))
                {
                    var fileName = Path.GetFileName(filePath);
                    if (hash == new uint256(fileName))
                    {
                        var blockBytes = await File.ReadAllBytesAsync(filePath);

                        return(Block.Load(blockBytes, IndexDownloader.Network));
                    }
                }
            }
            cancel.ThrowIfCancellationRequested();

            // Download the block
            Block block = null;

            using (await BlockDownloadLock.LockAsync())
            {
                while (true)
                {
                    cancel.ThrowIfCancellationRequested();
                    try
                    {
                        // If no connection, wait then continue.
                        while (Nodes.ConnectedNodes.Count == 0)
                        {
                            await Task.Delay(100);
                        }

                        Node node = Nodes.ConnectedNodes.RandomElement();
                        if (node == default(Node))
                        {
                            await Task.Delay(100);

                            continue;
                        }

                        if (!node.IsConnected && !(IndexDownloader.Network != Network.RegTest))
                        {
                            await Task.Delay(100);

                            continue;
                        }

                        try
                        {
                            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(32)))                             // ADSL	512 kbit/s	00:00:32
                            {
                                block = node.GetBlocks(new uint256[] { hash }, cts.Token)?.Single();
                            }

                            if (block == null)
                            {
                                Logger.LogInfo <WalletService>($"Disconnected node, because couldn't parse received block.");
                                node.DisconnectAsync("Couldn't parse block.");
                                continue;
                            }

                            if (!block.Check())
                            {
                                Logger.LogInfo <WalletService>($"Disconnected node, because block invalid block received.");
                                node.DisconnectAsync("Invalid block received.");
                                continue;
                            }
                        }
                        catch (TimeoutException)
                        {
                            Logger.LogInfo <WalletService>($"Disconnected node, because block download took too long.");
                            node.DisconnectAsync("Block download took too long.");
                            continue;
                        }
                        catch (OperationCanceledException)
                        {
                            Logger.LogInfo <WalletService>($"Disconnected node, because block download took too long.");
                            node.DisconnectAsync("Block download took too long.");
                            continue;
                        }
                        catch (Exception ex)
                        {
                            Logger.LogDebug <WalletService>(ex);
                            Logger.LogInfo <WalletService>($"Disconnected node, because block download failed: {ex.Message}");
                            node.DisconnectAsync("Block download failed.");
                            continue;
                        }

                        break;                         // If got this far break, then we have the block, it's valid. Break.
                    }
                    catch (Exception ex)
                    {
                        Logger.LogDebug <WalletService>(ex);
                    }
                }
            }
            // Save the block
            using (await BlockFolderLock.LockAsync())
            {
                var path = Path.Combine(BlocksFolderPath, hash.ToString());
                await File.WriteAllBytesAsync(path, block.ToBytes());
            }

            return(block);
        }