Example #1
0
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
Example #2
0
    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