public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { try { if (context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.DoHandshake))) { // a method other than DoHandshake is being called var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null && context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Ping))) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } // check that the peers session is equal to one announced in the headers if (peer != null && !peer.InboundSessionId.BytesEqual(context.GetSessionId())) { Logger.LogWarning($"Wrong session id, ({peer.InboundSessionId.ToHex()} vs {context.GetSessionId().ToHex()}) {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } } catch (Exception e) { Logger.LogError(e, "Auth interceptor error: "); throw; } return(continuation(request, context)); }
public override Task <TResponse> ClientStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod <TRequest, TResponse> continuation) { try { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } if (!peer.InboundSessionId.BytesEqual(context.GetSessionId())) { Logger.LogWarning($"Wrong session id, ({peer.InboundSessionId.ToHex()} vs {context.GetSessionId().ToHex()}) {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } catch (Exception e) { Logger.LogError(e, "Auth stream interceptor error: "); return(null); } return(continuation(requestStream, context)); }
public override Task <TResponse> ClientStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod <TRequest, TResponse> continuation) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); return(continuation(requestStream, context)); }
public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { try { if (IsNeedAuth(context.Method)) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } // check that the peers session is equal to one announced in the headers var sessionId = context.GetSessionId(); if (!peer.InboundSessionId.BytesEqual(sessionId)) { if (peer.InboundSessionId == null) { Logger.LogWarning($"Wrong inbound session id {context.Peer}, {context.Method}"); return(Task.FromResult <TResponse>(null)); } if (sessionId == null) { Logger.LogWarning($"Wrong context session id {context.Peer}, {context.Method}, {peer}"); return(Task.FromResult <TResponse>(null)); } Logger.LogWarning( $"Unequal session id, {context.Peer} ({peer.InboundSessionId.ToHex()} vs {sessionId.ToHex()}) {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } } catch (Exception e) { Logger.LogError(e, $"Auth interceptor error {context.Peer}, {context.Method}: "); throw; } return(continuation(request, context)); }
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 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); }
/// <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()); }
private async Task ProcessTransaction(Transaction tx, ServerCallContext context) { var chain = await _blockchainService.GetChainAsync(); // if this transaction's ref block is a lot higher than our chain // then don't participate in p2p network if (tx.RefBlockNumber > chain.LongestChainHeight + NetworkConstants.DefaultInitialSyncOffset) { return; } var peer = _connectionService.GetPeerByPubkey(context.GetPublicKey()); if (peer == null) { // if peer already removed, drop. return; } if (!peer.TryAddKnownTransaction(tx.GetHash())) { return; } _ = EventBus.PublishAsync(new TransactionsReceivedEvent { Transactions = new List <Transaction> { tx } }); }
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); }
/// <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 Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { if (context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Connect))) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null && context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Ping))) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } return(continuation(request, context)); }
/// <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 override async Task <VoidReply> BlockBroadcastStream(IAsyncStreamReader <BlockWithTransactions> requestStream, ServerCallContext context) { await requestStream.ForEachAsync(r => { _ = EventBus.PublishAsync(new BlockReceivedEvent(r, context.GetPublicKey())); return(Task.CompletedTask); }); return(new VoidReply()); }
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 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 Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { if (context.Method != "/" + nameof(PeerService) + "/" + nameof(PeerService.PeerServiceBase.Connect)) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConsts.PeerInfoMetadataKey, $"{peer}")); } return(continuation(request, context)); }
/// <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 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())); }
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.LogDebug($"Transaction stream started with {context.GetPeerInfo()} - {context.Peer}."); try { var peerPubkey = context.GetPublicKey(); await requestStream.ForEachAsync(async tx => await ProcessTransactionAsync(tx, peerPubkey)); } catch (Exception e) { Logger.LogError(e, $"Transaction stream error - {context.GetPeerInfo()}: "); throw; } Logger.LogDebug($"Transaction stream finished with {context.GetPeerInfo()} - {context.Peer}."); 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 { var peerPubkey = context.GetPublicKey(); await requestStream.ForEachAsync(async r => await ProcessLibAnnouncementAsync(r, peerPubkey)); } 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()); }
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())); }