public override async Task <NodeList> GetNodes(NodesRequest request, ServerCallContext context) { if (request == null) { return(new NodeList()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested {request.MaxCount} nodes."); NodeList nodes; try { nodes = await _peerDiscoveryService.GetNodesAsync(request.MaxCount); } catch (Exception e) { Logger.LogError(e, "Get nodes error: "); throw; } Logger.LogDebug($"Sending {nodes.Nodes.Count} to {context.GetPeerInfo()}."); return(nodes); }
/// <summary> /// This method returns a block. The parameter is a <see cref="BlockRequest"/> object, if the value /// of <see cref="BlockRequest.Hash"/> is not null, the request is by ID, otherwise it will be /// by height. /// </summary> public override async Task <BlockReply> RequestBlock(BlockRequest request, ServerCallContext context) { if (request == null || request.Hash == null || _syncStateService.SyncState != SyncState.Finished) { return(new BlockReply()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested block {request.Hash}."); BlockWithTransactions block; try { block = await _blockchainService.GetBlockWithTransactionsByHash(request.Hash); if (block == null) { Logger.LogDebug($"Could not find block {request.Hash} for {context.GetPeerInfo()}."); } else { var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); peer.TryAddKnownBlock(block.GetHash()); } } catch (Exception e) { Logger.LogError(e, $"Request block error: {context.GetPeerInfo()}"); throw; } return(new BlockReply { Block = block }); }
public override async Task <VoidReply> BlockBroadcastStream( IAsyncStreamReader <BlockWithTransactions> requestStream, ServerCallContext context) { Logger.LogDebug($"Block stream started with {context.GetPeerInfo()} - {context.Peer}."); try { var peerPubkey = context.GetPublicKey(); var peer = _connectionService.GetPeerByPubkey(peerPubkey); if (peer.SyncState != SyncState.Finished) { peer.SyncState = SyncState.Finished; } await requestStream.ForEachAsync(block => { peer.TryAddKnownBlock(block.GetHash()); _ = EventBus.PublishAsync(new BlockReceivedEvent(block, peerPubkey)); return(Task.CompletedTask); }); } catch (Exception e) { Logger.LogError(e, $"Block stream error - {context.GetPeerInfo()}: "); throw; } Logger.LogDebug($"Block stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
public override async Task <VoidReply> AnnouncementBroadcastStream( IAsyncStreamReader <BlockAnnouncement> requestStream, ServerCallContext context) { Logger.LogDebug($"Announcement stream started with {context.GetPeerInfo()} - {context.Peer}."); await requestStream.ForEachAsync(async r => await ProcessAnnouncement(r, context)); Logger.LogDebug($"Announcement stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
public override async Task <VoidReply> TransactionBroadcastStream(IAsyncStreamReader <Transaction> requestStream, ServerCallContext context) { Logger.LogDebug($"Transaction stream started with {context.GetPeerInfo()} - {context.Peer}."); await requestStream.ForEachAsync(async tx => await ProcessTransaction(tx, context)); Logger.LogDebug($"Transaction stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
public override async Task <NodeList> GetNodes(NodesRequest request, ServerCallContext context) { if (request == null) { return(new NodeList()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested {request.MaxCount} nodes."); var nodes = await _peerDiscoveryService.GetNodesAsync(request.MaxCount); Logger.LogDebug($"Sending {nodes.Nodes.Count} to {context.GetPeerInfo()}."); return(nodes); }
public override async Task <VoidReply> BlockBroadcastStream( IAsyncStreamReader <BlockWithTransactions> requestStream, ServerCallContext context) { Logger.LogDebug($"Block stream started with {context.GetPeerInfo()} - {context.Peer}."); await requestStream.ForEachAsync(r => { _ = EventBus.PublishAsync(new BlockReceivedEvent(r, context.GetPublicKey())); return(Task.CompletedTask); }); Logger.LogDebug($"Block stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
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); if (blocks == null) { return(blockList); } 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); }
public override async Task <BlockList> RequestBlocks(BlocksRequest request, ServerCallContext context) { if (request == null || request.PreviousBlockHash == null) { return(new BlockList()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested {request.Count} blocks from {request.PreviousBlockHash}."); var blockList = new BlockList(); var blocks = await _blockChainService.GetBlocksInBestChainBranchAsync(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 (_netOpts.CompressBlocksOnRequest) { var headers = new Metadata { new Metadata.Entry(GrpcConsts.GrpcRequestCompressKey, GrpcConsts.GrpcGzipConst) }; await context.WriteResponseHeadersAsync(headers); } return(blockList); }
public override async Task <VoidReply> ConfirmHandshake(ConfirmHandshakeRequest request, ServerCallContext context) { Logger.LogDebug($"Peer {context.GetPeerInfo()} has requested a confirm handshake."); _connectionService.ConfirmHandshake(context.GetPublicKey()); return(new VoidReply()); }
public Task ProcessAnnouncement(BlockAnnouncement announcement, ServerCallContext context) { if (announcement?.BlockHash == null) { Logger.LogWarning($"Received null announcement or header from {context.GetPeerInfo()}."); return(Task.CompletedTask); } Logger.LogDebug( $"Received announce, block hash: {announcement.BlockHash}, block height: {announcement.BlockHeight} from {context.GetPeerInfo()}."); var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); if (peer == null) { // if peer already removed, drop. return(Task.CompletedTask); } if (!peer.TryAddKnownBlock(announcement.BlockHash)) { return(Task.CompletedTask); } if (peer.SyncState != SyncState.Finished) { peer.SyncState = SyncState.Finished; } _ = EventBus.PublishAsync(new AnnouncementReceivedEventData(announcement, context.GetPublicKey())); return(Task.CompletedTask); }
public Task ProcessLibAnnouncement(LibAnnouncement announcement, ServerCallContext context) { if (announcement?.LibHash == null) { Logger.LogWarning($"Received null or empty announcement from {context.GetPeerInfo()}."); return(Task.CompletedTask); } Logger.LogDebug( $"Received lib announce hash: {announcement.LibHash}, height {announcement.LibHeight} from {context.GetPeerInfo()}."); var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); if (peer == null) { // if peer already removed, drop. return(Task.CompletedTask); } peer.UpdateLastKnownLib(announcement); if (peer.SyncState != SyncState.Finished) { peer.SyncState = SyncState.Finished; } return(Task.CompletedTask); }
public override Task <VoidReply> ConfirmHandshake(ConfirmHandshakeRequest request, ServerCallContext context) { try { Logger.LogDebug($"Peer {context.GetPeerInfo()} has requested a handshake confirmation."); _connectionService.ConfirmHandshake(context.GetPublicKey()); } catch (Exception e) { Logger.LogError(e, $"Confirm handshake error - {context.GetPeerInfo()}: "); throw; } return(Task.FromResult(new VoidReply())); }
/// <summary> /// Clients should call this method to disconnect explicitly. /// </summary> public override async Task <VoidReply> Disconnect(DisconnectReason request, ServerCallContext context) { Logger.LogDebug($"Peer {context.GetPeerInfo()} has sent a disconnect request."); await _peerPool.RemovePeerAsync(context.GetPublicKey(), false); return(new VoidReply()); }
public override async Task <VoidReply> LibAnnouncementBroadcastStream(IAsyncStreamReader <LibAnnouncement> requestStream, ServerCallContext context) { Logger.LogDebug($"Lib announcement stream started with {context.GetPeerInfo()} - {context.Peer}."); try { await requestStream.ForEachAsync(async r => await ProcessLibAnnouncement(r, context)); } catch (Exception e) { Logger.LogError(e, $"Lib announcement stream error: {context.GetPeerInfo()}"); throw; } Logger.LogDebug($"Lib announcement stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
/// <summary> /// This method is called when a peer wants to broadcast an announcement. /// </summary> public override Task <VoidReply> Announce(PeerNewBlockAnnouncement an, ServerCallContext context) { if (an?.BlockHash == null || an?.BlockTime == null) { Logger.LogError($"Received null announcement or header from {context.GetPeerInfo()}."); return(Task.FromResult(new VoidReply())); } var peerInPool = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); peerInPool?.HandlerRemoteAnnounce(an); Logger.LogDebug($"Received announce {an.BlockHash} from {context.GetPeerInfo()}."); _ = EventBus.PublishAsync(new AnnouncementReceivedEventData(an, context.GetPublicKey())); return(Task.FromResult(new VoidReply())); }
public Task ProcessAnnouncement(BlockAnnouncement announcement, ServerCallContext context) { if (announcement?.BlockHash == null) { Logger.LogError($"Received null announcement or header from {context.GetPeerInfo()}."); return(Task.CompletedTask); } Logger.LogDebug($"Received announce {announcement.BlockHash} from {context.GetPeerInfo()}."); var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); peer?.AddKnowBlock(announcement); _ = EventBus.PublishAsync(new AnnouncementReceivedEventData(announcement, context.GetPublicKey())); return(Task.CompletedTask); }
public override async Task <VoidReply> TransactionBroadcastStream(IAsyncStreamReader <Transaction> requestStream, ServerCallContext context) { Logger.LogTrace($"Transaction stream started with {context.GetPeerInfo()} - {context.Peer}."); try { await requestStream.ForEachAsync(async tx => await ProcessTransaction(tx, context)); } catch (Exception e) { Logger.LogError(e, $"Transaction stream error - {context.GetPeerInfo()}: "); throw; } Logger.LogTrace($"Transaction stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
/// <summary> /// This method returns a block. The parameter is a <see cref="BlockRequest"/> object, if the value /// of <see cref="BlockRequest.Hash"/> is not null, the request is by ID, otherwise it will be /// by height. /// </summary> public override async Task <BlockReply> RequestBlock(BlockRequest request, ServerCallContext context) { if (request == null || request.Hash == null || _syncStateService.SyncState != SyncState.Finished) { return(new BlockReply()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested block {request.Hash}."); var block = await _blockchainService.GetBlockWithTransactionsByHash(request.Hash); if (block == null) { Logger.LogDebug($"Could not find block {request.Hash} for {context.GetPeerInfo()}."); } return(new BlockReply { Block = block }); }
/// <summary> /// This method returns a block. The parameter is a <see cref="BlockRequest"/> object, if the value /// of <see cref="BlockRequest.Id"/> is not null, the request is by ID, otherwise it will be /// by height. /// </summary> public override async Task <BlockReply> RequestBlock(BlockRequest request, ServerCallContext context) { if (request == null || request.Hash == null) { return(new BlockReply()); } Logger.LogDebug($"Peer {context.GetPeerInfo()} requested block {request.Hash}."); var block = await _blockChainService.GetBlockByHashAsync(request.Hash); if (block == null) { Logger.LogDebug($"Could not find block {request.Hash} for {context.GetPeerInfo()}."); } return(new BlockReply { Block = block }); }
public override async Task <VoidReply> BlockBroadcastStream( IAsyncStreamReader <BlockWithTransactions> requestStream, ServerCallContext context) { Logger.LogDebug($"Block stream started with {context.GetPeerInfo()} - {context.Peer}."); try { var peerPubkey = context.GetPublicKey(); await requestStream.ForEachAsync(async block => await ProcessBlockAsync(block, peerPubkey)); } catch (Exception e) { Logger.LogError(e, $"Block stream error - {context.GetPeerInfo()}: "); throw; } Logger.LogDebug($"Block stream finished with {context.GetPeerInfo()} - {context.Peer}."); return(new VoidReply()); }
/// <summary> /// This method is called when a peer wants to broadcast an announcement. /// </summary> public override async Task <VoidReply> SendAnnouncement(BlockAnnouncement an, ServerCallContext context) { try { await ProcessAnnouncement(an, context); } catch (Exception e) { Logger.LogError(e, $"Process announcement error: {context.GetPeerInfo()}"); throw; } return(new VoidReply()); }
/// <summary> /// This method is called when another peer broadcasts a transaction. /// </summary> public override async Task <VoidReply> SendTransaction(Transaction tx, ServerCallContext context) { try { await ProcessTransaction(tx, context); } catch (Exception e) { Logger.LogError(e, $"SendTransaction error - {context.GetPeerInfo()}: "); throw; } return(new VoidReply()); }
/// <summary> /// Clients should call this method to disconnect explicitly. /// </summary> public override Task <VoidReply> Disconnect(DisconnectReason request, ServerCallContext context) { Logger.LogDebug($"Peer {context.GetPeerInfo()} has sent a disconnect request."); try { _connectionService.RemovePeer(context.GetPublicKey()); } catch (Exception e) { Logger.LogError(e, "Disconnect error: "); throw; } return(Task.FromResult(new VoidReply())); }
public Task ProcessLibAnnouncement(LibAnnouncement announcement, ServerCallContext context) { if (announcement?.LibHash == null) { Logger.LogError($"Received null or empty announcement from {context.GetPeerInfo()}."); return(Task.CompletedTask); } Logger.LogDebug($"Received lib announce hash: {announcement.LibHash}, height {announcement.LibHeight} from {context.GetPeerInfo()}."); var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); peer?.UpdateLastKnownLib(announcement); return(Task.CompletedTask); }
public override async Task <HandshakeReply> DoHandshake(HandshakeRequest request, ServerCallContext context) { Logger.LogDebug($"Peer {context.GetPeerInfo()} has requested a handshake."); return(await _connectionService.CheckIncomingHandshakeAsync(context.GetPublicKey(), request.Handshake)); }
/// <summary> /// Clients should call this method to disconnect explicitly. /// </summary> public override Task <VoidReply> Disconnect(DisconnectReason request, ServerCallContext context) { Logger.LogDebug($"Peer {context.GetPeerInfo()} has sent a disconnect request."); _connectionService.RemovePeer(context.GetPublicKey()); return(Task.FromResult(new VoidReply())); }