diff --git a/voltaire_bundler/bundle/exceptions.py b/voltaire_bundler/bundle/exceptions.py index 797cb3e..7e915c2 100644 --- a/voltaire_bundler/bundle/exceptions.py +++ b/voltaire_bundler/bundle/exceptions.py @@ -49,3 +49,8 @@ class MethodNotFoundException(Exception): @dataclass class UserOpFoundException(Exception): user_op_by_hash_result: dict + + +@dataclass +class UserOpReceiptFoundException(Exception): + user_op_receipt_result: dict diff --git a/voltaire_bundler/execution_endpoint.py b/voltaire_bundler/execution_endpoint.py index 8ac44c5..d7126aa 100644 --- a/voltaire_bundler/execution_endpoint.py +++ b/voltaire_bundler/execution_endpoint.py @@ -7,7 +7,7 @@ from voltaire_bundler.bundle.exceptions import \ ExecutionException, OtherJsonRpcErrorCode, OtherJsonRpcErrorException, \ - UserOpFoundException, ValidationException, ValidationExceptionCode + UserOpFoundException, UserOpReceiptFoundException, ValidationException, ValidationExceptionCode from voltaire_bundler.cli_manager import ConditionalRpc from voltaire_bundler.event_bus_manager.endpoint import Client, Endpoint from voltaire_bundler.typing import Address @@ -408,23 +408,33 @@ async def _event_rpc_getUserOperationReceipt( ValidationExceptionCode.InvalidFields, "Missing/invalid userOpHash", ) + user_operation_receipt_info_json_ops = [] if self.user_operation_handler_v6 is not None: - user_operation_receipt_info_json = ( - await self.user_operation_handler_v6.get_user_operation_receipt_rpc( + user_operation_receipt_info_json_ops.append(asyncio.create_task( + self.user_operation_handler_v6.get_user_operation_receipt_rpc( user_operation_hash, LocalMempoolManagerV6.entrypoint, - ) + )) ) - if user_operation_receipt_info_json is not None: - return user_operation_receipt_info_json - user_operation_receipt_info_json = ( - await self.user_operation_handler_v7.get_user_operation_receipt_rpc( - user_operation_hash, - LocalMempoolManagerV7.entrypoint, - ) - ) - return user_operation_receipt_info_json + user_operation_receipt_info_json_ops.append(asyncio.create_task( + self.user_operation_handler_v7.get_user_operation_receipt_rpc( + user_operation_hash, + LocalMempoolManagerV7.entrypoint, + )) + ) + done, _ = await asyncio.wait( + user_operation_receipt_info_json_ops, + return_when=asyncio.FIRST_EXCEPTION + ) + + for res in done: + excep = res.exception() + if isinstance(excep, UserOpReceiptFoundException): + return excep.user_op_receipt_result + elif excep is not None: + raise excep + return None async def _event_debug_bundler_sendBundleNow(self, _) -> str: await self.bundle_manager.send_next_bundle() diff --git a/voltaire_bundler/user_operation/user_operation_handler.py b/voltaire_bundler/user_operation/user_operation_handler.py index ecc61dc..4d3af7c 100644 --- a/voltaire_bundler/user_operation/user_operation_handler.py +++ b/voltaire_bundler/user_operation/user_operation_handler.py @@ -3,6 +3,7 @@ import logging from eth_abi import encode, decode +from voltaire_bundler.bundle.exceptions import UserOpReceiptFoundException from voltaire_bundler.typing import Address from voltaire_bundler.utils.eth_client_utils import \ get_latest_block_info, send_rpc_request_to_eth_client @@ -118,8 +119,7 @@ async def get_user_operation_receipt_rpc( "logs": user_operation_receipt_info.logs, "receipt": receipt_info_json, } - - return user_operation_receipt_rpc_json + raise UserOpReceiptFoundException(user_operation_receipt_rpc_json) async def get_user_operation_event_log_info( self, user_operation_hash: str, entrypoint: str