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); }
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); } }