示例#1
0
        public async Task DialPeer_Test()
        {
            AElfPeerEndpointHelper.TryParse("127.0.0.1:2000", out var endpoint);
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldNotBeNull();

            grpcPeer.CurrentBlockHash.ShouldBe(HashHelper.ComputeFrom("BestChainHash"));
            grpcPeer.CurrentBlockHeight.ShouldBe(10);
            grpcPeer.LastKnownLibHeight.ShouldBe(1);
        }
        public async Task DialPeer_Test()
        {
            AElfPeerEndpointHelper.TryParse("127.0.0.1:2000", out var endpoint);
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldBeNull();
        }
        public async Task DialPeer_Test()
        {
            var endpoint = IpEndPointHelper.Parse("127.0.0.1:2000");
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldBeNull();
        }
        private async Task <GrpcPeer> GetDialedPeerWithEndpointAsync(DnsEndPoint endpoint)
        {
            var peer = _peerPool.FindPeerByEndpoint(endpoint);

            if (peer != null)
            {
                if (peer.IsInvalid)
                {
                    _peerPool.RemovePeer(peer.Info.Pubkey);
                    await peer.DisconnectAsync(false);
                }
                else
                {
                    Logger.LogWarning($"Peer with endpoint {endpoint} is already in the pool.");
                    return(null);
                }
            }

            if (_peerPool.IsPeerBlackListed(endpoint.Host))
            {
                Logger.LogDebug($"Peer with endpoint {endpoint} is blacklisted.");
                return(null);
            }

            var dialedPeer = await _peerDialer.DialPeerAsync(endpoint);

            if (dialedPeer == null)
            {
                Logger.LogDebug($"Error dialing {endpoint}.");
                return(null);
            }

            return(dialedPeer);
        }
示例#5
0
        public async Task DialPeer_Test()
        {
            AElfPeerEndpointHelper.TryParse("127.0.0.1:2000", out var endpoint);
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldNotBeNull();

            var peersHandshake = _networkTestContext.GeneratedHandshakes[endpoint.Host];

            grpcPeer.CurrentBlockHash.ShouldBe(peersHandshake.HandshakeData.BestChainHash);
            grpcPeer.CurrentBlockHeight.ShouldBe(peersHandshake.HandshakeData.BestChainHeight);
            grpcPeer.LastKnownLibHeight.ShouldBe(peersHandshake.HandshakeData.LastIrreversibleBlockHeight);
        }
示例#6
0
        private async Task <GrpcPeer> GetDialedPeerWithEndpointAsync(DnsEndPoint endpoint)
        {
            if (_peerPool.FindPeerByEndpoint(endpoint) != null)
            {
                Logger.LogWarning($"Peer with endpoint {endpoint} is already in the pool.");
                return(null);
            }

            if (_peerPool.IsPeerBlackListed(endpoint.Host))
            {
                Logger.LogWarning($"Peer with endpoint {endpoint} is blacklisted.");
                return(null);
            }

            var dialedPeer = await _peerDialer.DialPeerAsync(endpoint);

            if (dialedPeer == null)
            {
                Logger.LogWarning($"Error dialing {endpoint}.");
                return(null);
            }

            return(dialedPeer);
        }
示例#7
0
        /// <summary>
        /// Connects to a node with the given ip address and adds it to the node's peer pool.
        /// </summary>
        /// <param name="endpoint">the ip address of the distant node</param>
        /// <returns>True if the connection was successful, false otherwise</returns>
        public async Task <bool> ConnectAsync(DnsEndPoint endpoint)
        {
            Logger.LogDebug($"Attempting to reach {endpoint}.");

            if (_peerPool.FindPeerByEndpoint(endpoint) != null)
            {
                Logger.LogWarning($"Peer with endpoint {endpoint} is already in the pool.");
                return(false);
            }

            if (_peerPool.IsPeerBlackListed(endpoint.Host))
            {
                Logger.LogWarning($"Peer with endpoint {endpoint} is blacklisted.");
                return(false);
            }

            var dialedPeer = await _peerDialer.DialPeerAsync(endpoint);

            if (dialedPeer == null)
            {
                Logger.LogWarning($"Error dialing {endpoint}.");
                return(false);
            }

            var inboundPeer = _peerPool.FindPeerByPublicKey(dialedPeer.Info.Pubkey) as GrpcPeer;

            /* A connection already exists, this can happen when both peers dial each other at the same time. To make
             * sure both sides close the same connection, they both decide based on the times of the handshakes.
             * Scenario steps, chronologically:
             *  1) P1 (hsk_time: t1) --> dials P2 --and-- P1 <-- P2 dials (hsk_time: t2)
             *  2) P2 receives P1s dial with t1 (in the hsk) and add to the pool
             *  3) P1 receives P2s dial with and adds to pool
             *  4) both dials finish and find that the pool already contains the dialed node.
             * To resolve this situation, both peers will choose the connection that was initiated the earliest,
             * so either P1s dial or P2s. */

            GrpcPeer currentPeer = dialedPeer;

            if (inboundPeer != null)
            {
                Logger.LogWarning("Duplicate peer connection detected: " +
                                  $"{inboundPeer} ({inboundPeer.LastReceivedHandshakeTime}) " +
                                  $"vs {dialedPeer} ({dialedPeer.LastSentHandshakeTime}).");

                if (inboundPeer.LastReceivedHandshakeTime > dialedPeer.LastSentHandshakeTime)
                {
                    // we started the dial first, replace the inbound connection with the dialed
                    if (!_peerPool.TryReplace(inboundPeer.Info.Pubkey, inboundPeer, dialedPeer))
                    {
                        Logger.LogWarning("Replacing the inbound connection failed.");
                    }

                    await inboundPeer.DisconnectAsync(false);

                    Logger.LogWarning($"Replaced the inbound connection with the dialed peer {inboundPeer} .");
                }
                else
                {
                    // keep the inbound connection
                    await dialedPeer.DisconnectAsync(false);

                    currentPeer = inboundPeer;

                    Logger.LogWarning($"Disconnected dialed peer {dialedPeer}.");
                }
            }
            else
            {
                if (!_peerPool.TryAddPeer(dialedPeer))
                {
                    Logger.LogWarning($"Peer add to the failed {dialedPeer.Info.Pubkey}.");
                    await dialedPeer.DisconnectAsync(false);

                    return(false);
                }

                Logger.LogDebug($"Added to pool {dialedPeer.RemoteEndpoint} - {dialedPeer.Info.Pubkey}.");
            }

            try
            {
                await currentPeer.ConfirmHandshakeAsync();
            }
            catch (Exception e)
            {
                Logger.LogError(e, $"Confirm handshake error. Peer: {currentPeer.Info.Pubkey}.");
                _peerPool.RemovePeer(currentPeer.Info.Pubkey);
                await currentPeer.DisconnectAsync(false);

                throw;
            }

            currentPeer.IsConnected = true;
            currentPeer.SyncState   = SyncState.Syncing;

            Logger.LogInformation($"Connected to: {currentPeer.RemoteEndpoint} - {currentPeer.Info.Pubkey.Substring(0, 45)}" +
                                  $" - in-token {currentPeer.InboundSessionId?.ToHex()}, out-token {currentPeer.OutboundSessionId?.ToHex()}" +
                                  $" - LIB height {currentPeer.LastKnownLibHeight}" +
                                  $" - best chain [{currentPeer.CurrentBlockHeight}, {currentPeer.CurrentBlockHash}]");

            FireConnectionEvent(currentPeer);

            return(true);
        }
示例#8
0
        /// <summary>
        /// Connects to a node with the given ip address and adds it to the node's peer pool.
        /// </summary>
        /// <param name="endpoint">the ip address of the distant node</param>
        /// <returns>True if the connection was successful, false otherwise</returns>
        public async Task <bool> ConnectAsync(IPEndPoint endpoint)
        {
            Logger.LogTrace($"Attempting to reach {endpoint}.");

            if (_peerPool.FindPeerByEndpoint(endpoint) != null)
            {
                Logger.LogWarning($"Peer {endpoint} is already in the pool.");
                return(false);
            }

            GrpcPeer peer;

            try
            {
                // create the connection to the distant node
                peer = await _peerDialer.DialPeerAsync(endpoint);
            }
            catch (PeerDialException ex)
            {
                Logger.LogError(ex, $"Dial exception {endpoint}:");
                return(false);
            }

            var peerPubkey = peer.Info.Pubkey;

            if (!_peerPool.TryAddPeer(peer))
            {
                Logger.LogWarning($"Peer {peerPubkey} is already in the pool.");
                await peer.DisconnectAsync(false);

                return(false);
            }

            Handshake peerHandshake;

            try
            {
                peerHandshake = await peer.DoHandshakeAsync(await _handshakeProvider.GetHandshakeAsync());
            }
            catch (NetworkException ex)
            {
                Logger.LogError(ex, $"Handshake failed to {endpoint} - {peerPubkey}.");
                await DisconnectAsync(peer);

                return(false);
            }

            HandshakeError handshakeError = ValidateHandshake(peerHandshake, peerPubkey);

            if (handshakeError != HandshakeError.HandshakeOk)
            {
                Logger.LogWarning($"Invalid handshake [{handshakeError}] from {endpoint} - {peerPubkey}");
                await DisconnectAsync(peer);

                return(false);
            }

            Logger.LogTrace($"Connected to {peer} - LIB height {peer.LastKnownLibHeight}, " +
                            $"best chain [{peer.CurrentBlockHeight}, {peer.CurrentBlockHash}].");

            FireConnectionEvent(peer);

            return(true);
        }