コード例 #1
0
        public async Task <PagedResult> GetBlocksAsync(BlocksRequest request)
        {
            var num = request.Num;

            if (!num.HasValue || num.Value == 0)
            {
                num = (await m_EosApi.GetInfo()).head_block_num;
            }
            var  blocks = new List <Block>();
            long start  = (long)num - (long)request.Skip - (long)request.Limit;
            long end    = start + (long)request.Limit;

            if (start < 0)
            {
                start = 0;
            }
            for (var i = end; i > start; i--)
            {
                var block = await m_EosApi.GetBlock(new GetBlockRequest()
                {
                    block_num_or_id = i.ToString()
                });

                blocks.Add(new Block
                {
                    Id       = block.id,
                    Time     = block.timestamp,
                    Num      = block.block_num,
                    Producer = block.producer,
                    Txns     = block.transactions.Count
                });
            }
            return(PagedResult.Create(blocks, (int)num.Value));
        }
コード例 #2
0
ファイル: GrpcServerService.cs プロジェクト: wymoon2690/AElf
        public override async Task <BlockList> RequestBlocks(BlocksRequest request, ServerCallContext context)
        {
            if (request == null || request.PreviousBlockHash == null || _syncStateService.SyncState != SyncState.Finished)
            {
                return(new BlockList());
            }

            Logger.LogDebug($"Peer {context.GetPeerInfo()} requested {request.Count} blocks from {request.PreviousBlockHash}.");

            var blockList = new BlockList();

            var blocks = await _blockchainService.GetBlocksWithTransactions(request.PreviousBlockHash, request.Count);

            if (blocks == null)
            {
                return(blockList);
            }

            blockList.Blocks.AddRange(blocks);

            if (blockList.Blocks.Count != request.Count)
            {
                Logger.LogTrace($"Replied with {blockList.Blocks.Count} blocks for request {request}");
            }

            if (NetworkOptions.CompressBlocksOnRequest)
            {
                var headers = new Metadata {
                    new Metadata.Entry(GrpcConstants.GrpcRequestCompressKey, GrpcConstants.GrpcGzipConst)
                };
                await context.WriteResponseHeadersAsync(headers);
            }

            return(blockList);
        }
コード例 #3
0
        public async Task <List <BlockWithTransactions> > GetBlocksAsync(Hash firstHash, int count)
        {
            var blockRequest = new BlocksRequest {
                PreviousBlockHash = firstHash, Count = count
            };
            var blockInfo = $"{{ first: {firstHash}, count: {count} }}";

            GrpcRequest request = new GrpcRequest
            {
                ErrorMessage = $"Get blocks for {blockInfo} failed.",
                MetricName   = nameof(MetricNames.GetBlocks),
                MetricInfo   = $"Get blocks for {blockInfo}"
            };

            Metadata data = new Metadata
            {
                { GrpcConstants.TimeoutMetadataKey, BlocksRequestTimeout.ToString() },
                { GrpcConstants.SessionIdMetadataKey, OutboundSessionId }
            };

            var list = await RequestAsync(() => _client.RequestBlocksAsync(blockRequest, data), request);

            if (list == null)
            {
                return(new List <BlockWithTransactions>());
            }

            return(list.Blocks.ToList());
        }
コード例 #4
0
        /// <summary>
        /// Gets list of blocks asynchronously
        /// </summary>
        /// <param name="req">BlocksRequest</param>
        /// <returns>BlocksResponse with blocks list</returns>
        public async Task <BlocksResponse> GetBlocksAsync(BlocksRequest req)
        {
            _url.Path  = Constants.ApiGetBlocks;
            _url.Query = req.ToQuery();
            var response = await _client.GetJsonAsync <BlocksResponse>(_url.ToString());

            ResetPath();
            return(response);
        }
コード例 #5
0
ファイル: GrpcPeer.cs プロジェクト: woxihuanjia/AElf
        public async Task <List <Block> > GetBlocksAsync(Hash firstHash, int count)
        {
            var blockRequest = new BlocksRequest {
                PreviousBlockHash = firstHash, Count = count
            };

            var list = await RequestAsync(_client, c => c.RequestBlocksAsync(blockRequest),
                                          $"Get blocks for {{ first: {firstHash}, count: {count} }} failed.");

            if (list == null)
            {
                return(new List <Block>());
            }

            return(list.Blocks.ToList());
        }
コード例 #6
0
        public override async Task <BlockList> RequestBlocks(BlocksRequest request, ServerCallContext context)
        {
            if (request == null ||
                request.PreviousBlockHash == null ||
                _syncStateService.SyncState != SyncState.Finished ||
                request.Count == 0 ||
                request.Count > GrpcConstants.MaxSendBlockCountLimit)
            {
                return(new BlockList());
            }

            Logger.LogDebug(
                $"Peer {context.GetPeerInfo()} requested {request.Count} blocks from {request.PreviousBlockHash}.");

            var blockList = new BlockList();

            try
            {
                var blocks =
                    await _blockchainService.GetBlocksWithTransactions(request.PreviousBlockHash, request.Count);

                blockList.Blocks.AddRange(blocks);

                if (NetworkOptions.CompressBlocksOnRequest)
                {
                    var headers = new Metadata
                    {
                        new Metadata.Entry(GrpcConstants.GrpcRequestCompressKey, GrpcConstants.GrpcGzipConst)
                    };
                    await context.WriteResponseHeadersAsync(headers);
                }

                Logger.LogTrace(
                    $"Replied to {context.GetPeerInfo()} with {blockList.Blocks.Count}, request was {request}");
            }
            catch (Exception e)
            {
                Logger.LogError(e, $"Request blocks error - {context.GetPeerInfo()} - request {request}: ");
                throw;
            }

            return(blockList);
        }
コード例 #7
0
        public Task <PagedResult> Blocks([FromQuery] BlocksRequest request)
        {
            var blocks = m_ChainManager.GetBlocksAsync(request);

            return(blocks);
        }
コード例 #8
0
        public override async Task <long> DownloadBlocks(PeerInfo?bestPeer, BlocksRequest blocksRequest,
                                                         CancellationToken cancellation)
        {
            if (_beaconPivot.BeaconPivotExists() == false && _poSSwitcher.HasEverReachedTerminalBlock() == false)
            {
                return(await base.DownloadBlocks(bestPeer, blocksRequest, cancellation));
            }

            if (bestPeer == null)
            {
                string message = $"Not expecting best peer to be null inside the {nameof(BlockDownloader)}";
                if (_logger.IsError)
                {
                    _logger.Error(message);
                }
                throw new ArgumentNullException(message);
            }

            DownloaderOptions options = blocksRequest.Options;
            bool downloadReceipts     = (options & DownloaderOptions.WithReceipts) == DownloaderOptions.WithReceipts;
            bool shouldProcess        = (options & DownloaderOptions.Process) == DownloaderOptions.Process;
            bool shouldMoveToMain     = (options & DownloaderOptions.MoveToMain) == DownloaderOptions.MoveToMain;

            int  blocksSynced  = 0;
            long currentNumber = _blockTree.BestKnownNumber;

            if (_logger.IsTrace)
            {
                _logger.Trace(
                    $"MergeBlockDownloader GetCurrentNumber: currentNumber {currentNumber}, beaconPivotExists: {_beaconPivot.BeaconPivotExists()}, BestSuggestedBody: {_blockTree.BestSuggestedBody?.Number}, BestKnownNumber: {_blockTree.BestKnownNumber}, BestPeer: {bestPeer}, BestKnownBeaconNumber {_blockTree.BestKnownBeaconNumber}");
            }

            bool HasMoreToSync(out BlockHeader[]?headers, out int headersToRequest)
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Continue full sync with {bestPeer} (our best {_blockTree.BestKnownNumber})");
                }

                headersToRequest = Math.Min(_syncBatchSize.Current, bestPeer.MaxHeadersPerRequest());
                if (_logger.IsTrace)
                {
                    _logger.Trace(
                        $"Full sync request {currentNumber}+{headersToRequest} to peer {bestPeer} with {bestPeer.HeadNumber} blocks. Got {currentNumber} and asking for {headersToRequest} more.");
                }

                // Note: blocksRequest.NumberOfLatestBlocksToBeIgnored not accounted for
                headers = _chainLevelHelper.GetNextHeaders(headersToRequest, bestPeer.HeadNumber);
                if (headers == null || headers.Length <= 1)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace("Chain level helper got no headers suggestion");
                    }
                    return(false);
                }

                return(true);
            }

            while (HasMoreToSync(out BlockHeader[]? headers, out int headersToRequest))
            {
                if (cancellation.IsCancellationRequested)
                {
                    return(blocksSynced);                                      // check before every heavy operation
                }
                Block[]? blocks          = null;
                TxReceipt[]?[]? receipts = null;
                if (_logger.IsTrace)
                {
                    _logger.Trace(
                        $"Downloading blocks from peer. CurrentNumber: {currentNumber}, BeaconPivot: {_beaconPivot.PivotNumber}, BestPeer: {bestPeer}, HeaderToRequest: {headersToRequest}");
                }

                BlockDownloadContext context = new(_specProvider, bestPeer, headers !, downloadReceipts, _receiptsRecovery);

                if (cancellation.IsCancellationRequested)
                {
                    return(blocksSynced);                                      // check before every heavy operation
                }
                await RequestBodies(bestPeer, cancellation, context);

                if (downloadReceipts)
                {
                    if (cancellation.IsCancellationRequested)
                    {
                        return(blocksSynced); // check before every heavy operation
                    }
                    await RequestReceipts(bestPeer, cancellation, context);
                }

                _sinceLastTimeout++;
                if (_sinceLastTimeout > 2)
                {
                    _syncBatchSize.Expand();
                }

                blocks   = context.Blocks;
                receipts = context.ReceiptsForBlocks;

                if (!(blocks?.Length > 0))
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace("Break early due to no blocks.");
                    }
                    break;
                }

                for (int blockIndex = 0; blockIndex < blocks.Length; blockIndex++)
                {
                    if (cancellation.IsCancellationRequested)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace("Peer sync cancelled");
                        }
                        break;
                    }

                    Block currentBlock = blocks[blockIndex];
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Received {currentBlock} from {bestPeer}");
                    }

                    if (currentBlock.IsBodyMissing)
                    {
                        throw new EthSyncException($"{bestPeer} didn't send body for block {currentBlock.ToString(Block.Format.Short)}.");
                    }

                    // can move this to block tree now?
                    if (!_blockValidator.ValidateSuggestedBlock(currentBlock))
                    {
                        throw new EthSyncException($"{bestPeer} sent an invalid block {currentBlock.ToString(Block.Format.Short)}.");
                    }

                    if (shouldProcess)
                    {
                        // covering edge case during fastSyncTransition when we're trying to SuggestBlock without the state
                        bool headIsGenesis = _blockTree.Head?.IsGenesis ?? false;
                        bool toBeProcessedIsNotBlockOne = currentBlock.Number > 1;
                        bool isFastSyncTransition       = headIsGenesis && toBeProcessedIsNotBlockOne;
                        if (isFastSyncTransition)
                        {
                            long bestFullState = _syncProgressResolver.FindBestFullState();
                            shouldProcess = currentBlock.Number > bestFullState && bestFullState != 0;
                            if (!shouldProcess)
                            {
                                if (_logger.IsInfo)
                                {
                                    _logger.Info($"Skipping processing during fastSyncTransition, currentBlock: {currentBlock}, bestFullState: {bestFullState}");
                                }
                                downloadReceipts = true;
                            }
                        }
                    }

                    if (downloadReceipts)
                    {
                        TxReceipt[]? contextReceiptsForBlock = receipts ![blockIndex];
                        if (currentBlock.Header.HasBody && contextReceiptsForBlock == null)
                        {
                            throw new EthSyncException($"{bestPeer} didn't send receipts for block {currentBlock.ToString(Block.Format.Short)}.");
                        }
                    }
コード例 #9
0
 /// <summary>
 /// Gets list of block synchronously
 /// </summary>
 /// <param name="req">BlocksRequest</param>
 /// <returns>BlocksResponse with blocks list</returns>
 public BlocksResponse GetBlocks(BlocksRequest req)
 {
     return(GetBlocksAsync(req).GetAwaiter().GetResult());
 }
コード例 #10
0
ファイル: RiseNodeApi.cs プロジェクト: Rajbandi/RiseSharp
 /// <summary>
 /// Gets list of blocks asynchronously 
 /// </summary>
 /// <param name="req">BlocksRequest</param>
 /// <returns>BlocksResponse with blocks list</returns>
 public async Task<BlocksResponse> GetBlocksAsync(BlocksRequest req)
 {
     _url.Path = Constants.ApiGetBlocks;
     _url.Query = req.ToQuery();
     var response = await _client.GetJsonAsync<BlocksResponse>(_url.ToString());
     ResetPath();
     return response;
 }
コード例 #11
0
ファイル: RiseNodeApi.cs プロジェクト: Rajbandi/RiseSharp
 /// <summary>
 /// Gets list of block synchronously  
 /// </summary>
 /// <param name="req">BlocksRequest</param>
 /// <returns>BlocksResponse with blocks list</returns>
 public BlocksResponse GetBlocks(BlocksRequest req)
 {
     return GetBlocksAsync(req).GetAwaiter().GetResult();
 }