async def test_queening_queue_recovers_from_penalty_with_one_peer( event_bus, chaindb_fresh, chaindb_20, has_parallel_peasant_call): local_context = ChainContextFactory(headerdb__db=chaindb_fresh.db) remote_context = ChainContextFactory(headerdb__db=chaindb_20.db) peer_pair = LatestETHPeerPairFactory( alice_peer_context=local_context, bob_peer_context=remote_context, event_bus=event_bus, ) async with peer_pair as (connection_to_local, connection_to_remote): local_peer_pool = MockPeerPoolWithConnectedPeers( [connection_to_remote], event_bus=event_bus, ) async with run_peer_pool_event_server( event_bus, local_peer_pool, handler_type=ETHPeerPoolEventServer ), background_asyncio_service( ETHRequestServer( event_bus, TO_NETWORKING_BROADCAST_CONFIG, AsyncChainDB(chaindb_20.db), )): queue = QueeningQueue(local_peer_pool) async with background_asyncio_service(queue): queen = await asyncio.wait_for(queue.get_queen_peer(), timeout=0.01) assert queen == connection_to_remote queue.penalize_queen(connection_to_remote, delay=0.1) assert queue.queen is None with pytest.raises(asyncio.TimeoutError): # The queen should be penalized for this entire period, and # there are no alternative peers, so this call should hang: await asyncio.wait_for(queue.get_queen_peer(), timeout=0.05) if has_parallel_peasant_call: waiting_on_peasant = asyncio.ensure_future( queue.pop_fastest_peasant()) # But after waiting long enough, even with just one peer, the blocking # call should return. Whether or not there is also a waiting call looking for # a peasant. final_queen = await asyncio.wait_for(queue.get_queen_peer(), timeout=0.075) assert final_queen == connection_to_remote if has_parallel_peasant_call: waiting_on_peasant.cancel() with pytest.raises(asyncio.CancelledError): await waiting_on_peasant
def __init__( self, chain: AsyncChainAPI, db: AtomicDatabaseAPI, chain_db: BaseAsyncChainDB, peer_pool: ETHPeerPool, event_bus: EndpointAPI, metrics_registry: MetricsRegistry, checkpoint: Checkpoint = None, force_beam_block_number: BlockNumber = None, enable_backfill: bool = True, enable_state_backfill: bool = True) -> None: self.logger = get_logger('trinity.sync.beam.chain.BeamSyncer') self.metrics_registry = metrics_registry self._body_for_header_exists = body_for_header_exists(chain_db, chain) if checkpoint is None: self._launch_strategy: SyncLaunchStrategyAPI = FromGenesisLaunchStrategy(chain_db) else: self._launch_strategy = FromCheckpointLaunchStrategy( chain_db, chain, checkpoint, peer_pool, ) self._header_syncer = ETHHeaderChainSyncer( chain, chain_db, peer_pool, self._launch_strategy, ) self._header_persister = HeaderOnlyPersist( self._header_syncer, chain_db, force_beam_block_number, self._launch_strategy, ) self._backfiller = BeamStateBackfill(db, peer_pool) if enable_state_backfill: self._queen_queue: QueenTrackerAPI = self._backfiller else: self._queen_queue = QueeningQueue(peer_pool) self._state_downloader = BeamDownloader( db, peer_pool, self._queen_queue, event_bus, ) self._data_hunter = MissingDataEventHandler( self._state_downloader, event_bus, self.metrics_registry, ) self._block_importer = BeamBlockImporter( chain, db, self._state_downloader, self._backfiller, event_bus, self.metrics_registry, ) self._launchpoint_header_syncer = HeaderLaunchpointSyncer(self._header_syncer) self._body_syncer = RegularChainBodySyncer( chain, chain_db, peer_pool, self._launchpoint_header_syncer, self._block_importer, ) self._manual_header_syncer = ManualHeaderSyncer() self._fast_syncer = RigorousFastChainBodySyncer( chain, chain_db, peer_pool, self._manual_header_syncer, ) self._header_backfill = SequentialHeaderChainGapSyncer(chain, chain_db, peer_pool) self._block_backfill = BodyChainGapSyncer(chain, chain_db, peer_pool) self._chain = chain self._enable_backfill = enable_backfill self._enable_state_backfill = enable_state_backfill