Beispiel #1
0
        public async Task ProcessPeerDiscoveryJob_PeerPoolIsFull_Test()
        {
            var endpoint = new AElfPeerEndpoint("192.168.100.1", 8000);
            var peer     = new Mock <IPeer>();

            peer.Setup(p => p.IsReady).Returns(true);
            peer.Setup(p => p.Info).Returns(new PeerConnectionInfo
            {
                Pubkey = endpoint.ToString(), ConnectionTime = TimestampHelper.GetUtcNow()
            });
            peer.Setup(p => p.RemoteEndpoint).Returns(endpoint);

            _peerPool.TryAddPeer(peer.Object);

            await RunDiscoveryWorkerAsync();

            var endpointString = "192.168.100.100:8003";
            var nodeList       = await _peerDiscoveryService.GetNodesAsync(10);

            nodeList.Nodes.Count.ShouldBe(1);
            nodeList.Nodes[0].Endpoint.ShouldBe(endpointString);
            nodeList.Nodes[0].Pubkey.ShouldBe(ByteString.CopyFromUtf8(endpointString));

            AElfPeerEndpointHelper.TryParse(endpointString, out var aelEndpoint);
            var result = _peerPool.FindPeerByEndpoint(aelEndpoint);

            result.ShouldBeNull();
        }
        public static bool TryParse(string endpointString, out DnsEndPoint endpoint,
                                    int defaultPort = NetworkConstants.DefaultPeerPort)
        {
            endpoint = null;

            if (string.IsNullOrEmpty(endpointString) || endpointString.Trim().Length == 0)
            {
                return(false);
            }

            if (defaultPort != -1 && (defaultPort < IPEndPoint.MinPort || defaultPort > IPEndPoint.MaxPort))
            {
                return(false);
            }

            string[] values = endpointString.Split(new char[] { ':' });
            string   host;
            int      port = -1;

            if (values.Length <= 2)
            {
                // ipv4 or hostname
                host = values[0];

                if (values.Length == 1)
                {
                    port = defaultPort;
                }
                else
                {
                    var parsedPort = GetPort(values[1]);

                    if (parsedPort == 0)
                    {
                        return(false);
                    }

                    port = parsedPort;
                }
            }
            else
            {
                //ipv6
                //could be [a:b:c]:d
                if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
                {
                    host = string.Join(":", values.Take(values.Length - 1).ToArray());
                    var parsedPort = GetPort(values[values.Length - 1]);

                    if (parsedPort == 0)
                    {
                        return(false);
                    }
                }
                else // [a:b:c] or a:b:c
                {
                    host = endpointString;
                    port = defaultPort;
                }
            }

            if (port == -1)
            {
                return(false);
            }

            // we leave semantic analysis of the ip/hostname to lower levels.
            endpoint = new AElfPeerEndpoint(host, port);

            return(true);
        }
Beispiel #3
0
        public async Task <HandshakeReply> DoHandshakeAsync(DnsEndPoint endpoint, Handshake handshake)
        {
            // validate the handshake (signature, chain id...)
            var handshakeValidationResult = await _handshakeProvider.ValidateHandshakeAsync(handshake);

            if (handshakeValidationResult != HandshakeValidationResult.Ok)
            {
                var handshakeError = GetHandshakeError(handshakeValidationResult);
                return(new HandshakeReply {
                    Error = handshakeError
                });
            }

            var pubkey = handshake.HandshakeData.Pubkey.ToHex();

            // remove any remaining connection to the peer (before the check
            // that we have room for more connections)
            var currentPeer = _peerPool.FindPeerByPublicKey(pubkey);

            if (currentPeer != null)
            {
                _peerPool.RemovePeer(pubkey);
                await currentPeer.DisconnectAsync(false);
            }

            try
            {
                // mark the (IP; pubkey) pair as currently handshaking
                if (!_peerPool.AddHandshakingPeer(endpoint.Host, pubkey))
                {
                    return new HandshakeReply {
                               Error = HandshakeError.ConnectionRefused
                    }
                }
                ;

                // create the connection to the peer
                var peerEndpoint = new AElfPeerEndpoint(endpoint.Host, handshake.HandshakeData.ListeningPort);
                var grpcPeer     = await _peerDialer.DialBackPeerAsync(peerEndpoint, handshake);

                // add the new peer to the pool
                if (!_peerPool.TryAddPeer(grpcPeer))
                {
                    Logger.LogWarning($"Stopping connection, peer already in the pool {grpcPeer.Info.Pubkey}.");

                    await grpcPeer.DisconnectAsync(false);

                    return(new HandshakeReply {
                        Error = HandshakeError.RepeatedConnection
                    });
                }

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

                // send back our handshake
                var replyHandshake = await _handshakeProvider.GetHandshakeAsync();

                grpcPeer.InboundSessionId = replyHandshake.SessionId.ToByteArray();
                grpcPeer.UpdateLastSentHandshake(replyHandshake);

                return(new HandshakeReply {
                    Handshake = replyHandshake, Error = HandshakeError.HandshakeOk
                });
            }
            finally
            {
                // remove the handshaking mark (IP; pubkey)
                _peerPool.RemoveHandshakingPeer(endpoint.Host, pubkey);
            }
        }