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