From 6eea4db8cfd3a16da89ebf5a630a732738c4a0ba Mon Sep 17 00:00:00 2001 From: fselmo Date: Tue, 30 Apr 2024 16:09:02 -0600 Subject: [PATCH] Return responses sorted by response ids in each provider case --- web3/providers/ipc.py | 9 +++++++-- web3/providers/legacy_websocket.py | 4 +++- web3/providers/persistent/async_ipc.py | 7 +++++-- web3/providers/persistent/websocket.py | 7 +++++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py index 974cb33226..1fd35e4be0 100644 --- a/web3/providers/ipc.py +++ b/web3/providers/ipc.py @@ -218,12 +218,17 @@ def make_batch_request( timeout.sleep(0) elif has_valid_json_rpc_ending(raw_response): try: - response = self.decode_rpc_response(raw_response) + response = cast( + List[RPCResponse], + self.decode_rpc_response(raw_response), + ) except JSONDecodeError: timeout.sleep(0) continue else: - return cast(List[RPCResponse], response) + # sort by response `id` since the JSON-RPC 2.0 spec doesn't + # guarantee order + return sorted(response, key=lambda resp: int(resp["id"])) else: timeout.sleep(0) continue diff --git a/web3/providers/legacy_websocket.py b/web3/providers/legacy_websocket.py index ce6336b4f5..266900bd9f 100644 --- a/web3/providers/legacy_websocket.py +++ b/web3/providers/legacy_websocket.py @@ -148,4 +148,6 @@ def make_batch_request( future = asyncio.run_coroutine_threadsafe( self.coro_make_request(request_data), LegacyWebSocketProvider._loop ) - return cast(List[RPCResponse], future.result()) + response = cast(List[RPCResponse], future.result()) + # sort by response `id` since the JSON-RPC 2.0 spec doesn't guarantee order + return sorted(response, key=lambda resp: int(resp["id"])) diff --git a/web3/providers/persistent/async_ipc.py b/web3/providers/persistent/async_ipc.py index b922358e7d..84df8ee1b0 100644 --- a/web3/providers/persistent/async_ipc.py +++ b/web3/providers/persistent/async_ipc.py @@ -195,8 +195,11 @@ async def make_batch_request( # generate a cache key with all the request ids hashed request_ids = [rpc_request["id"] for rpc_request in json.loads(request_data)] - response = await self._get_response_for_request_id(request_ids) - return cast(List[RPCResponse], response) + response = cast( + List[RPCResponse], await self._get_response_for_request_id(request_ids) + ) + # sort by response `id` since the JSON-RPC 2.0 spec doesn't guarantee order + return sorted(response, key=lambda resp: int(resp["id"])) async def _message_listener(self) -> None: self.logger.info( diff --git a/web3/providers/persistent/websocket.py b/web3/providers/persistent/websocket.py index 496d800552..ac73b2d747 100644 --- a/web3/providers/persistent/websocket.py +++ b/web3/providers/persistent/websocket.py @@ -195,8 +195,11 @@ async def make_batch_request( # generate a cache key with all the request ids hashed request_ids = [rpc_request["id"] for rpc_request in json.loads(request_data)] - response = await self._get_response_for_request_id(request_ids) - return cast(List[RPCResponse], response) + response = cast( + List[RPCResponse], await self._get_response_for_request_id(request_ids) + ) + # sort by response `id` since the JSON-RPC 2.0 spec doesn't guarantee order + return sorted(response, key=lambda resp: int(resp["id"])) async def _message_listener(self) -> None: self.logger.info(