private void AddPeer(string publicKey, int blockHeight)
        {
            var channel = new Channel(OSConsensusDPosTestConstants.FakeIpEndpoint, ChannelCredentials.Insecure);

            var connectionInfo = new PeerConnectionInfo
            {
                Pubkey          = publicKey,
                ProtocolVersion = KernelConstants.ProtocolVersion,
                ConnectionTime  = TimestampHelper.GetUtcNow(),
                IsInbound       = true
            };

            var peer = new GrpcPeer(new GrpcClient(channel, new PeerService.PeerServiceClient(channel)), IpEndPointHelper.Parse(OSConsensusDPosTestConstants.FakeIpEndpoint), connectionInfo);

            peer.IsConnected = true;

            var blocks = _osTestHelper.BestBranchBlockList.GetRange(0, blockHeight);

            foreach (var block in blocks)
            {
                peer.AddKnowBlock(new BlockAnnouncement
                {
                    BlockHash = block.GetHash(), BlockHeight = block.Height
                });
            }
            _peerPool.TryAddPeer(peer);
        }
Esempio n. 2
0
        public static GrpcPeer CreateNewPeer(string ipAddress = "127.0.0.1:2000", bool isValid = true, string publicKey = null)
        {
            var pubkey  = publicKey ?? NetworkTestConstants.FakePubkey;
            var channel = new Channel(ipAddress, ChannelCredentials.Insecure);

            PeerService.PeerServiceClient client;

            if (isValid)
            {
                client = new PeerService.PeerServiceClient(channel.Intercept(metadata =>
                {
                    metadata.Add(GrpcConstants.PubkeyMetadataKey, pubkey);
                    return(metadata);
                }));
            }
            else
            {
                client = new PeerService.PeerServiceClient(channel);
            }

            var connectionInfo = new PeerConnectionInfo
            {
                Pubkey          = pubkey,
                ProtocolVersion = KernelConstants.ProtocolVersion,
                ConnectionTime  = TimestampHelper.GetUtcNow(),
                SessionId       = new byte[] { 0, 1, 2 },
                IsInbound       = true
            };

            var peer = new GrpcPeer(new GrpcClient(channel, client), IpEndPointHelper.Parse(ipAddress), connectionInfo);

            peer.InboundSessionId = new byte[] { 0, 1, 2 };

            return(peer);
        }
Esempio n. 3
0
        public static GrpcPeer CreatePeerWithInfo(string ip, PeerConnectionInfo info)
        {
            var peer = new GrpcPeer(new GrpcClient(CreateMockChannel(), null), IpEndPointHelper.Parse(ip), info);

            peer.InboundSessionId = new byte[] { 0, 1, 2 };
            return(peer);
        }
        private TaskCompletionSource <VoidReply> _testCompletionSource; // completion for all

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var mockClient = new Mock <PeerService.PeerServiceClient>();

            _testCompletionSource = new TaskCompletionSource <VoidReply>();

            // setup mock announcement stream
            var announcementStreamCall = MockStreamCall <BlockAnnouncement, VoidReply>(_testCompletionSource.Task);

            mockClient.Setup(m => m.AnnouncementBroadcastStream(null, null, CancellationToken.None))
            .Returns(announcementStreamCall);

            // setup mock transaction stream
            var transactionStreamCall = MockStreamCall <Transaction, VoidReply>(_testCompletionSource.Task);

            mockClient.Setup(m => m.TransactionBroadcastStream(null, null, CancellationToken.None))
            .Returns(transactionStreamCall);

            // setup mock block stream
            var blockStreamCall = MockStreamCall <BlockWithTransactions, VoidReply>(_testCompletionSource.Task);

            mockClient.Setup(m => m.BlockBroadcastStream(null, null, CancellationToken.None))
            .Returns(blockStreamCall);

            // create peer
            _peerUnderTest = GrpcTestPeerHelpers.CreatePeerWithClient(NetworkTestConstants.FakeIpEndpoint,
                                                                      NetworkTestConstants.FakePubkey, mockClient.Object);

            _peerUnderTest.IsConnected = true;

            context.Services.AddSingleton <IPeer>(_peerUnderTest);
        }
Esempio n. 5
0
        public async Task RemovePeerTest()
        {
            var ipAddressOne = "192.168.1.1:1680";
            var channelOne   = new Channel(ipAddressOne, ChannelCredentials.Insecure);
            var peerOne      = new GrpcPeer(channelOne, new PeerService.PeerServiceClient(channelOne),
                                            "0454dcd0afc20d015e328666d8d25f3f28b13ccd9744eb6b153e4a69709aab399",
                                            ipAddressOne);

            _peerPool.AddPeer(peerOne);

            var ipAddressTwo = "192.168.1.2:1680";
            var channelTwo   = new Channel(ipAddressTwo, ChannelCredentials.Insecure);
            var peerTwo      = new GrpcPeer(channelTwo, new PeerService.PeerServiceClient(channelTwo),
                                            "0624dcd0afc20d015e328666d8d25f3f28b13ccd9744eb6b153e4a69709aab390",
                                            ipAddressTwo);

            _peerPool.AddPeer(peerTwo);

            var response = await DeleteResponseAsObjectAsync <bool>($"/api/net/peer?address={ipAddressOne}");

            response.ShouldBeTrue();

            var peers = await GetResponseAsObjectAsync <List <string> >("/api/net/peers");

            peers.Count.ShouldBe(1);
            peers.ShouldContain((peer) => peer.IsIn(ipAddressTwo));
        }
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var services = context.Services;
            var peerList = new List <IPeer>();

            for (int i = 0; i < 3; i++)
            {
                var peer = new GrpcPeer(null, null, $"bp{i + 1}-pubkey", $"127.0.0.1:68{i + 1}0");
                peerList.Add(peer);
            }

            services.AddTransient(o =>
            {
                var mockService = new Mock <IPeerPool>();
                mockService.Setup(m => m.FindPeerByPublicKey(It.Is <string>(s => s.Length > 0)))
                .Returns(peerList[2]);
                mockService.Setup(m => m.GetPeers(It.IsAny <bool>()))
                .Returns(peerList);
                return(mockService.Object);
            });

            services.AddTransient(o =>
            {
                var mockService = new Mock <IDPoSInformationProvider>();
                mockService.Setup(m => m.GetCurrentMiners(It.IsAny <ChainContext>()))
                .Returns(async() =>
                         await Task.FromResult(new [] {
                    "bp1-pubkey",
                    "bp2-pubkey",
                    "bp3-pubkey"
                }));
                return(mockService.Object);
            });
        }
Esempio n. 7
0
        public static GrpcPeer CreatePeerWithInfo(string ip, PeerConnectionInfo info)
        {
            AElfPeerEndpointHelper.TryParse(ip, out var endpoint);
            var peer = new GrpcPeer(new GrpcClient(CreateMockChannel(), null), endpoint, info);

            peer.InboundSessionId = new byte[] { 0, 1, 2 };
            return(peer);
        }
Esempio n. 8
0
        public static GrpcPeer CreatePeerWithClient(string ip, string pubkey, PeerService.PeerServiceClient client)
        {
            var peer = new GrpcPeer(new GrpcClient(CreateMockChannel(), client), IpEndPointHelper.Parse(ip), new PeerConnectionInfo {
                Pubkey = pubkey, SessionId = new byte[] { 0, 1, 2 }
            });

            peer.InboundSessionId = new byte[] { 0, 1, 2 };
            return(peer);
        }
Esempio n. 9
0
        private void FireConnectionEvent(GrpcPeer peer)
        {
            var nodeInfo = new NodeInfo {
                Endpoint = peer.RemoteEndpoint.ToString(), Pubkey = peer.Info.Pubkey.ToByteString()
            };
            var bestChainHeader = peer.LastReceivedHandshake.HandshakeData.BestChainHead;

            _ = EventBus.PublishAsync(new PeerConnectedEventData(nodeInfo, bestChainHeader));
        }
Esempio n. 10
0
        private void FireConnectionEvent(GrpcPeer peer)
        {
            var nodeInfo = new NodeInfo {
                Endpoint = peer.RemoteEndpoint.ToString(), Pubkey = peer.Info.Pubkey.ToByteString()
            };
            var bestChainHash   = peer.CurrentBlockHash;
            var bestChainHeight = peer.CurrentBlockHeight;

            _ = EventBus.PublishAsync(new PeerConnectedEventData(nodeInfo, bestChainHash, bestChainHeight));
        }
Esempio n. 11
0
        public async Task RequestBlockAsync_Failed()
        {
            _grpcPeer = GrpcTestPeerHelpers.CreateNewPeer("127.0.0.1:3000", false);
            _pool.TryAddPeer(_grpcPeer);

            var blockHeader = await _blockchainService.GetBestChainLastBlockHeaderAsync();

            var block = await _grpcPeer.GetBlockByHashAsync(blockHeader.GetHash());

            block.ShouldBeNull();
        }
Esempio n. 12
0
        public GrpcPeerTests()
        {
            _blockchainService = GetRequiredService <IBlockchainService>();
            _networkServer     = GetRequiredService <IAElfNetworkServer>();
            _eventBus          = GetRequiredService <ILocalEventBus>();
            _osTestHelper      = GetRequiredService <OSTestHelper>();
            _pool = GetRequiredService <IPeerPool>();

            _grpcPeer = GrpcTestPeerHelpers.CreateNewPeer();
            _pool.TryAddPeer(_grpcPeer);
        }
Esempio n. 13
0
        public GrpcPeerTests()
        {
            _blockchainService = GetRequiredService<IBlockchainService>();
            _networkServer = GetRequiredService<IAElfNetworkServer>();
            _pool = GetRequiredService<IPeerPool>();

            _grpcPeer = GrpcTestPeerHelpers.CreateNewPeer();
            _grpcPeer.IsConnected = true;

            //_nonInterceptedPeer = GrpcTestPeerHelpers.CreateNewPeer("127.0.0.1:2000", false);
            //_nonInterceptedPeer.IsConnected = true;
            _nonInterceptedPeer = MockServiceClient("127.0.0.1:2000");

            _pool.TryAddPeer(_grpcPeer);
        }
        public async Task Calling_DisposedPeer_ThrowsUnrecoverableNEtException()
        {
            await _networkServer.StartAsync();

            Channel channel = new Channel("localhost", 2001, ChannelCredentials.Insecure);

            PeerService.PeerServiceClient peerClient = new PeerService.PeerServiceClient(channel);

            GrpcClient grpcClient = new GrpcClient(channel, peerClient);

            AElfPeerEndpointHelper.TryParse("127.0.0.1:2001", out var endpoint);

            GrpcPeer peer = new GrpcPeer(grpcClient, endpoint, new PeerConnectionInfo
            {
                SessionId = new byte[] { 1, 2, 3 }
            });

            await peer.DisconnectAsync(false);

            var exHealthCheck = await Assert.ThrowsAsync <NetworkException>(async() => await peer.CheckHealthAsync());

            exHealthCheck.ExceptionType.ShouldBe(NetworkExceptionType.Unrecoverable);

            var exGetBlocks = await Assert.ThrowsAsync <NetworkException>(
                async() => await peer.GetBlocksAsync(Hash.FromString("blockHash"), 10));

            exGetBlocks.ExceptionType.ShouldBe(NetworkExceptionType.Unrecoverable);

            var exGetBlock = await Assert.ThrowsAsync <NetworkException>(
                async() => await peer.GetBlockByHashAsync(Hash.FromString("blockHash")));

            exGetBlock.ExceptionType.ShouldBe(NetworkExceptionType.Unrecoverable);

            var exGetNodes = await Assert.ThrowsAsync <NetworkException>(
                async() => await peer.GetNodesAsync());

            exGetNodes.ExceptionType.ShouldBe(NetworkExceptionType.Unrecoverable);

            await _networkServer.StopAsync();
        }
Esempio n. 15
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);
        }
Esempio n. 16
0
 public void AddDialedPeer(GrpcPeer peer)
 {
     DialedPeers.Add(peer);
 }