예제 #1
0
        public GrpcPeer(GrpcClient client, DnsEndPoint remoteEndpoint, PeerConnectionInfo peerConnectionInfo)
        {
            _channel = client.Channel;
            _client  = client.Client;

            RemoteEndpoint = remoteEndpoint;
            Info           = peerConnectionInfo;

            _knownTransactionCache = new BoundedExpirationCache(TransactionCacheMaxItems, QueuedItemTimeout);
            _knownBlockCache       = new BoundedExpirationCache(BlockCacheMaxItems, QueuedItemTimeout);

            _recentRequestsRoundtripTimes = new ConcurrentDictionary <string, ConcurrentQueue <RequestMetric> >();
            RecentRequestsRoundtripTimes  =
                new ReadOnlyDictionary <string, ConcurrentQueue <RequestMetric> >(_recentRequestsRoundtripTimes);

            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.Announce), new ConcurrentQueue <RequestMetric>());
            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.GetBlock), new ConcurrentQueue <RequestMetric>());
            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.GetBlocks), new ConcurrentQueue <RequestMetric>());

            _sendAnnouncementJobs = new ActionBlock <StreamJob>(SendStreamJobAsync,
                                                                new ExecutionDataflowBlockOptions
            {
                BoundedCapacity = NetworkConstants.DefaultMaxBufferedAnnouncementCount
            });
            _sendBlockJobs = new ActionBlock <StreamJob>(SendStreamJobAsync,
                                                         new ExecutionDataflowBlockOptions
            {
                BoundedCapacity = NetworkConstants.DefaultMaxBufferedBlockCount
            });
            _sendTransactionJobs = new ActionBlock <StreamJob>(SendStreamJobAsync,
                                                               new ExecutionDataflowBlockOptions
            {
                BoundedCapacity = NetworkConstants.DefaultMaxBufferedTransactionCount
            });
        }
예제 #2
0
        /// <summary>
        /// Calls the server side DoHandshake RPC method, in order to establish a 2-way connection.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task <HandshakeReply> CallDoHandshakeAsync(GrpcClient client, DnsEndPoint remoteEndPoint,
                                                                 Handshake handshake)
        {
            HandshakeReply handshakeReply;

            try
            {
                var metadata = new Metadata
                {
                    { GrpcConstants.RetryCountMetadataKey, "0" },
                    { GrpcConstants.TimeoutMetadataKey, (NetworkOptions.PeerDialTimeout * 2).ToString() }
                };

                handshakeReply =
                    await client.Client.DoHandshakeAsync(new HandshakeRequest { Handshake = handshake }, metadata);

                Logger.LogDebug($"Handshake to {remoteEndPoint} successful.");
            }
            catch (Exception)
            {
                await client.Channel.ShutdownAsync();

                throw;
            }

            return(handshakeReply);
        }
예제 #3
0
        /// <summary>
        /// Calls the server side DoHandshake RPC method, in order to establish a 2-way connection.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task <HandshakeReply> CallDoHandshakeAsync(GrpcClient client, IPEndPoint remoteEndPoint,
                                                                 Handshake handshake)
        {
            HandshakeReply handshakeReply;

            try
            {
                var metadata = new Metadata
                {
                    { GrpcConstants.TimeoutMetadataKey, (NetworkOptions.PeerDialTimeoutInMilliSeconds * 2).ToString() }
                };

                handshakeReply =
                    await client.Client.DoHandshakeAsync(new HandshakeRequest { Handshake = handshake }, metadata);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Could not connect to {remoteEndPoint}.");
                await client.Channel.ShutdownAsync();

                throw;
            }

            return(handshakeReply);
        }
예제 #4
0
        /// <summary>
        /// Checks that the distant node is reachable by pinging it.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task PingNodeAsync(GrpcClient client, IPEndPoint ipAddress)
        {
            try
            {
                var metadata = new Metadata {
                    { GrpcConstants.TimeoutMetadataKey, NetworkOptions.PeerDialTimeoutInMilliSeconds.ToString() }
                };

                await client.Client.PingAsync(new PingRequest(), metadata);
            }
            catch (AggregateException ex)
            {
                await CleanupAndGetExceptionAsync($"Could not ping {ipAddress}.", client.Channel, ex);
            }
        }
예제 #5
0
        public GrpcPeer(GrpcClient client, IPEndPoint remoteEndpoint, PeerInfo peerInfo)
        {
            _channel = client.Channel;
            _client  = client.Client;

            RemoteEndpoint = remoteEndpoint;
            Info           = peerInfo;

            _recentBlockHeightAndHashMappings = new ConcurrentDictionary <long, Hash>();
            RecentBlockHeightAndHashMappings  = new ReadOnlyDictionary <long, Hash>(_recentBlockHeightAndHashMappings);

            _recentRequestsRoundtripTimes = new ConcurrentDictionary <string, ConcurrentQueue <RequestMetric> >();
            RecentRequestsRoundtripTimes  =
                new ReadOnlyDictionary <string, ConcurrentQueue <RequestMetric> >(_recentRequestsRoundtripTimes);

            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.Announce), new ConcurrentQueue <RequestMetric>());
            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.GetBlock), new ConcurrentQueue <RequestMetric>());
            _recentRequestsRoundtripTimes.TryAdd(nameof(MetricNames.GetBlocks), new ConcurrentQueue <RequestMetric>());
        }
예제 #6
0
        /// <summary>
        /// Checks that the distant node is reachable by pinging it.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task PingNodeAsync(GrpcClient client, IPEndPoint ipAddress)
        {
            try
            {
                var metadata = new Metadata
                {
                    { GrpcConstants.TimeoutMetadataKey, NetworkOptions.PeerDialTimeoutInMilliSeconds.ToString() }
                };

                await client.Client.PingAsync(new PingRequest(), metadata);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Could not ping {ipAddress}.");
                await client.Channel.ShutdownAsync();

                throw;
            }
        }
예제 #7
0
        /// <summary>
        /// Calls the server side connect RPC method, in order to establish a 2-way connection.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task <ConnectReply> CallConnectAsync(GrpcClient client, IPEndPoint ipAddress,
                                                           ConnectionInfo connectionInfo)
        {
            ConnectReply connectReply = null;

            try
            {
                var metadata = new Metadata {
                    { GrpcConstants.TimeoutMetadataKey, (NetworkOptions.PeerDialTimeoutInMilliSeconds * 2).ToString() }
                };

                connectReply = await client.Client.ConnectAsync(new ConnectRequest { Info = connectionInfo }, metadata);
            }
            catch (AggregateException ex)
            {
                await CleanupAndGetExceptionAsync($"Could not connect to {ipAddress}.", client.Channel, ex);
            }

            return(connectReply);
        }
예제 #8
0
        /// <summary>
        /// Checks that the distant node is reachable by pinging it.
        /// </summary>
        /// <returns>The reply from the server.</returns>
        private async Task PingNodeAsync(GrpcClient client, DnsEndPoint peerEndpoint)
        {
            try
            {
                var metadata = new Metadata
                {
                    { GrpcConstants.RetryCountMetadataKey, "0" },
                    { GrpcConstants.TimeoutMetadataKey, NetworkOptions.PeerDialTimeout.ToString() }
                };

                await client.Client.PingAsync(new PingRequest(), metadata);

                Logger.LogDebug($"Pinged {peerEndpoint} successfully.");
            }
            catch (Exception ex)
            {
                Logger.LogWarning(ex, $"Could not ping {peerEndpoint}.");
                await client.Channel.ShutdownAsync();

                throw;
            }
        }