Exemplo n.º 1
0
        private async Task <DownloadBlocksResult> DownloadBlocksAsync(Chain chain, BlockDownloadJobInfo jobInfo)
        {
            var downloadResult = new DownloadBlocksResult();

            if (jobInfo.CurrentTargetBlockHeight > 0)
            {
                if (jobInfo.CurrentTargetBlockHeight <= chain.BestChainHeight || await BlockIsInBestChain(chain,
                                                                                                          jobInfo.CurrentTargetBlockHash, jobInfo.CurrentTargetBlockHeight))
                {
                    downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                    {
                        PreviousBlockHash      = jobInfo.CurrentTargetBlockHash,
                        PreviousBlockHeight    = jobInfo.CurrentTargetBlockHeight,
                        BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                        SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                        MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount
                    });
                }
            }
            else
            {
                // Download blocks from longest chain
                downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                {
                    PreviousBlockHash      = chain.LongestChainHash,
                    PreviousBlockHeight    = chain.LongestChainHeight,
                    BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                    SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                    MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount
                });

                // Download blocks from best chain
                if (downloadResult.DownloadBlockCount == 0)
                {
                    downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                    {
                        PreviousBlockHash      = chain.BestChainHash,
                        PreviousBlockHeight    = chain.BestChainHeight,
                        BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                        SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                        MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount
                    });
                }
                // Download blocks from LIB
                if (downloadResult.DownloadBlockCount == 0)
                {
                    Logger.LogDebug($"Resynchronize from lib, lib height: {chain.LastIrreversibleBlockHeight}.");
                    downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                    {
                        PreviousBlockHash      = chain.LastIrreversibleBlockHash,
                        PreviousBlockHeight    = chain.LastIrreversibleBlockHeight,
                        BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                        SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                        MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount
                    });
                }
            }

            return(downloadResult);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Download and attach blocks
        /// UseSuggestedPeer == true: Download blocks from suggested peer directly;
        /// Target download height > peer lib height, download blocks from suggested peer;
        /// Target download height <= peer lib height, select a random peer to download.
        /// </summary>
        /// <param name="downloadBlockDto"></param>
        /// <returns></returns>
        public async Task <DownloadBlocksResult> DownloadBlocksAsync(DownloadBlockDto downloadBlockDto)
        {
            var downloadResult = new DownloadBlocksResult();
            var peerPubkey     = downloadBlockDto.SuggestedPeerPubkey;

            try
            {
                if (UseSuggestedPeer(downloadBlockDto))
                {
                    downloadResult = await DownloadBlocksAsync(peerPubkey, downloadBlockDto);
                }
                else
                {
                    // If cannot get the blocks, there should be network problems or bad peer,
                    // because we have selected peer with lib height greater than or equal to the target height.
                    // 1. network problems, need to retry from other peer.
                    // 2. not network problems, this peer or the last peer is bad peer, we need to remove it.
                    var downloadTargetHeight =
                        downloadBlockDto.PreviousBlockHeight + downloadBlockDto.MaxBlockDownloadCount;
                    var exceptedPeers = new List <string> {
                        _blockSyncStateProvider.LastRequestPeerPubkey
                    };
                    var retryTimes = 2;

                    while (true)
                    {
                        peerPubkey = GetRandomPeerPubkey(downloadBlockDto.SuggestedPeerPubkey, downloadTargetHeight,
                                                         exceptedPeers);

                        downloadResult = await DownloadBlocksAsync(peerPubkey, downloadBlockDto);

                        if (downloadResult.Success || retryTimes <= 0)
                        {
                            break;
                        }

                        exceptedPeers.Add(peerPubkey);
                        retryTimes--;
                    }

                    if (downloadResult.Success && downloadResult.DownloadBlockCount == 0)
                    {
                        await CheckBadPeerAsync(peerPubkey, downloadBlockDto.PreviousBlockHash,
                                                downloadBlockDto.PreviousBlockHeight);
                    }
                }
            }
            catch (BlockDownloadException e)
            {
                await LocalEventBus.PublishAsync(new BadPeerFoundEventData
                {
                    BlockHash   = e.BlockHash,
                    BlockHeight = e.BlockHeight,
                    PeerPubkey  = e.PeerPubkey
                });
            }

            return(downloadResult);
        }
Exemplo n.º 3
0
        private async Task <DownloadBlocksResult> DownloadBlocksAsync(Chain chain, BlockDownloadJobInfo jobInfo)
        {
            var downloadResult = new DownloadBlocksResult();

            if (jobInfo.CurrentTargetBlockHeight == 0)
            {
                // Download blocks from longest chain
                downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                {
                    PreviousBlockHash      = chain.LongestChainHash,
                    PreviousBlockHeight    = chain.LongestChainHeight,
                    BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                    SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                    MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount,
                    UseSuggestedPeer       = true
                });

                // Download blocks from best chain
                if (downloadResult.Success && downloadResult.DownloadBlockCount == 0)
                {
                    downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                    {
                        PreviousBlockHash      = chain.BestChainHash,
                        PreviousBlockHeight    = chain.BestChainHeight,
                        BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                        SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                        MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount,
                        UseSuggestedPeer       = true
                    });
                }

                // Download blocks from LIB
                if (downloadResult.Success && downloadResult.DownloadBlockCount == 0)
                {
                    Logger.LogDebug($"Resynchronize from lib, lib height: {chain.LastIrreversibleBlockHeight}.");
                    downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                    {
                        PreviousBlockHash      = chain.LastIrreversibleBlockHash,
                        PreviousBlockHeight    = chain.LastIrreversibleBlockHeight,
                        BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                        SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                        MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount,
                        UseSuggestedPeer       = true
                    });
                }
            }
            // If last target block didn't become the longest chain, stop this job.
            else if (jobInfo.CurrentTargetBlockHeight <= chain.LongestChainHeight + 8)
            {
                downloadResult = await _blockDownloadService.DownloadBlocksAsync(new DownloadBlockDto
                {
                    PreviousBlockHash      = jobInfo.CurrentTargetBlockHash,
                    PreviousBlockHeight    = jobInfo.CurrentTargetBlockHeight,
                    BatchRequestBlockCount = jobInfo.BatchRequestBlockCount,
                    SuggestedPeerPubkey    = jobInfo.SuggestedPeerPubkey,
                    MaxBlockDownloadCount  = _blockSyncOptions.MaxBlockDownloadCount,
                    UseSuggestedPeer       = false
                });
            }

            return(downloadResult);
        }