public async Task BroadcastBlock_OnePeerKnowsBlock_Test() { var blockHeader = OsCoreTestHelper.CreateFakeBlockHeader(1, 2); var blockWithTransactions = new BlockWithTransactions { Header = blockHeader }; _peerPool.FindPeerByPublicKey("Pubkey0").TryAddKnownBlock(blockWithTransactions.GetHash()); await _networkService.BroadcastBlockWithTransactionsAsync(blockWithTransactions); foreach (var peer in _testContext.MockedPeers) { peer.Verify(p => p.TryAddKnownBlock(blockHeader.GetHash()), Times.Once()); } _testContext.MockedPeers[0].Verify( p => p.EnqueueBlock(blockWithTransactions, It.IsAny <Action <NetworkException> >()), Times.Never); _testContext.MockedPeers[1].Verify( p => p.EnqueueBlock(blockWithTransactions, It.IsAny <Action <NetworkException> >()), Times.Once()); _testContext.MockedPeers[2].Verify( p => p.EnqueueBlock(blockWithTransactions, It.IsAny <Action <NetworkException> >()), Times.Once()); }
public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { try { if (context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.DoHandshake))) { // a method other than DoHandshake is being called var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null && context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Ping))) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } // check that the peers session is equal to one announced in the headers if (peer != null && !peer.InboundSessionId.BytesEqual(context.GetSessionId())) { Logger.LogWarning($"Wrong session id, ({peer.InboundSessionId.ToHex()} vs {context.GetSessionId().ToHex()}) {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } } catch (Exception e) { Logger.LogError(e, "Auth interceptor error: "); throw; } return(continuation(request, context)); }
public void GetPeersByPubKey() { var pubkey = "NormalPeer"; var peerInfo = _networkService.GetPeerByPubkey(pubkey); peerInfo.ShouldNotBeNull(); var peer = _peerPool.FindPeerByPublicKey(pubkey); peerInfo.IpAddress.ShouldBe(peer.RemoteEndpoint.ToString()); peerInfo.Pubkey.ShouldBe(peer.Info.Pubkey); peerInfo.LastKnownLibHeight.ShouldBe(peer.LastKnownLibHeight); peerInfo.ProtocolVersion.ShouldBe(peer.Info.ProtocolVersion); peerInfo.ConnectionTime.ShouldBe(peer.Info.ConnectionTime.Seconds); peerInfo.ConnectionStatus.ShouldBe(peer.ConnectionStatus); peerInfo.Inbound.ShouldBe(peer.Info.IsInbound); peerInfo.SyncState.ShouldBe(peer.SyncState); peerInfo.BufferedAnnouncementsCount.ShouldBe(peer.BufferedAnnouncementsCount); peerInfo.BufferedBlocksCount.ShouldBe(peer.BufferedBlocksCount); peerInfo.BufferedTransactionsCount.ShouldBe(peer.BufferedTransactionsCount); var fakePubkey = Cryptography.CryptoHelper.GenerateKeyPair().PublicKey.ToHex(); peerInfo = _networkService.GetPeerByPubkey(fakePubkey); peerInfo.ShouldBeNull(); }
public void AddedPeer_IsFindable_ByAddressAndPubkey() { var peer = CreatePeer(); _peerPool.TryAddPeer(peer); _peerPool.PeerCount.ShouldBe(1); _peerPool.FindPeerByEndpoint(peer.RemoteEndpoint).ShouldNotBeNull(); _peerPool.FindPeerByPublicKey(peer.Info.Pubkey).ShouldNotBeNull(); }
public async Task <bool> RemovePeerByPubkeyAsync(string peerPubkey, int removalSeconds = NetworkConstants.DefaultPeerRemovalSeconds) { var peer = _peerPool.FindPeerByPublicKey(peerPubkey); if (!await TryRemovePeerAsync(peer, removalSeconds)) { Logger.LogWarning($"Remove peer failed. Peer pubkey: {peerPubkey}"); return(false); } return(true); }
public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { try { if (IsNeedAuth(context.Method)) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } // check that the peers session is equal to one announced in the headers var sessionId = context.GetSessionId(); if (!peer.InboundSessionId.BytesEqual(sessionId)) { if (peer.InboundSessionId == null) { Logger.LogWarning($"Wrong inbound session id {context.Peer}, {context.Method}"); return(Task.FromResult <TResponse>(null)); } if (sessionId == null) { Logger.LogWarning($"Wrong context session id {context.Peer}, {context.Method}, {peer}"); return(Task.FromResult <TResponse>(null)); } Logger.LogWarning( $"Unequal session id, {context.Peer} ({peer.InboundSessionId.ToHex()} vs {sessionId.ToHex()}) {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } } catch (Exception e) { Logger.LogError(e, $"Auth interceptor error {context.Peer}, {context.Method}: "); throw; } return(continuation(request, context)); }
public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { if (context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Connect))) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null && context.Method != GetFullMethodName(nameof(PeerService.PeerServiceBase.Ping))) { Logger.LogWarning($"Could not find peer {context.GetPublicKey()}"); return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}")); } return(continuation(request, context)); }
public async Task <List <Block> > GetBlocksAsync(Hash previousBlock, long previousHeight, int count, string peerPubKey = null, bool tryOthersIfFail = false) { // try get the block from the specified peer. if (!string.IsNullOrWhiteSpace(peerPubKey)) { IPeer peer = _peerPool.FindPeerByPublicKey(peerPubKey); if (peer == null) { // if the peer was specified but we can't find it // we don't try any further. Logger.LogWarning($"Specified peer was not found."); return(null); } var blocks = await RequestAsync(peer, p => p.GetBlocksAsync(previousBlock, count)); if (blocks != null && blocks.Count > 0) { return(blocks); } if (!tryOthersIfFail) { Logger.LogWarning($"{peerPubKey} does not have blocks {nameof(tryOthersIfFail)} is false."); return(null); } } // shuffle the peers that can give us the blocks var shuffledPeers = _peerPool.GetPeers() .Where(p => p.CurrentBlockHeight >= previousHeight) .OrderBy(a => Guid.NewGuid()); foreach (var peer in shuffledPeers) { var blocks = await RequestAsync(peer, p => p.GetBlocksAsync(previousBlock, count)); if (blocks != null) { return(blocks); } } return(null); }
public async Task <bool> RemovePeerByPubkeyAsync(string peerPubKey, bool blacklistPeer = false) { var peer = _peerPool.FindPeerByPublicKey(peerPubKey); if (peer == null) { Logger.LogWarning($"Could not find peer: {peerPubKey}"); return(false); } if (blacklistPeer) { _blackListedPeerProvider.AddHostToBlackList(peer.RemoteEndpoint.Host); Logger.LogDebug($"Blacklisted {peer.RemoteEndpoint.Host} ({peerPubKey})"); } await _networkServer.DisconnectAsync(peer); return(true); }
public async Task SendDiscoveryJob_NoNode_Test() { var peer = _peerPool.FindPeerByPublicKey("PeerWithNoNode"); await SendDiscoveryJobAsync(peer); var nodes = await _nodeManager.GetRandomNodesAsync(10); nodes.Nodes.Count.ShouldBe(0); }
public async Task <IBlockIndex> FindLastLastIrreversibleBlockAsync(string senderPubKey) { var senderPeer = _peerPool.FindPeerByPublicKey(senderPubKey); if (senderPeer == null) { return(null); } var orderedBlocks = senderPeer.RecentBlockHeightAndHashMappings.OrderByDescending(p => p.Key).ToList(); var chain = await _blockchainService.GetChainAsync(); var chainContext = new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight }; var pubkeyList = (await _dpoSInformationProvider.GetCurrentMinerList(chainContext)).ToList(); var peers = _peerPool.GetPeers().Where(p => pubkeyList.Contains(p.Info.Pubkey)).ToList(); var pubKey = (await _accountService.GetPublicKeyAsync()).ToHex(); if (peers.Count == 0 && !pubkeyList.Contains(pubKey)) { return(null); } foreach (var block in orderedBlocks) { var peersHadBlockAmount = peers.Where(p => { p.RecentBlockHeightAndHashMappings.TryGetValue(block.Key, out var hash); return(hash == block.Value); }).Count(); if (pubkeyList.Contains(pubKey) && _knownBlockCacheProvider.TryGetBlockByHeight(block.Key, out var blockHash) && blockHash == block.Value) { peersHadBlockAmount++; } var sureAmount = pubkeyList.Count.Mul(2).Div(3) + 1; if (peersHadBlockAmount >= sureAmount) { Logger.LogDebug($"LIB found in network layer: height {block.Key}"); return(new BlockIndex(block.Value, block.Key)); } } return(null); }
public async Task LibAnnouncementBroadcastStream_Test() { var chain = await _blockchainService.GetChainAsync(); var irreversibleBlockHeight = (int)chain.LastIrreversibleBlockHeight; var bestBlockHeight = (int)chain.BestChainHeight; var requestLibAnnouncements = new List <LibAnnouncement>(); var preBlockHash = chain.LastIrreversibleBlockHash; var preBlockHeight = irreversibleBlockHeight; for (var i = irreversibleBlockHeight + 1; i <= bestBlockHeight; i++) { var libBlock = _osTestHelper.GenerateBlock(preBlockHash, preBlockHeight); requestLibAnnouncements.Add(new LibAnnouncement { LibHeight = preBlockHeight, LibHash = preBlockHash }); preBlockHash = libBlock.GetHash(); preBlockHeight++; } var requestStream = new TestAsyncStreamReader <LibAnnouncement>(requestLibAnnouncements); var pubKey = NetworkTestConstants.FakePubkey2; Metadata metadata = new Metadata { { GrpcConstants.PubkeyMetadataKey, pubKey } }; var context = BuildServerCallContext(metadata); var result = await _serverService.LibAnnouncementBroadcastStream(requestStream, context); result.ShouldBe(new VoidReply()); var peer = _peerPool.FindPeerByPublicKey(pubKey); var lastBlock = requestLibAnnouncements.Last(); peer.LastKnownLibHash.ShouldBe(lastBlock.LibHash); peer.LastKnownLibHeight.ShouldBe(lastBlock.LibHeight); }
public async Task Connect_PeerAlreadyInPoolAndIsInvalid_Test() { var peer = CreatePeerAndAddToPeerPool(NetworkTestConstants.GoodPeerEndpoint, NetworkTestConstants.FakePubkey2); peer.IsConnected = false; peer.Info.ConnectionTime = TimestampHelper.GetUtcNow() .AddMilliseconds(-NetworkConstants.PeerConnectionTimeout - 1000); var added = await _connectionService.ConnectAsync(peer.RemoteEndpoint); added.ShouldBeTrue(); var currentPeer = _peerPool.FindPeerByPublicKey(NetworkTestConstants.FakePubkey); currentPeer.ShouldNotBeNull(); }
public override Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { if (context.Method != "/" + nameof(PeerService) + "/" + nameof(PeerService.PeerServiceBase.Connect)) { var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); if (peer == null) { return(Task.FromResult <TResponse>(null)); } context.RequestHeaders.Add(new Metadata.Entry(GrpcConsts.PeerInfoMetadataKey, $"{peer}")); } return(continuation(request, context)); }
/// <summary> /// This method is called when a peer wants to broadcast an announcement. /// </summary> public override Task <VoidReply> Announce(PeerNewBlockAnnouncement an, ServerCallContext context) { if (an?.BlockHash == null || an?.BlockTime == null) { Logger.LogError($"Received null announcement or header from {context.GetPeerInfo()}."); return(Task.FromResult(new VoidReply())); } var peerInPool = _peerPool.FindPeerByPublicKey(context.GetPublicKey()); peerInPool?.HandlerRemoteAnnounce(an); Logger.LogDebug($"Received announce {an.BlockHash} from {context.GetPeerInfo()}."); _ = EventBus.PublishAsync(new AnnouncementReceivedEventData(an, context.GetPublicKey())); return(Task.FromResult(new VoidReply())); }
public async Task RequestBlock_WillAddToPeersBlockCache_Test() { var pubKey = "SomePubKey"; Metadata metadata = new Metadata { { GrpcConstants.PubkeyMetadataKey, pubKey } }; var reqBlockCtxt = BuildServerCallContext(metadata); _peerPool.TryAddPeer(GrpcTestPeerHelpers.CreateBasicPeer("127.0.0.1:1245", pubKey)); var chain = await _blockchainService.GetChainAsync(); var reply = await _serverService.RequestBlock(new BlockRequest { Hash = chain.LongestChainHash }, reqBlockCtxt); _peerPool.FindPeerByPublicKey(reqBlockCtxt.GetPublicKey()); Assert.NotNull(reply.Block); Assert.True(reply.Block.GetHash() == chain.LongestChainHash); }
public void QueryPeers_Test() { var commonHost = "12.34.56.67"; string commonPort = "1900"; string commonEndpoint = commonHost + ":" + commonPort; var peer1 = CreatePeer(commonEndpoint); _peerPool.TryAddPeer(peer1); var peer2 = CreatePeer(commonEndpoint); _peerPool.TryAddPeer(peer2); var peer3 = CreatePeer("12.34.56.64:1900"); _peerPool.TryAddPeer(peer3); var peer4 = CreatePeer("12.34.56.61:1900", isReady: false); _peerPool.TryAddPeer(peer4); var peers = _peerPool.GetPeers(); peers.Count.ShouldBe(3); peers = _peerPool.GetPeers(true); peers.Count.ShouldBe(4); peers = _peerPool.GetPeersByHost(commonHost); peers.Count.ShouldBe(2); peers.ShouldContain(peer1); peers.ShouldContain(peer2); var peer = _peerPool.FindPeerByEndpoint(peer3.RemoteEndpoint); peer.ShouldBe(peer3); peer = _peerPool.FindPeerByPublicKey(peer3.Info.Pubkey); peer.ShouldBe(peer3); }
public async Task ProcessPeerInvalidTransaction_Test() { var peer1 = _peerPool.FindPeerByPublicKey("Peer1"); var peer3 = _peerPool.FindPeerByPublicKey("Peer3"); bool isInBlackList; for (var i = 0; i < 5; i++) { var txId = HashHelper.ComputeFrom("Tx" + i + "Peer3"); await _peerInvalidTransactionProcessingService.ProcessPeerInvalidTransactionAsync(txId); isInBlackList = _blackListedPeerProvider.IsIpBlackListed(peer3.RemoteEndpoint.Host); isInBlackList.ShouldBeFalse(); } await _peerInvalidTransactionProcessingService.ProcessPeerInvalidTransactionAsync(HashHelper.ComputeFrom("Tx" + 5 + "Peer3")); isInBlackList = _blackListedPeerProvider.IsIpBlackListed(peer3.RemoteEndpoint.Host); isInBlackList.ShouldBeTrue(); isInBlackList = _blackListedPeerProvider.IsIpBlackListed(peer1.RemoteEndpoint.Host); isInBlackList.ShouldBeFalse(); }
public PeerInfo GetPeerByPubkey(string peerPubkey) { var peer = _peerPool.FindPeerByPublicKey(peerPubkey); return(peer == null ? null : PeerInfoHelper.FromNetworkPeer(peer)); }
public GrpcPeer GetPeerByPubkey(string pubkey) { return(_peerPool.FindPeerByPublicKey(pubkey) as GrpcPeer); }