web3 7.11.1__py3-none-any.whl → 7.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ens/async_ens.py +2 -2
- ens/ens.py +2 -2
- ens/utils.py +14 -3
- web3/_utils/abi.py +24 -20
- web3/_utils/batching.py +22 -68
- web3/_utils/caching/request_caching_validation.py +8 -4
- web3/_utils/decorators.py +12 -9
- web3/_utils/http_session_manager.py +18 -15
- web3/_utils/method_formatters.py +17 -24
- web3/_utils/module_testing/eth_module.py +25 -14
- web3/_utils/module_testing/web3_module.py +78 -4
- web3/_utils/validation.py +1 -1
- web3/contract/utils.py +20 -35
- web3/manager.py +105 -23
- web3/method.py +7 -7
- web3/providers/async_base.py +15 -1
- web3/providers/base.py +18 -5
- web3/providers/ipc.py +2 -4
- web3/providers/legacy_websocket.py +4 -5
- web3/providers/persistent/persistent.py +110 -40
- web3/providers/persistent/request_processor.py +34 -51
- web3/providers/persistent/subscription_manager.py +12 -7
- web3/providers/rpc/async_rpc.py +7 -7
- web3/providers/rpc/rpc.py +6 -6
- web3/utils/subscriptions.py +7 -4
- {web3-7.11.1.dist-info → web3-7.12.0.dist-info}/METADATA +69 -56
- {web3-7.11.1.dist-info → web3-7.12.0.dist-info}/RECORD +30 -30
- {web3-7.11.1.dist-info → web3-7.12.0.dist-info}/WHEEL +1 -1
- {web3-7.11.1.dist-info → web3-7.12.0.dist-info/licenses}/LICENSE +0 -0
- {web3-7.11.1.dist-info → web3-7.12.0.dist-info}/top_level.txt +0 -0
|
@@ -27,7 +27,6 @@ from websockets.legacy.client import (
|
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
from web3._utils.batching import (
|
|
30
|
-
batching_context,
|
|
31
30
|
sort_batch_response_by_response_ids,
|
|
32
31
|
)
|
|
33
32
|
from web3._utils.caching import (
|
|
@@ -136,7 +135,7 @@ class LegacyWebSocketProvider(JSONBaseProvider):
|
|
|
136
135
|
@handle_request_caching
|
|
137
136
|
def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
138
137
|
self.logger.debug(
|
|
139
|
-
|
|
138
|
+
"Making request WebSocket. URI: %s, Method: %s", self.endpoint_uri, method
|
|
140
139
|
)
|
|
141
140
|
request_data = self.encode_rpc_request(method, params)
|
|
142
141
|
future = asyncio.run_coroutine_threadsafe(
|
|
@@ -144,13 +143,13 @@ class LegacyWebSocketProvider(JSONBaseProvider):
|
|
|
144
143
|
)
|
|
145
144
|
return future.result()
|
|
146
145
|
|
|
147
|
-
@batching_context
|
|
148
146
|
def make_batch_request(
|
|
149
147
|
self, requests: List[Tuple[RPCEndpoint, Any]]
|
|
150
148
|
) -> List[RPCResponse]:
|
|
151
149
|
self.logger.debug(
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
"Making batch request WebSocket. URI: %s, Methods: %s",
|
|
151
|
+
self.endpoint_uri,
|
|
152
|
+
requests,
|
|
154
153
|
)
|
|
155
154
|
request_data = self.encode_batch_rpc_request(requests)
|
|
156
155
|
future = asyncio.run_coroutine_threadsafe(
|
|
@@ -24,7 +24,6 @@ from websockets import (
|
|
|
24
24
|
|
|
25
25
|
from web3._utils.batching import (
|
|
26
26
|
BATCH_REQUEST_ID,
|
|
27
|
-
async_batching_context,
|
|
28
27
|
sort_batch_response_by_response_ids,
|
|
29
28
|
)
|
|
30
29
|
from web3._utils.caching import (
|
|
@@ -71,16 +70,16 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
71
70
|
|
|
72
71
|
_send_func_cache: Tuple[
|
|
73
72
|
Optional[int], Optional[Callable[..., Coroutine[Any, Any, RPCRequest]]]
|
|
74
|
-
] = (
|
|
75
|
-
None,
|
|
76
|
-
None,
|
|
77
|
-
)
|
|
73
|
+
] = (None, None)
|
|
78
74
|
_recv_func_cache: Tuple[
|
|
79
75
|
Optional[int], Optional[Callable[..., Coroutine[Any, Any, RPCResponse]]]
|
|
80
|
-
] = (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
76
|
+
] = (None, None)
|
|
77
|
+
_send_batch_func_cache: Tuple[
|
|
78
|
+
Optional[int], Optional[Callable[..., Coroutine[Any, Any, List[RPCRequest]]]]
|
|
79
|
+
] = (None, None)
|
|
80
|
+
_recv_batch_func_cache: Tuple[
|
|
81
|
+
Optional[int], Optional[Callable[..., Coroutine[Any, Any, List[RPCResponse]]]]
|
|
82
|
+
] = (None, None)
|
|
84
83
|
|
|
85
84
|
def __init__(
|
|
86
85
|
self,
|
|
@@ -98,13 +97,14 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
98
97
|
request_information_cache_size=request_information_cache_size,
|
|
99
98
|
)
|
|
100
99
|
self._message_listener_task: Optional["asyncio.Task[None]"] = None
|
|
101
|
-
self._batch_request_counter: Optional[int] = None
|
|
102
100
|
self._listen_event: asyncio.Event = asyncio.Event()
|
|
103
101
|
self._max_connection_retries = max_connection_retries
|
|
104
102
|
|
|
105
103
|
self.request_timeout = request_timeout
|
|
106
104
|
self.silence_listener_task_exceptions = silence_listener_task_exceptions
|
|
107
105
|
|
|
106
|
+
# -- cached middleware request/response functions -- #
|
|
107
|
+
|
|
108
108
|
async def send_func(
|
|
109
109
|
self, async_w3: "AsyncWeb3", middleware_onion: "MiddlewareOnion"
|
|
110
110
|
) -> Callable[..., Coroutine[Any, Any, RPCRequest]]:
|
|
@@ -155,6 +155,60 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
155
155
|
|
|
156
156
|
return self._recv_func_cache[1]
|
|
157
157
|
|
|
158
|
+
async def send_batch_func(
|
|
159
|
+
self, async_w3: "AsyncWeb3", middleware_onion: "MiddlewareOnion"
|
|
160
|
+
) -> Callable[..., Coroutine[Any, Any, List[RPCRequest]]]:
|
|
161
|
+
middleware = middleware_onion.as_tuple_of_middleware()
|
|
162
|
+
cache_key = hash(tuple(id(mw) for mw in middleware))
|
|
163
|
+
|
|
164
|
+
if cache_key != self._send_batch_func_cache[0]:
|
|
165
|
+
|
|
166
|
+
async def send_func(
|
|
167
|
+
requests: List[Tuple[RPCEndpoint, Any]]
|
|
168
|
+
) -> List[RPCRequest]:
|
|
169
|
+
for mw in middleware:
|
|
170
|
+
initialized = mw(async_w3)
|
|
171
|
+
requests = [
|
|
172
|
+
await initialized.async_request_processor(method, params)
|
|
173
|
+
for (method, params) in requests
|
|
174
|
+
]
|
|
175
|
+
return await self.send_batch_request(requests)
|
|
176
|
+
|
|
177
|
+
self._send_batch_func_cache = (cache_key, send_func)
|
|
178
|
+
|
|
179
|
+
return self._send_batch_func_cache[1]
|
|
180
|
+
|
|
181
|
+
async def recv_batch_func(
|
|
182
|
+
self, async_w3: "AsyncWeb3", middleware_onion: "MiddlewareOnion"
|
|
183
|
+
) -> Callable[..., Coroutine[Any, Any, List[RPCResponse]]]:
|
|
184
|
+
middleware = middleware_onion.as_tuple_of_middleware()
|
|
185
|
+
cache_key = hash(tuple(id(mw) for mw in middleware))
|
|
186
|
+
|
|
187
|
+
if cache_key != self._recv_batch_func_cache[0]:
|
|
188
|
+
|
|
189
|
+
async def recv_function(
|
|
190
|
+
rpc_requests: List[RPCRequest],
|
|
191
|
+
) -> List[RPCResponse]:
|
|
192
|
+
methods = [rpc_request["method"] for rpc_request in rpc_requests]
|
|
193
|
+
responses = await self.recv_for_batch_request(rpc_requests)
|
|
194
|
+
for mw in reversed(middleware):
|
|
195
|
+
if not isinstance(responses, list):
|
|
196
|
+
# RPC errors return only one response with the error object
|
|
197
|
+
return responses
|
|
198
|
+
|
|
199
|
+
initialized = mw(async_w3)
|
|
200
|
+
responses = [
|
|
201
|
+
await initialized.async_response_processor(m, r)
|
|
202
|
+
for m, r in zip(methods, responses)
|
|
203
|
+
]
|
|
204
|
+
return responses
|
|
205
|
+
|
|
206
|
+
self._recv_batch_func_cache = (cache_key, recv_function)
|
|
207
|
+
|
|
208
|
+
return self._recv_batch_func_cache[1]
|
|
209
|
+
|
|
210
|
+
# -- connection management -- #
|
|
211
|
+
|
|
158
212
|
def get_endpoint_uri_or_ipc_path(self) -> str:
|
|
159
213
|
if hasattr(self, "endpoint_uri"):
|
|
160
214
|
return str(self.endpoint_uri)
|
|
@@ -167,6 +221,7 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
167
221
|
)
|
|
168
222
|
|
|
169
223
|
async def connect(self) -> None:
|
|
224
|
+
endpoint = self.get_endpoint_uri_or_ipc_path()
|
|
170
225
|
_connection_attempts = 0
|
|
171
226
|
_backoff_rate_change = 1.75
|
|
172
227
|
_backoff_time = 1.75
|
|
@@ -174,9 +229,7 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
174
229
|
while _connection_attempts != self._max_connection_retries:
|
|
175
230
|
try:
|
|
176
231
|
_connection_attempts += 1
|
|
177
|
-
self.logger.info(
|
|
178
|
-
f"Connecting to: {self.get_endpoint_uri_or_ipc_path()}"
|
|
179
|
-
)
|
|
232
|
+
self.logger.info("Connecting to: %s", endpoint)
|
|
180
233
|
await self._provider_specific_connect()
|
|
181
234
|
self._message_listener_task = asyncio.create_task(
|
|
182
235
|
self._message_listener()
|
|
@@ -184,19 +237,18 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
184
237
|
self._message_listener_task.add_done_callback(
|
|
185
238
|
self._message_listener_callback
|
|
186
239
|
)
|
|
187
|
-
self.logger.info(
|
|
188
|
-
f"Successfully connected to: {self.get_endpoint_uri_or_ipc_path()}"
|
|
189
|
-
)
|
|
240
|
+
self.logger.info("Successfully connected to: %s", endpoint)
|
|
190
241
|
break
|
|
191
242
|
except (WebSocketException, OSError) as e:
|
|
192
243
|
if _connection_attempts == self._max_connection_retries:
|
|
193
244
|
raise ProviderConnectionError(
|
|
194
|
-
f"Could not connect to: {
|
|
245
|
+
f"Could not connect to: {endpoint}. "
|
|
195
246
|
f"Retries exceeded max of {self._max_connection_retries}."
|
|
196
247
|
) from e
|
|
197
248
|
self.logger.info(
|
|
198
|
-
|
|
199
|
-
|
|
249
|
+
"Could not connect to: %s. Retrying in %s seconds.",
|
|
250
|
+
endpoint,
|
|
251
|
+
round(_backoff_time, 1),
|
|
200
252
|
exc_info=True,
|
|
201
253
|
)
|
|
202
254
|
await asyncio.sleep(_backoff_time)
|
|
@@ -217,9 +269,12 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
217
269
|
await self._provider_specific_disconnect()
|
|
218
270
|
self._request_processor.clear_caches()
|
|
219
271
|
self.logger.info(
|
|
220
|
-
|
|
272
|
+
"Successfully disconnected from: %s",
|
|
273
|
+
self.get_endpoint_uri_or_ipc_path(),
|
|
221
274
|
)
|
|
222
275
|
|
|
276
|
+
# -- request methods -- #
|
|
277
|
+
|
|
223
278
|
@async_handle_send_caching
|
|
224
279
|
async def send_request(self, method: RPCEndpoint, params: Any) -> RPCRequest:
|
|
225
280
|
request_dict = self.form_request(method, params)
|
|
@@ -238,20 +293,33 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
238
293
|
rpc_request = await self.send_request(method, params)
|
|
239
294
|
return await self.recv_for_request(rpc_request)
|
|
240
295
|
|
|
241
|
-
|
|
242
|
-
|
|
296
|
+
# -- batch requests -- #
|
|
297
|
+
|
|
298
|
+
async def send_batch_request(
|
|
243
299
|
self, requests: List[Tuple[RPCEndpoint, Any]]
|
|
244
|
-
) -> List[
|
|
245
|
-
|
|
300
|
+
) -> List[RPCRequest]:
|
|
301
|
+
request_dicts = [
|
|
302
|
+
self.form_request(method, params) for (method, params) in requests
|
|
303
|
+
]
|
|
304
|
+
request_data = self.encode_batch_request_dicts(request_dicts)
|
|
246
305
|
await self.socket_send(request_data)
|
|
306
|
+
return request_dicts
|
|
247
307
|
|
|
248
|
-
|
|
308
|
+
async def recv_for_batch_request(
|
|
309
|
+
self, _request_dicts: List[RPCRequest]
|
|
310
|
+
) -> List[RPCResponse]:
|
|
249
311
|
response = cast(
|
|
250
312
|
List[RPCResponse],
|
|
251
313
|
await self._get_response_for_request_id(BATCH_REQUEST_ID),
|
|
252
314
|
)
|
|
253
315
|
return response
|
|
254
316
|
|
|
317
|
+
async def make_batch_request(
|
|
318
|
+
self, requests: List[Tuple[RPCEndpoint, Any]]
|
|
319
|
+
) -> List[RPCResponse]:
|
|
320
|
+
request_dicts = await self.send_batch_request(requests)
|
|
321
|
+
return await self.recv_for_batch_request(request_dicts)
|
|
322
|
+
|
|
255
323
|
# -- abstract methods -- #
|
|
256
324
|
|
|
257
325
|
@abstractmethod
|
|
@@ -320,26 +388,26 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
320
388
|
Check the request response cache for any errors not tied to current requests
|
|
321
389
|
and raise them if found.
|
|
322
390
|
"""
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
response
|
|
326
|
-
|
|
327
|
-
|
|
391
|
+
for response in self._request_processor._request_response_cache._data.values():
|
|
392
|
+
if isinstance(response, dict):
|
|
393
|
+
if "id" not in response:
|
|
394
|
+
validate_rpc_response_and_raise_if_error(
|
|
395
|
+
cast(RPCResponse, response), None, logger=self.logger
|
|
396
|
+
)
|
|
397
|
+
else:
|
|
328
398
|
request = self._request_processor._request_information_cache.get_cache_entry( # noqa: E501
|
|
329
399
|
generate_cache_key(response["id"])
|
|
330
400
|
)
|
|
331
401
|
if "error" in response and request is None:
|
|
332
|
-
# if we find an error response in the cache without a
|
|
333
|
-
# corresponding request, raise the error
|
|
334
402
|
validate_rpc_response_and_raise_if_error(
|
|
335
403
|
cast(RPCResponse, response), None, logger=self.logger
|
|
336
404
|
)
|
|
337
405
|
|
|
338
406
|
async def _message_listener(self) -> None:
|
|
339
407
|
self.logger.info(
|
|
340
|
-
|
|
341
|
-
"
|
|
342
|
-
|
|
408
|
+
"%s listener background task started. Storing all messages in "
|
|
409
|
+
"appropriate request processor queues / caches to be processed.",
|
|
410
|
+
self.__class__.__qualname__,
|
|
343
411
|
)
|
|
344
412
|
while True:
|
|
345
413
|
# the use of sleep(0) seems to be the most efficient way to yield control
|
|
@@ -363,8 +431,8 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
363
431
|
self._raise_stray_errors_from_cache()
|
|
364
432
|
except PersistentConnectionClosedOK as e:
|
|
365
433
|
self.logger.info(
|
|
366
|
-
"Message listener background task has ended gracefully: "
|
|
367
|
-
|
|
434
|
+
"Message listener background task has ended gracefully: %s",
|
|
435
|
+
e.user_message,
|
|
368
436
|
)
|
|
369
437
|
# trigger a return to end the listener task and initiate the callback fn
|
|
370
438
|
return
|
|
@@ -382,8 +450,9 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
382
450
|
"""
|
|
383
451
|
self.logger.error(
|
|
384
452
|
"Exception caught in listener, error logging and keeping "
|
|
385
|
-
"listener background task alive
|
|
386
|
-
|
|
453
|
+
"listener background task alive.\n error=%s: %s",
|
|
454
|
+
e.__class__.__name__,
|
|
455
|
+
e,
|
|
387
456
|
)
|
|
388
457
|
|
|
389
458
|
def _handle_listener_task_exceptions(self) -> None:
|
|
@@ -416,7 +485,8 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
|
|
|
416
485
|
|
|
417
486
|
if request_cache_key in self._request_processor._request_response_cache:
|
|
418
487
|
self.logger.debug(
|
|
419
|
-
|
|
488
|
+
"Popping response for id %s from cache.",
|
|
489
|
+
request_id,
|
|
420
490
|
)
|
|
421
491
|
popped_response = await self._request_processor.pop_raw_response(
|
|
422
492
|
cache_key=request_cache_key,
|
|
@@ -13,10 +13,6 @@ from typing import (
|
|
|
13
13
|
Union,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
from eth_utils.toolz import (
|
|
17
|
-
compose,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
16
|
from web3._utils.batching import (
|
|
21
17
|
BATCH_REQUEST_ID,
|
|
22
18
|
)
|
|
@@ -128,7 +124,9 @@ class RequestProcessor:
|
|
|
128
124
|
if cache_key in self._request_information_cache:
|
|
129
125
|
self._provider.logger.debug(
|
|
130
126
|
"This is a cached request, not caching request info because it is "
|
|
131
|
-
|
|
127
|
+
"not unique:\n method=%s,\n params=%s",
|
|
128
|
+
method,
|
|
129
|
+
params,
|
|
132
130
|
)
|
|
133
131
|
return None
|
|
134
132
|
|
|
@@ -137,9 +135,6 @@ class RequestProcessor:
|
|
|
137
135
|
raise Web3ValueError(
|
|
138
136
|
"Request id must be provided when not batching requests."
|
|
139
137
|
)
|
|
140
|
-
# the _batch_request_counter is set when entering the context manager
|
|
141
|
-
request_id = self._provider._batch_request_counter
|
|
142
|
-
self._provider._batch_request_counter += 1
|
|
143
138
|
|
|
144
139
|
cache_key = generate_cache_key(request_id)
|
|
145
140
|
request_info = RequestInformation(
|
|
@@ -148,8 +143,11 @@ class RequestProcessor:
|
|
|
148
143
|
response_formatters,
|
|
149
144
|
)
|
|
150
145
|
self._provider.logger.debug(
|
|
151
|
-
|
|
152
|
-
|
|
146
|
+
"Caching request info:\n request_id=%s,\n"
|
|
147
|
+
" cache_key=%s,\n request_info=%s",
|
|
148
|
+
request_id,
|
|
149
|
+
cache_key,
|
|
150
|
+
request_info.__dict__,
|
|
153
151
|
)
|
|
154
152
|
self._request_information_cache.cache(
|
|
155
153
|
cache_key,
|
|
@@ -170,7 +168,9 @@ class RequestProcessor:
|
|
|
170
168
|
if request_info is not None:
|
|
171
169
|
self._provider.logger.debug(
|
|
172
170
|
"Request info popped from cache:\n"
|
|
173
|
-
|
|
171
|
+
" cache_key=%s,\n request_info=%s",
|
|
172
|
+
cache_key,
|
|
173
|
+
request_info.__dict__,
|
|
174
174
|
)
|
|
175
175
|
return request_info
|
|
176
176
|
|
|
@@ -224,33 +224,6 @@ class RequestProcessor:
|
|
|
224
224
|
|
|
225
225
|
return request_info
|
|
226
226
|
|
|
227
|
-
def append_result_formatter_for_request(
|
|
228
|
-
self, request_id: int, result_formatter: Callable[..., Any]
|
|
229
|
-
) -> None:
|
|
230
|
-
cache_key = generate_cache_key(request_id)
|
|
231
|
-
cached_request_info_for_id: RequestInformation = (
|
|
232
|
-
self._request_information_cache.get_cache_entry(cache_key)
|
|
233
|
-
)
|
|
234
|
-
if cached_request_info_for_id is not None:
|
|
235
|
-
(
|
|
236
|
-
current_result_formatters,
|
|
237
|
-
error_formatters,
|
|
238
|
-
null_result_formatters,
|
|
239
|
-
) = cached_request_info_for_id.response_formatters
|
|
240
|
-
cached_request_info_for_id.response_formatters = (
|
|
241
|
-
compose(
|
|
242
|
-
result_formatter,
|
|
243
|
-
current_result_formatters,
|
|
244
|
-
),
|
|
245
|
-
error_formatters,
|
|
246
|
-
null_result_formatters,
|
|
247
|
-
)
|
|
248
|
-
else:
|
|
249
|
-
self._provider.logger.debug(
|
|
250
|
-
f"No cached request info for response id `{request_id}`. Cannot "
|
|
251
|
-
f"append response formatter for response."
|
|
252
|
-
)
|
|
253
|
-
|
|
254
227
|
def append_middleware_response_processor(
|
|
255
228
|
self,
|
|
256
229
|
response: RPCResponse,
|
|
@@ -269,13 +242,16 @@ class RequestProcessor:
|
|
|
269
242
|
)
|
|
270
243
|
else:
|
|
271
244
|
self._provider.logger.debug(
|
|
272
|
-
|
|
273
|
-
|
|
245
|
+
"No cached request info for response id `%s`. Cannot "
|
|
246
|
+
"append middleware response processor for response: %s",
|
|
247
|
+
response_id,
|
|
248
|
+
response,
|
|
274
249
|
)
|
|
275
250
|
else:
|
|
276
251
|
self._provider.logger.debug(
|
|
277
252
|
"No response `id` in response. Cannot append middleware response "
|
|
278
|
-
|
|
253
|
+
"processor for response: %s",
|
|
254
|
+
response,
|
|
279
255
|
)
|
|
280
256
|
|
|
281
257
|
# raw response cache
|
|
@@ -302,7 +278,7 @@ class RequestProcessor:
|
|
|
302
278
|
await self._provider._listen_event.wait()
|
|
303
279
|
|
|
304
280
|
self._provider.logger.debug(
|
|
305
|
-
|
|
281
|
+
"Caching subscription response:\n response=%s", raw_response
|
|
306
282
|
)
|
|
307
283
|
subscription_id = raw_response.get("params", {}).get("subscription")
|
|
308
284
|
sub_container = self._subscription_container
|
|
@@ -320,16 +296,20 @@ class RequestProcessor:
|
|
|
320
296
|
# constant cache key for the batch response.
|
|
321
297
|
cache_key = generate_cache_key(BATCH_REQUEST_ID)
|
|
322
298
|
self._provider.logger.debug(
|
|
323
|
-
|
|
324
|
-
|
|
299
|
+
"Caching batch response:\n cache_key=%s,\n response=%s",
|
|
300
|
+
cache_key,
|
|
301
|
+
raw_response,
|
|
325
302
|
)
|
|
326
303
|
self._request_response_cache.cache(cache_key, raw_response)
|
|
327
304
|
else:
|
|
328
305
|
response_id = raw_response.get("id")
|
|
329
306
|
cache_key = generate_cache_key(response_id)
|
|
330
307
|
self._provider.logger.debug(
|
|
331
|
-
|
|
332
|
-
|
|
308
|
+
"Caching response:\n response_id=%s,\n"
|
|
309
|
+
" cache_key=%s,\n response=%s",
|
|
310
|
+
response_id,
|
|
311
|
+
cache_key,
|
|
312
|
+
raw_response,
|
|
333
313
|
)
|
|
334
314
|
self._request_response_cache.cache(cache_key, raw_response)
|
|
335
315
|
|
|
@@ -354,13 +334,15 @@ class RequestProcessor:
|
|
|
354
334
|
if self._subscription_queue_synced_with_ws_stream:
|
|
355
335
|
self._subscription_queue_synced_with_ws_stream = False
|
|
356
336
|
self._provider.logger.info(
|
|
357
|
-
|
|
358
|
-
"Processing as FIFO."
|
|
337
|
+
"Subscription response queue has %s subscriptions. "
|
|
338
|
+
"Processing as FIFO.",
|
|
339
|
+
qsize,
|
|
359
340
|
)
|
|
360
341
|
|
|
361
342
|
self._provider.logger.debug(
|
|
362
343
|
"Subscription response popped from queue to be processed:\n"
|
|
363
|
-
|
|
344
|
+
" raw_response=%s",
|
|
345
|
+
raw_response,
|
|
364
346
|
)
|
|
365
347
|
else:
|
|
366
348
|
if not cache_key:
|
|
@@ -372,8 +354,9 @@ class RequestProcessor:
|
|
|
372
354
|
if raw_response is not None:
|
|
373
355
|
self._provider.logger.debug(
|
|
374
356
|
"Cached response popped from cache to be processed:\n"
|
|
375
|
-
|
|
376
|
-
|
|
357
|
+
" cache_key=%s,\n raw_response=%s",
|
|
358
|
+
cache_key,
|
|
359
|
+
raw_response,
|
|
377
360
|
)
|
|
378
361
|
|
|
379
362
|
return raw_response
|
|
@@ -123,8 +123,9 @@ class SubscriptionManager:
|
|
|
123
123
|
subscriptions._id = sub_id
|
|
124
124
|
self._add_subscription(subscriptions)
|
|
125
125
|
self.logger.info(
|
|
126
|
-
"Successfully subscribed to subscription:\n "
|
|
127
|
-
|
|
126
|
+
"Successfully subscribed to subscription:\n label: %s\n id: %s",
|
|
127
|
+
subscriptions.label,
|
|
128
|
+
sub_id,
|
|
128
129
|
)
|
|
129
130
|
return sub_id
|
|
130
131
|
elif isinstance(subscriptions, Sequence):
|
|
@@ -190,8 +191,10 @@ class SubscriptionManager:
|
|
|
190
191
|
if await self._w3.eth._unsubscribe(subscriptions.id):
|
|
191
192
|
self._remove_subscription(subscriptions)
|
|
192
193
|
self.logger.info(
|
|
193
|
-
"Successfully unsubscribed from subscription:\n
|
|
194
|
-
|
|
194
|
+
"Successfully unsubscribed from subscription:\n"
|
|
195
|
+
" label: %s\n id: %s",
|
|
196
|
+
subscriptions.label,
|
|
197
|
+
subscriptions.id,
|
|
195
198
|
)
|
|
196
199
|
|
|
197
200
|
if len(self._subscription_container.handler_subscriptions) == 0:
|
|
@@ -208,7 +211,7 @@ class SubscriptionManager:
|
|
|
208
211
|
unsubscribed: List[bool] = []
|
|
209
212
|
# re-create the subscription list to prevent modifying the original list
|
|
210
213
|
# in case ``subscription_manager.subscriptions`` was passed in directly
|
|
211
|
-
subs =
|
|
214
|
+
subs = list(subscriptions)
|
|
212
215
|
for sub in subs:
|
|
213
216
|
if isinstance(sub, str):
|
|
214
217
|
sub = HexStr(sub)
|
|
@@ -216,7 +219,8 @@ class SubscriptionManager:
|
|
|
216
219
|
return all(unsubscribed)
|
|
217
220
|
|
|
218
221
|
self.logger.warning(
|
|
219
|
-
|
|
222
|
+
"Failed to unsubscribe from subscription\n subscription=%s",
|
|
223
|
+
subscriptions,
|
|
220
224
|
)
|
|
221
225
|
return False
|
|
222
226
|
|
|
@@ -240,7 +244,8 @@ class SubscriptionManager:
|
|
|
240
244
|
if len(self.subscriptions) > 0:
|
|
241
245
|
self.logger.warning(
|
|
242
246
|
"Failed to unsubscribe from all subscriptions. Some subscriptions "
|
|
243
|
-
|
|
247
|
+
"are still active.\n subscriptions=%s",
|
|
248
|
+
self.subscriptions,
|
|
244
249
|
)
|
|
245
250
|
return False
|
|
246
251
|
|
web3/providers/rpc/async_rpc.py
CHANGED
|
@@ -36,7 +36,6 @@ from web3.types import (
|
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
from ..._utils.batching import (
|
|
39
|
-
async_batching_context,
|
|
40
39
|
sort_batch_response_by_response_ids,
|
|
41
40
|
)
|
|
42
41
|
from ..._utils.caching import (
|
|
@@ -156,22 +155,23 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
156
155
|
@async_handle_request_caching
|
|
157
156
|
async def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
158
157
|
self.logger.debug(
|
|
159
|
-
|
|
158
|
+
"Making request HTTP. URI: %s, Method: %s", self.endpoint_uri, method
|
|
160
159
|
)
|
|
161
160
|
request_data = self.encode_rpc_request(method, params)
|
|
162
161
|
raw_response = await self._make_request(method, request_data)
|
|
163
162
|
response = self.decode_rpc_response(raw_response)
|
|
164
163
|
self.logger.debug(
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
"Getting response HTTP. URI: %s, Method: %s, Response: %s",
|
|
165
|
+
self.endpoint_uri,
|
|
166
|
+
method,
|
|
167
|
+
response,
|
|
167
168
|
)
|
|
168
169
|
return response
|
|
169
170
|
|
|
170
|
-
@async_batching_context
|
|
171
171
|
async def make_batch_request(
|
|
172
172
|
self, batch_requests: List[Tuple[RPCEndpoint, Any]]
|
|
173
173
|
) -> Union[List[RPCResponse], RPCResponse]:
|
|
174
|
-
self.logger.debug(
|
|
174
|
+
self.logger.debug("Making batch request HTTP - uri: `%s`", self.endpoint_uri)
|
|
175
175
|
request_data = self.encode_batch_rpc_request(batch_requests)
|
|
176
176
|
raw_response = await self._request_session_manager.async_make_post_request(
|
|
177
177
|
self.endpoint_uri, request_data, **self.get_request_kwargs()
|
|
@@ -191,4 +191,4 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
191
191
|
await session.close()
|
|
192
192
|
cache.clear()
|
|
193
193
|
|
|
194
|
-
self.logger.info(
|
|
194
|
+
self.logger.info("Successfully disconnected from: %s", self.endpoint_uri)
|
web3/providers/rpc/rpc.py
CHANGED
|
@@ -34,7 +34,6 @@ from web3.types import (
|
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
from ..._utils.batching import (
|
|
37
|
-
batching_context,
|
|
38
37
|
sort_batch_response_by_response_ids,
|
|
39
38
|
)
|
|
40
39
|
from ..._utils.caching import (
|
|
@@ -164,22 +163,23 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
164
163
|
@handle_request_caching
|
|
165
164
|
def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
166
165
|
self.logger.debug(
|
|
167
|
-
|
|
166
|
+
"Making request HTTP. URI: %s, Method: %s", self.endpoint_uri, method
|
|
168
167
|
)
|
|
169
168
|
request_data = self.encode_rpc_request(method, params)
|
|
170
169
|
raw_response = self._make_request(method, request_data)
|
|
171
170
|
response = self.decode_rpc_response(raw_response)
|
|
172
171
|
self.logger.debug(
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
"Getting response HTTP. URI: %s, Method: %s, Response: %s",
|
|
173
|
+
self.endpoint_uri,
|
|
174
|
+
method,
|
|
175
|
+
response,
|
|
175
176
|
)
|
|
176
177
|
return response
|
|
177
178
|
|
|
178
|
-
@batching_context
|
|
179
179
|
def make_batch_request(
|
|
180
180
|
self, batch_requests: List[Tuple[RPCEndpoint, Any]]
|
|
181
181
|
) -> Union[List[RPCResponse], RPCResponse]:
|
|
182
|
-
self.logger.debug(
|
|
182
|
+
self.logger.debug("Making batch request HTTP, uri: `%s`", self.endpoint_uri)
|
|
183
183
|
request_data = self.encode_batch_rpc_request(batch_requests)
|
|
184
184
|
raw_response = self._request_session_manager.make_post_request(
|
|
185
185
|
self.endpoint_uri, request_data, **self.get_request_kwargs()
|
web3/utils/subscriptions.py
CHANGED
|
@@ -87,10 +87,13 @@ def handler_wrapper(
|
|
|
87
87
|
sub.handler_call_count += 1
|
|
88
88
|
sub.manager.total_handler_calls += 1
|
|
89
89
|
sub.manager.logger.debug(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
"Subscription handler called.\n"
|
|
91
|
+
" label: %s\n"
|
|
92
|
+
" call count: %s\n"
|
|
93
|
+
" total handler calls: %s",
|
|
94
|
+
sub.label,
|
|
95
|
+
sub.handler_call_count,
|
|
96
|
+
sub.manager.total_handler_calls,
|
|
94
97
|
)
|
|
95
98
|
await handler(context)
|
|
96
99
|
|