Ejemplo n.º 1
0
        public void DialPeerAsync_HandshakeDataProblem_ShouldThrowException()
        {
            IpEndPointHelper.TryParse(NetworkTestConstants.HandshakeWithNetExceptionIp, out var endpoint);
            _networkServer.ConnectAsync(endpoint).ShouldThrow <Exception>();

            _peerPool.PeerCount.ShouldBe(0);
        }
Ejemplo 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);
        }
Ejemplo n.º 3
0
        public void DialPeerAsync_HandshakeError_ShouldThrowException()
        {
            IpEndPointHelper.TryParse(NetworkTestConstants.BadHandshakeIp, out var endpoint);
            _networkServer.ConnectAsync(endpoint).ShouldThrow <NetworkException>();

            _peerPool.PeerCount.ShouldBe(0);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Connects to the boot nodes provided in the network options.
        /// </summary>
        private async Task DialBootNodesAsync()
        {
            if (NetworkOptions.BootNodes == null || !NetworkOptions.BootNodes.Any())
            {
                Logger.LogWarning("Boot nodes list is empty.");
                return;
            }

            var taskList = NetworkOptions.BootNodes
                           .Select(async node =>
            {
                bool dialed = false;

                if (!IpEndPointHelper.TryParse(node, out IPEndPoint endpoint))
                {
                    return;
                }

                try
                {
                    dialed = await _connectionService.ConnectAsync(endpoint);
                }
                catch (Exception e)
                {
                    Logger.LogError(e, $"Connect peer failed.{node}");
                }

                if (!dialed)
                {
                    await _connectionService.SchedulePeerReconnection(endpoint);
                }
            }).ToList();

            await Task.WhenAll(taskList.ToArray <Task>());
        }
        public async Task DialPeer_Test()
        {
            var endpoint = IpEndPointHelper.Parse("127.0.0.1:2000");
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldBeNull();
        }
Ejemplo n.º 6
0
        public async Task DialPeerAsync_ShouldThrowException()
        {
            IpEndPointHelper.TryParse(NetworkTestConstants.DialExceptionIpEndpoint, out var endpoint);
            _networkServer.ConnectAsync(endpoint).ShouldThrow <Exception>();

            _peerPool.PeerCount.ShouldBe(0);
        }
Ejemplo n.º 7
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);
        }
Ejemplo 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);
        }
Ejemplo n.º 9
0
        private static IPEndPoint ParseEndPoint(string ipEndpoint)
        {
            if (!IpEndPointHelper.TryParse(ipEndpoint, out var endpoint))
            {
                throw new Exception($"Endpoint {ipEndpoint} could not be parsed.");
            }

            return(endpoint);
        }
Ejemplo n.º 10
0
        public async Task <bool> AddPeerAsync(string address)
        {
            if (IpEndPointHelper.TryParse(address, out IPEndPoint endpoint))
            {
                return(await _networkServer.ConnectAsync(endpoint));
            }

            return(false);
        }
Ejemplo n.º 11
0
        public async Task AddPeerAsync_CannotAddBlacklistedPeer()
        {
            var endpoint = IpEndPointHelper.Parse("127.0.0.1:5000");
            var address  = endpoint.Address;

            _blackListProvider.AddIpToBlackList(address);

            (await _networkService.AddPeerAsync(endpoint.ToString())).ShouldBeFalse();
        }
Ejemplo n.º 12
0
        public async Task DialPeerAsync_GoodPeer_ShouldBeInPool()
        {
            IpEndPointHelper.TryParse(NetworkTestConstants.GoodPeerEndpoint, out var endpoint);

            // two different hosts with the same pubkey.
            var added = await _networkServer.ConnectAsync(endpoint);

            added.ShouldBeTrue();
            _peerPool.FindPeerByEndpoint(endpoint).ShouldNotBeNull();
        }
Ejemplo n.º 13
0
        public async Task DialPeer_Test()
        {
            var endpoint = IpEndPointHelper.Parse("127.0.0.1:2000");
            var grpcPeer = await _peerDialer.DialPeerAsync(endpoint);

            grpcPeer.ShouldNotBeNull();

            var peersHandshake = _networkTestContext.GeneratedHandshakes[endpoint.Address.ToString()];

            grpcPeer.CurrentBlockHash.ShouldBe(peersHandshake.HandshakeData.BestChainHash);
            grpcPeer.CurrentBlockHeight.ShouldBe(peersHandshake.HandshakeData.BestChainHeight);
            grpcPeer.LastKnownLibHeight.ShouldBe(peersHandshake.HandshakeData.LastIrreversibleBlockHeight);
        }
Ejemplo n.º 14
0
        public async Task RemovePeerByPubkeyAsync_BlackListTest()
        {
            var peerPubKey = "blacklistpeer";
            var endpoint   = IpEndPointHelper.Parse("127.0.0.1:5000");
            var address    = endpoint.Address;

            await _networkService.RemovePeerByPubkeyAsync(peerPubKey);

            _blackListProvider.IsIpBlackListed(address).ShouldBeFalse();

            await _networkService.RemovePeerByPubkeyAsync(peerPubKey, true);

            _blackListProvider.IsIpBlackListed(address).ShouldBeTrue();
        }
Ejemplo n.º 15
0
        public async Task DialBackPeer_Test()
        {
            var endpoint  = IpEndPointHelper.Parse("127.0.0.1:2000");
            var handshake = await _handshakeProvider.GetHandshakeAsync();

            var grpcPeer = await _peerDialer.DialBackPeerAsync(endpoint, handshake);

            grpcPeer.ShouldNotBeNull();
            grpcPeer.CurrentBlockHash.ShouldBe(handshake.HandshakeData.BestChainHash);
            grpcPeer.CurrentBlockHeight.ShouldBe(handshake.HandshakeData.BestChainHeight);
            grpcPeer.LastKnownLibHeight.ShouldBe(handshake.HandshakeData.LastIrreversibleBlockHeight);
            grpcPeer.Info.Pubkey.ShouldBe(handshake.HandshakeData.Pubkey.ToHex());
            grpcPeer.Info.ProtocolVersion.ShouldBe(handshake.HandshakeData.Version);
        }
Ejemplo n.º 16
0
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var publicKeys = new[]
            {
                OSConsensusDPosTestConstants.Bp1PublicKey,
                OSConsensusDPosTestConstants.Bp2PublicKey,
                OSConsensusDPosTestConstants.Bp3PublicKey
            };

            var services = context.Services;

            services.AddSingleton <IPeerPool, PeerPool>();
            var peerList = new List <IPeer>();

            for (var i = 0; i < 3; i++)
            {
                var connectionInfo = new PeerConnectionInfo
                {
                    Pubkey          = publicKeys[i],
                    ProtocolVersion = KernelConstants.ProtocolVersion,
                    ConnectionTime  = TimestampHelper.GetUtcNow(),
                    IsInbound       = true
                };
                peerList.Add(new GrpcPeer(new GrpcClient(null, null), IpEndPointHelper.Parse($"127.0.0.1:68{i + 1}0"), connectionInfo));
            }

            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 <IAEDPoSInformationProvider>();
                mockService.Setup(m => m.GetCurrentMinerList(It.IsAny <ChainContext>()))
                .Returns(async() =>
                         await Task.FromResult(publicKeys));
                return(mockService.Object);
            });
        }
Ejemplo n.º 17
0
        private GrpcPeer CreateNewPeer()
        {
            var pubkey         = "048f5ced21f8d687cb9ade1c22dc0e183b05f87124c82073f5d82a09b139cc466efbfb6f28494d0a9d7366fcb769fe5436cfb7b5d322a2b0f69c4bcb1c33ac24ad";
            var ipAddress      = "127.0.0.1:888";
            var remoteEndpoint = IpEndPointHelper.Parse(ipAddress);
            var channel        = new Channel(ipAddress, ChannelCredentials.Insecure);
            var client         = new PeerService.PeerServiceClient(channel);

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

            return(new GrpcPeer(new GrpcClient(channel, client), remoteEndpoint, connectionInfo));
        }
Ejemplo n.º 18
0
        private IPeer BuildPeer(string ipAddress, string pubkey, Timestamp connectionTime, bool isInbound)
        {
            var connectionInfo = new PeerConnectionInfo
            {
                Pubkey          = pubkey,
                ProtocolVersion = KernelConstants.ProtocolVersion,
                ConnectionTime  = connectionTime,
                IsInbound       = isInbound
            };

            var peerMock = new Mock <IPeer>();

            peerMock.SetupGet(p => p.Info).Returns(connectionInfo);
            peerMock.SetupGet(p => p.RemoteEndpoint).Returns(IpEndPointHelper.Parse(ipAddress));
            peerMock.Setup(p => p.GetRequestMetrics()).Returns(new Dictionary <string, List <RequestMetric> >());

            return(peerMock.Object);
        }
Ejemplo n.º 19
0
        public async Task <bool> RemovePeerAsync(string address)
        {
            if (!IpEndPointHelper.TryParse(address, out IPEndPoint endpoint))
            {
                return(false);
            }

            var peer = _peerPool.FindPeerByEndpoint(endpoint);

            if (peer == null)
            {
                Logger.LogWarning($"Could not find peer at address {address}");
                return(false);
            }

            await _networkServer.DisconnectAsync(peer);

            return(true);
        }
Ejemplo n.º 20
0
        public async Task DialPeerAsync_GoodPeer_ShouldLaunchConnectionEvent()
        {
            PeerConnectedEventData eventData = null;

            _eventBus.Subscribe <PeerConnectedEventData>(e =>
            {
                eventData = e;
                return(Task.CompletedTask);
            });

            // two different hosts with the same pubkey.
            IpEndPointHelper.TryParse(NetworkTestConstants.GoodPeerEndpoint, out var endpoint);
            var added = await _networkServer.ConnectAsync(endpoint);

            added.ShouldBeTrue();
            _peerPool.FindPeerByEndpoint(endpoint).ShouldNotBeNull();

            eventData.ShouldNotBeNull();
        }
Ejemplo n.º 21
0
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var pool    = context.ServiceProvider.GetRequiredService <IPeerPool>();
            var channel = new Channel(NetworkTestConstants.FakeIpEndpoint, ChannelCredentials.Insecure);

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

            if (!IpEndPointHelper.TryParse(NetworkTestConstants.FakeIpEndpoint, out var peerEndpoint))
            {
                throw new Exception($"Ip {NetworkTestConstants.FakeIpEndpoint} is invalid.");
            }

            pool.TryAddPeer(new GrpcPeer(new GrpcClient(channel, new PeerService.PeerServiceClient(channel)), peerEndpoint, connectionInfo));
        }
Ejemplo n.º 22
0
        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);
            GrpcPeer   peer       = new GrpcPeer(grpcClient, IpEndPointHelper.Parse("127.0.0.1:2001"), 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();
        }
Ejemplo n.º 23
0
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddSingleton <INetworkService, NetworkService>();

            Mock <IPeerPool> peerPoolMock = new Mock <IPeerPool>();
            var p3 = new Mock <IPeer>();

            p3.Setup(p => p.Info).Returns(new PeerConnectionInfo {
                Pubkey = "pBestPeer"
            });

            var osTestHelper = context.Services.GetServiceLazy <OSTestHelper>();

            peerPoolMock.Setup(p => p.FindPeerByPublicKey(It.Is <string>(adr => adr == "blacklistpeer")))
            .Returns <string>(adr =>
            {
                var endpoint = IpEndPointHelper.Parse("127.0.0.1:5000");

                var peer = new Mock <IPeer>();
                peer.Setup(p => p.RemoteEndpoint).Returns(endpoint);
                peer.Setup(p => p.Info).Returns(new PeerConnectionInfo {
                    Pubkey = "blacklistpeer", ConnectionTime = TimestampHelper.GetUtcNow()
                });
                return(peer.Object);
            });

            peerPoolMock.Setup(p => p.FindPeerByPublicKey(It.Is <string>(adr => adr == "p1")))
            .Returns <string>(adr =>
            {
                var p1 = new Mock <IPeer>();

                var blockWithTransactions = osTestHelper.Value.GenerateBlockWithTransactions(Hash.Empty, 10);

                p1.Setup(p => p.Info).Returns(new PeerConnectionInfo
                {
                    Pubkey = "p1", ConnectionTime = TimestampHelper.GetUtcNow()
                });
                p1.Setup(p => p.GetBlocksAsync(It.IsAny <Hash>(), It.IsAny <int>()))
                .Returns <Hash, int>((h, cnt) => Task.FromResult(new List <BlockWithTransactions>()));

                p1.Setup(p => p.GetBlockByHashAsync(It.Is <Hash>(h => h == Hash.FromString("bHash1"))))
                .Returns <Hash>(h => Task.FromResult(blockWithTransactions));

                return(p1.Object);
            });

            peerPoolMock.Setup(p => p.FindPeerByPublicKey(It.Is <string>(adr => adr == "failed_peer")))
            .Returns <string>(adr =>
            {
                var p1 = new Mock <IPeer>();
                p1.Setup(p => p.Info).Returns(new PeerConnectionInfo
                {
                    Pubkey = "p1", ConnectionTime = TimestampHelper.GetUtcNow()
                });
                p1.Setup(p => p.GetBlockByHashAsync(It.IsAny <Hash>())).Throws(new NetworkException());
                p1.Setup(p => p.GetBlocksAsync(It.IsAny <Hash>(), It.IsAny <int>())).Throws(new NetworkException());
                return(p1.Object);
            });

            peerPoolMock.Setup(p => p.GetPeers(It.IsAny <bool>()))
            .Returns <bool>(includeFailing =>
            {
                List <IPeer> peers = new List <IPeer>();

                var blockWithTransactions = osTestHelper.Value.GenerateBlockWithTransactions(Hash.Empty, 10);

                var p2 = new Mock <IPeer>();
                p2.Setup(p => p.RemoteEndpoint).Returns(new IPEndPoint(100, 100));
                p2.Setup(p => p.Info).Returns(new PeerConnectionInfo
                {
                    Pubkey = "p2", ConnectionTime = TimestampHelper.GetUtcNow()
                });
                p2.Setup(p => p.GetBlocksAsync(It.Is <Hash>(h => h == Hash.FromString("block")), It.IsAny <int>()))
                .Returns <Hash, int>((h, cnt) => Task.FromResult(new List <BlockWithTransactions> {
                    blockWithTransactions
                }));
                p2.Setup(p => p.GetBlockByHashAsync(It.Is <Hash>(h => h == Hash.FromString("block"))))
                .Returns <Hash>(h => Task.FromResult(blockWithTransactions));
                p2.Setup(m => m.GetNodesAsync(It.IsAny <int>()))
                .Returns(Task.FromResult(new NodeList
                {
                    Nodes =
                    {
                        new NodeInfo
                        {
                            Endpoint = "http://127.0.0.1:8000",
                            Pubkey   = ByteString.CopyFromUtf8("p2")
                        }
                    }
                }));
                peers.Add(p2.Object);

                p3.Setup(p => p.RemoteEndpoint).Returns(new IPEndPoint(100, 100));
                p3.Setup(p => p.Info).Returns(new PeerConnectionInfo
                {
                    Pubkey = "p3", ConnectionTime = TimestampHelper.GetUtcNow()
                });
                p3.Setup(p => p.GetBlocksAsync(It.Is <Hash>(h => h == Hash.FromString("blocks")), It.IsAny <int>()))
                .Returns <Hash, int>((h, cnt) => Task.FromResult(new List <BlockWithTransactions> {
                    blockWithTransactions, blockWithTransactions
                }));
                p3.Setup(p => p.GetBlockByHashAsync(It.Is <Hash>(h => h == Hash.FromString("bHash2"))))
                .Returns <Hash>(h => Task.FromResult(blockWithTransactions));
                peers.Add(p3.Object);

                var exceptionOnBcast = new Mock <IPeer>();
                exceptionOnBcast.Setup(p => p.RemoteEndpoint).Returns(new IPEndPoint(100, 100));
                exceptionOnBcast.Setup(p => p.Info).Returns(new PeerConnectionInfo
                {
                    Pubkey = "exceptionOnBcast", ConnectionTime = TimestampHelper.GetUtcNow()
                });

                peers.Add(exceptionOnBcast.Object);

                if (includeFailing)
                {
                    var failingPeer = new Mock <IPeer>();
                    failingPeer.Setup(p => p.RemoteEndpoint).Returns(new IPEndPoint(100, 100));
                    failingPeer.Setup(p => p.Info).Returns(new PeerConnectionInfo
                    {
                        Pubkey = "failing", ConnectionTime = TimestampHelper.GetUtcNow()
                    });
                    peers.Add(failingPeer.Object);
                }

                return(peers);
            });

            context.Services.AddSingleton <IPeerPool>(o => peerPoolMock.Object);

            context.Services.AddTransient(o => Mock.Of <IBroadcastPrivilegedPubkeyListProvider>());
        }
Ejemplo n.º 24
0
        internal async Task DoReconnectionJobAsync()
        {
            await _networkService.SendHealthChecksAsync();

            var peersToConnect = _reconnectionService.GetPeersReadyForReconnection(TimestampHelper.GetUtcNow());

            if (peersToConnect.Count <= 0)
            {
                Logger.LogDebug("No peers to reconnect.");
                return;
            }

            foreach (var peerToConnect in peersToConnect)
            {
                string peerEndpoint = peerToConnect.Endpoint;

                // check that we haven't already reconnected to this node
                if (_peerPool.FindPeerByEndpoint(IpEndPointHelper.Parse(peerEndpoint)) != null)
                {
                    Logger.LogDebug($"Peer {peerEndpoint} already in the pool, no need to reconnect.");

                    if (!_reconnectionService.CancelReconnection(peerEndpoint))
                    {
                        Logger.LogDebug($"Could not find to {peerEndpoint}.");
                    }

                    continue;
                }

                Logger.LogDebug($"Starting reconnection to {peerToConnect.Endpoint}.");

                var connected = false;

                try
                {
                    connected = await _networkService.AddPeerAsync(peerEndpoint);
                }
                catch (Exception ex)
                {
                    // todo consider different handling of the exception in dialer
                    // down the stack the AddPeerAsync rethrows any exception,
                    // in order to continue this job, Exception has to be catched for now.
                    Logger.LogError(ex, $"Could not re-connect to {peerEndpoint}.");
                }

                if (connected)
                {
                    Logger.LogDebug($"Reconnection to {peerEndpoint} succeeded.");

                    if (!_reconnectionService.CancelReconnection(peerEndpoint))
                    {
                        Logger.LogDebug($"Could not find {peerEndpoint}.");
                    }
                }
                else
                {
                    peerToConnect.NextAttempt =
                        TimestampHelper.GetUtcNow().AddMilliseconds(_networkOptions.PeerReconnectionPeriod);

                    Logger.LogDebug($"Could not connect to {peerEndpoint}, next attempt {peerToConnect.NextAttempt}.");
                }
            }
        }
        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);
        }