예제 #1
0
        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);
        }
예제 #2
0
        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++;
            }
        }