private FastBlocksBatch CreateResponse(LatencySyncPeerMock syncPeer) { if (!_pendingResponses.ContainsKey(syncPeer)) { TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} WAKES UP"); syncPeer.IsReported = false; return(null); } FastBlocksBatch responseBatch = _pendingResponses[syncPeer]; IBlockTree tree = _peerTrees[syncPeer]; _pendingResponses.Remove(syncPeer); if (_timingOut.Contains(syncPeer)) { TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} TIMED OUT"); // timeout punishment syncPeer.BusyUntil = _time + 5000; syncPeer.IsReported = true; return(responseBatch); } TestContext.WriteLine($"{_time,6} |SYNC PEER {syncPeer.Node:s} RESPONDING TO {responseBatch}"); switch (responseBatch.BatchType) { case FastBlocksBatchType.None: break; case FastBlocksBatchType.Headers: var headersSyncBatch = responseBatch.Headers; PrepareHeadersResponse(headersSyncBatch, syncPeer, tree); break; case FastBlocksBatchType.Bodies: var bodiesSyncBatch = responseBatch.Bodies; PrepareBodiesResponse(bodiesSyncBatch, syncPeer, tree); break; case FastBlocksBatchType.Receipts: var receiptSyncBatch = responseBatch.Receipts; PrepareReceiptsResponse(receiptSyncBatch, syncPeer, tree); break; default: throw new ArgumentOutOfRangeException(); } return(responseBatch); }
private void RunFeed(int timeLimit = 5000, int restartEvery = 100000) { _feed.StartNewRound(); while (true) { if (_scheduledActions.ContainsKey(_time)) { _scheduledActions[_time].Invoke(); } if (_time % restartEvery == 0) { ResetAndStartNewRound(); } if (_time > timeLimit) { TestContext.WriteLine($"TIMEOUT AT {_time}"); break; } if (_pendingResponses.Count < _syncPeers.Count(p => !p.IsReported)) { FastBlocksBatch batch = _feed.PrepareRequest(); if (batch == null && _pendingResponses.Count == 0) { TestContext.WriteLine($"STOP - NULL BATCH AND NO PENDING"); break; } if (batch != null) { bool wasAssigned = false; foreach (LatencySyncPeerMock syncPeer in _syncPeers) { if (syncPeer.BusyUntil == null && _peerTrees[syncPeer].Head.Number >= (batch.MinNumber ?? 0)) { syncPeer.BusyUntil = _time + syncPeer.Latency; if (_timingOut.Contains(syncPeer)) { syncPeer.BusyUntil = _time + _timeoutTime; } batch.Allocation = new SyncPeerAllocation(new PeerInfo(syncPeer), "test"); _pendingResponses.Add(syncPeer, batch); TestContext.WriteLine($"{_time,6} |SENDING {batch} REQUEST TO {syncPeer.Node:s}"); wasAssigned = true; break; } } if (!wasAssigned) { // TestContext.WriteLine($"{_time,6} | {batch} WAS NOT ASSIGNED"); _feed.HandleResponse(batch); } } } foreach (LatencySyncPeerMock intSyncPeerMock in _syncPeers) { if (intSyncPeerMock.BusyUntil == _time) { intSyncPeerMock.BusyUntil = null; FastBlocksBatch responseBatch = CreateResponse(intSyncPeerMock); if (responseBatch != null) { _feed.HandleResponse(responseBatch); } } } _time++; } }