async def _serve_bytecode(self, event: CollectMissingBytecode) -> None: await self._state_downloader.ensure_nodes_present( {event.bytecode_hash}, event.block_number, event.urgent, ) await self._event_bus.broadcast(MissingBytecodeResult(), event.broadcast_config())
async def request_missing_bytecode( bytecode_hash: Hash32) -> MissingBytecodeCollected: return await event_bus.request( CollectMissingBytecode( bytecode_hash, urgent, ))
async def _hang_until_bytecode_served(self, event: CollectMissingBytecode) -> None: try: await self.wait(self._serve_bytecode(event)) except OperationCancelled: await self._event_bus.broadcast( MissingBytecodeResult(is_retry_acceptable=False), event.broadcast_config(), ) raise
async def request_missing_bytecode( bytecode_hash: Hash32, block_number: BlockNumber) -> MissingBytecodeResult: if event_bus.is_any_endpoint_subscribed_to(CollectMissingBytecode): return await event_bus.request(CollectMissingBytecode( bytecode_hash, urgent, block_number, )) else: raise StateUnretrievable("No servers for CollectMissingBytecode")
async def _hang_until_bytecode_served(self, event: CollectMissingBytecode) -> None: try: await asyncio.wait_for( self._serve_bytecode(event), timeout=BLOCK_IMPORT_MISSING_STATE_TIMEOUT, ) except asyncio.CancelledError: await self._event_bus.broadcast( MissingBytecodeResult(is_retry_acceptable=False), event.broadcast_config(), ) raise except asyncio.TimeoutError: pass
async def execute_with_retries( event_bus: EndpointAPI, func: Func, params: Any, chain: Union[AsyncChainAPI, BaseAsyncBeaconChainDB]) -> None: """ If a beam sync (or anything which responds to CollectMissingAccount) is running then attempt to fetch missing data from it before giving up. """ retryable = is_retryable(func) for iteration in itertools.count(): try: return await func(*params) except MissingAccountTrieNode as exc: if not retryable: raise if iteration > MAX_RETRIES: raise Exception( f"Failed to collect all necessary state after {MAX_RETRIES} attempts" ) from exc if not event_bus.is_any_endpoint_subscribed_to( CollectMissingAccount): raise requested_header = await check_requested_block_age( chain, func, params) await event_bus.request( CollectMissingAccount( exc.missing_node_hash, exc.address_hash, exc.state_root_hash, urgent=True, block_number=requested_header.block_number, )) except MissingBytecode as exc: if not retryable: raise if iteration > MAX_RETRIES: raise Exception( f"Failed to collect all necessary state after {MAX_RETRIES} attempts" ) from exc if not event_bus.is_any_endpoint_subscribed_to( CollectMissingBytecode): raise requested_header = await check_requested_block_age( chain, func, params) await event_bus.request( CollectMissingBytecode( bytecode_hash=exc.missing_code_hash, urgent=True, block_number=requested_header.block_number, )) except MissingStorageTrieNode as exc: if not retryable: raise if iteration > MAX_RETRIES: raise Exception( f"Failed to collect all necessary state after {MAX_RETRIES} attempts" ) from exc if not event_bus.is_any_endpoint_subscribed_to( CollectMissingStorage): raise requested_header = await check_requested_block_age( chain, func, params) await event_bus.request( CollectMissingStorage( missing_node_hash=exc.missing_node_hash, storage_key=exc.requested_key, storage_root_hash=exc.storage_root_hash, account_address=exc.account_address, urgent=True, block_number=requested_header.block_number, ))
async def collect_bytecodes(event: CollectMissingBytecode): replace_missing_node(event.bytecode_hash) await event_bus.broadcast( MissingBytecodeResult(), event.broadcast_config() )
async def request_missing_bytecode(bytecode_hash: Hash32) -> None: await event_bus.request(CollectMissingBytecode(bytecode_hash, ))
async def _serve_bytecode(self, event: CollectMissingBytecode) -> None: await self._state_downloader.ensure_node_present(event.bytecode_hash) await self._event_bus.broadcast(MissingBytecodeCollected(), event.broadcast_config())