private Block HandleBlockReception(byte[] serializedBlock, Peer peer) { try { Block block = Block.Parser.ParseFrom(serializedBlock); byte[] blockHash = block.GetHashBytes(); if (_lastBlocksReceived.Contains(blockHash)) { _logger.Warn("Block already in network cache"); return(null); } _lastBlocksReceived.Enqueue(blockHash); peer.StopBlockTimer(block); return(block); } catch (Exception e) { _logger?.Error(e, "Error while handling block reception"); } return(null); }
public void Test2() { BoundedByteArrayQueue bq = new BoundedByteArrayQueue(2); byte[] byte01 = ByteArrayHelpers.RandomFill(10); bq.Enqueue(byte01); byte[] byte02 = ByteArrayHelpers.RandomFill(10); bq.Enqueue(byte02); Assert.True(bq.Contains(byte01)); }
private void HandleNewTransaction(Message msg) { try { Transaction tx = Transaction.Parser.ParseFrom(msg.Payload); byte[] txHash = tx.GetHashBytes(); if (_lastTxReceived.Contains(txHash)) { return; } _lastTxReceived.Enqueue(txHash); MessageHub.Instance.Publish(new TxReceived(tx)); } catch (Exception e) { _logger?.Error(e, "Error while handling new transaction reception."); } }
public NetworkManager(IPeerManager peerManager, IBlockSynchronizer blockSynchronizer, INodeService nodeService, ILogger logger) { _incomingJobs = new BlockingPriorityQueue <PeerMessageReceivedArgs>(); _peers = new List <IPeer>(); _peerManager = peerManager; _logger = logger; _blockSynchronizer = blockSynchronizer; _nodeService = nodeService; peerManager.PeerEvent += OnPeerAdded; MessageHub.Instance.Subscribe <TransactionAddedToPool>(inTx => { if (inTx?.Transaction == null) { _logger?.Warn("[event] Transaction null."); return; } var txHash = inTx.Transaction.GetHashBytes(); if (txHash != null) { _lastTxReceived.Enqueue(txHash); } if (_peers == null || !_peers.Any()) { return; } BroadcastMessage(AElfProtocolMsgType.NewTransaction, inTx.Transaction.Serialize()); }); MessageHub.Instance.Subscribe <BlockMined>(inBlock => { if (inBlock?.Block == null) { _logger?.Warn("[event] Block null."); return; } byte[] blockHash = inBlock.Block.GetHash().DumpByteArray(); if (blockHash != null) { _lastBlocksReceived.Enqueue(blockHash); } AnnounceBlock((Block)inBlock.Block); _logger?.Info($"Block produced, announcing {blockHash.ToHex()} to peers ({string.Join("|", _peers)}) with " + $"{inBlock.Block.Body.TransactionsCount} txs, block height {inBlock.Block.Header.Index}."); LocalHeight++; }); MessageHub.Instance.Subscribe <BlockAccepted>(inBlock => { if (inBlock?.Block == null) { _logger?.Warn("[event] Block null."); return; } // Note - This should not happen during header this if (UnlinkableHeaderIndex != 0) { return; } IBlock acceptedBlock = inBlock.Block; LocalHeight++; var blockHash = acceptedBlock.GetHash().DumpByteArray(); var blockHeight = acceptedBlock.Header.Index; // todo TEMP if (_temp.Contains(blockHash)) { return; } _temp.Enqueue(blockHash); if (blockHash != null) { _lastBlocksReceived.Enqueue(blockHash); } _logger?.Trace($"Block accepted, announcing {blockHash.ToHex()} to peers ({string.Join("|", _peers)}), " + $"block height {acceptedBlock.Header.Index}."); lock (_syncLock) { if (CurrentSyncSource == null || !CurrentSyncSource.IsSyncingHistory) { AnnounceBlock(acceptedBlock); } if (CurrentSyncSource == null) { _logger?.Warn("Unexpected situation, executed a block but no peer is currently syncing."); } else if (!CurrentSyncSource.IsSyncing) { _logger?.Warn($"{CurrentSyncSource} is sync source but not in sync state."); } else if (CurrentSyncSource.IsSyncingHistory) { if ((int)blockHeight != CurrentSyncSource.CurrentlyRequestedHeight) { _logger?.Warn($"{CurrentSyncSource} unexpected situation, the block executed was not the exepected height."); } bool hasReqNext = CurrentSyncSource.SyncNextHistory(); if (hasReqNext) { return; } _logger?.Trace($"{CurrentSyncSource} history blocks synced, local height {LocalHeight}."); // If this peer still has announcements and the next one is the next block we need. if (CurrentSyncSource.AnyStashed) { if (CurrentSyncSource.SyncNextAnnouncement()) { _logger?.Trace($"{CurrentSyncSource} has the next block - started sync."); return; } _logger?.Warn($"{CurrentSyncSource} Failed to start announcement sync."); } } else if (CurrentSyncSource.IsSyncingAnnounced) { // we check if the hash of the accepted block is the one the sync source fetched if (!CurrentSyncSource.SyncedAnnouncement.Id.ToByteArray().BytesEqual(blockHash)) { _logger?.Warn($"Block {blockHash.ToHex()} accepted by the chain but not currently synced."); } foreach (var peer in _peers) { // Clear the announcement or any previous announcement to not request // again. peer.CleanAnnouncements((int)blockHeight); } bool hasReqNext = CurrentSyncSource.SyncNextAnnouncement(); if (hasReqNext) { return; } _logger?.Trace($"Catched up to announcements with {CurrentSyncSource}."); } var oldSyncSource = CurrentSyncSource; // At this point the current sync source either doesn't have the next announcement // or has none at all. CurrentSyncSource = null; // Try and find a peer with an anouncement that corresponds to the next block we need. foreach (var p in _peers.Where(p => p.AnyStashed && p != oldSyncSource)) { if (p.SyncNextAnnouncement()) { CurrentSyncSource = p; FireSyncStateChanged(true); _logger?.Debug($"Catching up with {p}."); return; } } if (CurrentSyncSource != null) { _logger?.Error($"The current sync source {CurrentSyncSource} is not null even though sync should be finished."); } FireSyncStateChanged(false); _logger?.Debug("Catched up all peers."); } }); MessageHub.Instance.Subscribe <UnlinkableHeader>(unlinkableHeaderMsg => { if (unlinkableHeaderMsg?.Header == null) { _logger?.Warn("[event] message or header null."); return; } // The reception of this event means that the chain has discovered // that the current block it is trying to execute (height H) is // not linkable to the block we have at H-1. // At this point we stop all current syncing activities and repetedly // download previous headers to the block we couldn't link (in other // word "his branch") until we find a linkable block (at wich point // the HeaderAccepted event should be launched. // note that when this event is called, our knowledge of the local // height doesn't mean much. lock (_syncLock) { // If this is already != 0, it means that the previous batch of // headers was not linked and that more need to be requested. if (UnlinkableHeaderIndex != 0) { // Set state with the first occurence of the unlinkable block UnlinkableHeaderIndex = (int)unlinkableHeaderMsg.Header.Index; } else { CurrentSyncSource = null; // Reset all syncing operations foreach (var peer in _peers) { peer.ResetSync(); } LocalHeight = 0; } } _logger?.Trace($"Header unlinkable, height {unlinkableHeaderMsg.Header.Index}."); // Use the peer with the highest target to request headers. IPeer target = _peers .Where(p => p.KnownHeight >= (int)unlinkableHeaderMsg.Header.Index) .OrderByDescending(p => p.KnownHeight) .FirstOrDefault(); if (target == null) { _logger?.Warn("[event] no peers to sync from."); return; } target.RequestHeaders((int)unlinkableHeaderMsg.Header.Index, DefaultHeaderRequestCount); }); MessageHub.Instance.Subscribe <HeaderAccepted>(header => { if (header?.Header == null) { _logger?.Warn("[event] message or header null."); return; } if (UnlinkableHeaderIndex != 0) { _logger?.Warn("[event] HeaderAccepted but network module not in recovery mode."); return; } if (CurrentSyncSource != null) { // todo possible sync reset _logger?.Warn("[event] current sync source is not null"); return; } lock (_syncLock) { // Local height reset LocalHeight = (int)header.Header.Index - 1; // Reset Unlinkable header state UnlinkableHeaderIndex = 0; _logger?.Trace($"[event] header accepted, height {header.Header.Index}, local height reset to {header.Header.Index - 1}."); // Use the peer with the highest target that is higher than our height. IPeer target = _peers .Where(p => p.KnownHeight > LocalHeight) .OrderByDescending(p => p.KnownHeight) .FirstOrDefault(); if (target == null) { _logger?.Warn("[event] no peers to sync from."); return; } CurrentSyncSource = target; CurrentSyncSource.SyncToHeight(LocalHeight + 1, target.KnownHeight); FireSyncStateChanged(true); } }); MessageHub.Instance.Subscribe <ChainInitialized>(inBlock => { _peerManager.Start(); Task.Run(StartProcessingIncoming).ConfigureAwait(false); }); }