private async Task <BlockBody[]> SendRequest(GetBlockBodiesMessage message, CancellationToken token) { if (_headersRequests.IsAddingCompleted || _isDisposed) { throw new TimeoutException("Session disposed"); } if (Logger.IsTrace) { Logger.Trace("Sending bodies request:"); Logger.Trace($"Blockhashes count: {message.BlockHashes.Length}"); } var request = new Request <GetBlockBodiesMessage, BlockBody[]>(message); _bodiesRequests.Add(request, token); var perfCalcId = _perfService.StartPerfCalc(); Send(request.Message); Task <BlockBody[]> task = request.CompletionSource.Task; CancellationTokenSource delayCancellation = new CancellationTokenSource(); CancellationTokenSource compositeCancellation = CancellationTokenSource.CreateLinkedTokenSource(token, delayCancellation.Token); var firstTask = await Task.WhenAny(task, Task.Delay(Timeouts.Eth, compositeCancellation.Token)); if (firstTask.IsCanceled) { token.ThrowIfCancellationRequested(); } if (firstTask == task) { delayCancellation.Cancel(); var latency = _perfService.EndPerfCalc(perfCalcId); if (latency.HasValue) { StatsManager.ReportLatencyCaptureEvent(Session.Node, NodeLatencyStatType.BlockBodies, latency.Value); } return(task.Result); } throw new TimeoutException($"{Session} Request timeout in {nameof(GetBlockBodiesMessage)} with {message.BlockHashes.Length} block hashes"); }
private async Task <Block[]> SendRequest(GetBlockBodiesMessage message, CancellationToken token) { if (Logger.IsTrace) { Logger.Trace("Sending bodies request:"); Logger.Trace($"Blockhashes count: {message.BlockHashes.Length}"); } var request = new Request <GetBlockBodiesMessage, Block[]>(message); _bodiesRequests.Add(request, token); var perfCalcId = _perfService.StartPerfCalc(); Send(request.Message); Task <Block[]> task = request.CompletionSource.Task; var firstTask = await Task.WhenAny(task, Task.Delay(Timeouts.Eth, token)); if (firstTask.IsCanceled) { token.ThrowIfCancellationRequested(); } if (firstTask == task) { var latency = _perfService.EndPerfCalc(perfCalcId); if (latency.HasValue) { P2PSession?.NodeStats.AddLatencyCaptureEvent(NodeLatencyStatType.BlockBodies, latency.Value); } return(task.Result); } throw new TimeoutException($"{P2PSession.RemoteNodeId} Request timeout in {nameof(GetBlockBodiesMessage)}"); }
async Task <BlockBody[]> ISyncPeer.GetBlockBodies(IList <Keccak> blockHashes, CancellationToken token) { // Logger.Info($"Sending bodies request ({blockHashes.Count}) to {this}"); if (blockHashes.Count == 0) { return(new BlockBody[0]); } var bodiesMsg = new GetBlockBodiesMessage(blockHashes); BlockBody[] blocks = await SendRequest(bodiesMsg, token); // int nonNullCount = 0; // for (int i = 0; i < blocks.Length; i++) // { // if (blocks[i] != null) // { // nonNullCount++; // } // } // Logger.Info($"Sent bodies request ({blockHashes.Count}) to {this} - received {blocks.Length}, out of which {nonNullCount} non null"); return(blocks); }
public virtual void HandleMessage(ZeroPacket message) { if (Logger.IsTrace) { Logger.Trace($"Handling {message} message from {Session.Node:c}."); } if (message.PacketType != Eth62MessageCode.Status && !_statusReceived) { throw new SubprotocolException($"No {nameof(StatusMessage)} received prior to communication with {Session.Node:c}."); } int size = message.Content.ReadableBytes; // Logger.Warn($"Received a message {message.Protocol}.{Enum.GetName(typeof(Eth62MessageCode), message.PacketType)} of size {size/1024}kb"); switch (message.PacketType) { case Eth62MessageCode.Status: StatusMessage statusMessage = Deserialize <StatusMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, statusMessage.ToString()); } Handle(statusMessage); break; case Eth62MessageCode.NewBlockHashes: if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, nameof(NewBlockHashesMessage)); } Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} NewBlockHashes from {Node:c}"); } Metrics.Eth62NewBlockHashesReceived++; Handle(Deserialize <NewBlockHashesMessage>(message.Content)); break; case Eth62MessageCode.Transactions: Interlocked.Increment(ref Counter); Metrics.Eth62TransactionsReceived++; TransactionsMessage transactionsMessage = Deserialize <TransactionsMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(TransactionsMessage)}({transactionsMessage.Transactions.Length})"); } if (!_isDowngradedDueToTxFlooding || 10 > _random.Next(0, 99)) // TODO: disable that when IsMining is set to true { Handle(transactionsMessage); } break; case Eth62MessageCode.GetBlockHeaders: Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} GetBlockHeaders from {Node:c}"); } Metrics.Eth62GetBlockHeadersReceived++; GetBlockHeadersMessage getBlockHeadersMessage = Deserialize <GetBlockHeadersMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(GetBlockHeadersMessage)}({getBlockHeadersMessage.StartingBlockNumber}|{getBlockHeadersMessage.StartingBlockHash}, {getBlockHeadersMessage.MaxHeaders})"); } Handle(getBlockHeadersMessage); break; case Eth62MessageCode.BlockHeaders: Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} BlockHeaders from {Node:c}"); } Metrics.Eth62BlockHeadersReceived++; BlockHeadersMessage blockHeadersMessage = Deserialize <BlockHeadersMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(BlockHeadersMessage)}({blockHeadersMessage.BlockHeaders.Length})"); } Handle(blockHeadersMessage, size); break; case Eth62MessageCode.GetBlockBodies: Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} GetBlockBodies from {Node:c}"); } Metrics.Eth62GetBlockBodiesReceived++; GetBlockBodiesMessage getBlockBodiesMessage = Deserialize <GetBlockBodiesMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(GetBlockBodiesMessage)}({getBlockBodiesMessage.BlockHashes.Count})"); } Handle(getBlockBodiesMessage); break; case Eth62MessageCode.BlockBodies: Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} BlockBodies from {Node:c}"); } Metrics.Eth62BlockBodiesReceived++; BlockBodiesMessage blockBodiesMessage = Deserialize <BlockBodiesMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(BlockBodiesMessage)}({blockBodiesMessage.Bodies.Length})"); } Handle(blockBodiesMessage, size); break; case Eth62MessageCode.NewBlock: Interlocked.Increment(ref Counter); if (Logger.IsTrace) { Logger.Trace($"{Counter:D5} NewBlock from {Node:c}"); } Metrics.Eth62NewBlockReceived++; NewBlockMessage newBlockMessage = Deserialize <NewBlockMessage>(message.Content); if (NetworkDiagTracer.IsEnabled) { NetworkDiagTracer.ReportIncomingMessage(Session.Node.Host, Name, $"{nameof(NewBlockMessage)}({newBlockMessage.Block.Number})"); } Handle(newBlockMessage); break; } }