示例#1
0
        /// <returns>null if don't have, ques it if not qued</returns>
        public Block GetBlock(uint256 hash)
        {
            using (BlocksFolderLock.Lock())
            {
                foreach (var filePath in Directory.EnumerateFiles(BlocksFolderPath))
                {
                    var fileName = Path.GetFileName(filePath);
                    if (hash == new uint256(fileName))
                    {
                        var blockBytes = File.ReadAllBytes(filePath);
                        var block      = new Block(blockBytes);
                        return(block);
                    }
                }
            }

            QueToDownload(hash);
            return(default);
示例#2
0
        public void QueToDownload(uint256 hash)
        {
            using (BlocksFolderLock.Lock())
                using (BlocksToDownloadLock.Lock())
                {
                    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))
                    {
                        if (!BlocksToDownload.Contains(hash))
                        {
                            BlocksToDownload.Add(hash);
                        }
                    }
                }
        }
示例#3
0
        /// <remarks>
        /// Use it at reorgs.
        /// </remarks>
        public void TryRemove(uint256 hash)
        {
            using (BlocksFolderLock.Lock())
                using (BlocksToDownloadLock.Lock())
                {
                    if (BlocksToDownload.Contains(hash))
                    {
                        BlocksToDownload.Remove(hash);
                    }

                    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()));
                    }
                }
        }
示例#4
0
        public void Start()
        {
            Interlocked.Exchange(ref _running, 1);

            Task.Run(async() =>
            {
                while (IsRunning)
                {
                    try
                    {
                        // If stop was requested return.
                        if (IsRunning == false)
                        {
                            return;
                        }

                        // If no connection, wait then continue.
                        if (Nodes.ConnectedNodes.Count == 0)
                        {
                            await Task.Delay(10);
                            continue;
                        }
                        if (IsRunning == false)
                        {
                            return;
                        }

                        uint256 hash = null;
                        // If nothing to download, wait then continue.
                        using (BlocksToDownloadLock.Lock())
                        {
                            if (BlocksToDownload.Count == 0)
                            {
                                await Task.Delay(100);
                                continue;
                            }
                            else
                            {
                                hash = BlocksToDownload.First();
                            }
                        }
                        if (IsRunning == false)
                        {
                            return;
                        }

                        Node node = Nodes.ConnectedNodes.RandomElement();
                        if (node == default(Node))
                        {
                            await Task.Delay(10);
                            continue;
                        }
                        if (!node.IsConnected)
                        {
                            await Task.Delay(10);
                            continue;
                        }

                        Block block = null;

                        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 <BlockDownloader>($"Disconnected node, because couldn't parse received block.");
                                node.DisconnectAsync("Couldn't parse block.");
                                continue;
                            }

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

                        using (BlocksFolderLock.Lock())
                            using (BlocksToDownloadLock.Lock())
                            {
                                BlocksToDownload.Remove(hash);
                                var path = Path.Combine(BlocksFolderPath, hash.ToString());
                                await File.WriteAllBytesAsync(path, block.ToBytes());
                            }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogDebug <BlockDownloader>(ex);
                    }
                }
            }
                     );
        }