web3 7.0.0b3__py3-none-any.whl → 7.0.0b5__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.
Files changed (82) hide show
  1. ens/_normalization.py +1 -3
  2. ens/async_ens.py +12 -9
  3. ens/contract_data.py +2 -2
  4. ens/ens.py +8 -5
  5. ens/exceptions.py +19 -27
  6. ens/specs/nf.json +1 -1
  7. ens/specs/normalization_spec.json +1 -1
  8. ens/utils.py +17 -10
  9. web3/__init__.py +2 -7
  10. web3/_utils/abi.py +30 -29
  11. web3/_utils/async_transactions.py +7 -4
  12. web3/_utils/blocks.py +6 -2
  13. web3/_utils/caching.py +7 -3
  14. web3/_utils/compat/__init__.py +0 -3
  15. web3/_utils/contract_sources/compile_contracts.py +1 -1
  16. web3/_utils/contracts.py +17 -17
  17. web3/_utils/datatypes.py +5 -1
  18. web3/_utils/decorators.py +6 -1
  19. web3/_utils/empty.py +1 -1
  20. web3/_utils/encoding.py +15 -10
  21. web3/_utils/error_formatters_utils.py +5 -3
  22. web3/_utils/events.py +38 -36
  23. web3/_utils/fee_utils.py +2 -4
  24. web3/_utils/filters.py +23 -18
  25. web3/_utils/formatters.py +2 -2
  26. web3/_utils/math.py +3 -2
  27. web3/_utils/method_formatters.py +24 -28
  28. web3/_utils/module.py +2 -1
  29. web3/_utils/module_testing/__init__.py +0 -3
  30. web3/_utils/module_testing/eth_module.py +494 -432
  31. web3/_utils/module_testing/module_testing_utils.py +1 -3
  32. web3/_utils/module_testing/utils.py +14 -7
  33. web3/_utils/normalizers.py +3 -3
  34. web3/_utils/request.py +4 -4
  35. web3/_utils/rpc_abi.py +5 -19
  36. web3/_utils/threads.py +8 -7
  37. web3/_utils/transactions.py +14 -12
  38. web3/_utils/type_conversion.py +5 -1
  39. web3/_utils/validation.py +12 -10
  40. web3/contract/async_contract.py +23 -18
  41. web3/contract/base_contract.py +69 -74
  42. web3/contract/contract.py +25 -19
  43. web3/contract/utils.py +11 -6
  44. web3/datastructures.py +22 -12
  45. web3/eth/async_eth.py +38 -32
  46. web3/eth/base_eth.py +7 -3
  47. web3/eth/eth.py +20 -15
  48. web3/exceptions.py +83 -78
  49. web3/gas_strategies/time_based.py +2 -4
  50. web3/geth.py +1 -191
  51. web3/main.py +6 -6
  52. web3/manager.py +128 -68
  53. web3/method.py +13 -5
  54. web3/middleware/base.py +4 -2
  55. web3/middleware/filter.py +45 -23
  56. web3/middleware/formatting.py +6 -3
  57. web3/middleware/names.py +4 -1
  58. web3/middleware/signing.py +8 -4
  59. web3/middleware/stalecheck.py +2 -1
  60. web3/providers/eth_tester/defaults.py +1 -49
  61. web3/providers/eth_tester/main.py +41 -15
  62. web3/providers/eth_tester/middleware.py +13 -9
  63. web3/providers/ipc.py +7 -3
  64. web3/providers/persistent/async_ipc.py +6 -7
  65. web3/providers/persistent/persistent.py +11 -1
  66. web3/providers/persistent/request_processor.py +7 -7
  67. web3/providers/persistent/websocket.py +3 -3
  68. web3/providers/rpc/async_rpc.py +24 -7
  69. web3/providers/rpc/rpc.py +30 -17
  70. web3/providers/rpc/utils.py +1 -10
  71. web3/testing.py +4 -4
  72. web3/tools/benchmark/main.py +13 -9
  73. web3/tools/benchmark/node.py +2 -8
  74. web3/tools/benchmark/utils.py +1 -1
  75. web3/tracing.py +9 -5
  76. web3/types.py +20 -23
  77. {web3-7.0.0b3.dist-info → web3-7.0.0b5.dist-info}/METADATA +13 -28
  78. {web3-7.0.0b3.dist-info → web3-7.0.0b5.dist-info}/RECORD +81 -82
  79. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  80. {web3-7.0.0b3.dist-info → web3-7.0.0b5.dist-info}/LICENSE +0 -0
  81. {web3-7.0.0b3.dist-info → web3-7.0.0b5.dist-info}/WHEEL +0 -0
  82. {web3-7.0.0b3.dist-info → web3-7.0.0b5.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,6 @@ from eth_tester.exceptions import (
21
21
  FilterNotFound,
22
22
  TransactionFailed,
23
23
  TransactionNotFound,
24
- ValidationError,
25
24
  )
26
25
  from eth_typing import (
27
26
  HexAddress,
@@ -218,7 +217,7 @@ def _generate_random_private_key() -> HexStr:
218
217
  WARNING: This is not a secure way to generate private keys and should only
219
218
  be used for testing purposes.
220
219
  """
221
- return encode_hex(bytes(bytearray((random.randint(0, 255) for _ in range(32)))))
220
+ return encode_hex(bytes(bytearray(random.randint(0, 255) for _ in range(32))))
222
221
 
223
222
 
224
223
  @without_params
@@ -226,18 +225,6 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
226
225
  return eth_tester.add_account(_generate_random_private_key())
227
226
 
228
227
 
229
- def personal_send_transaction(eth_tester: "EthereumTester", params: Any) -> HexStr:
230
- transaction, password = params
231
-
232
- try:
233
- eth_tester.unlock_account(transaction["from"], password)
234
- transaction_hash = eth_tester.send_transaction(transaction)
235
- finally:
236
- eth_tester.lock_account(transaction["from"])
237
-
238
- return transaction_hash
239
-
240
-
241
228
  API_ENDPOINTS = {
242
229
  "web3": {
243
230
  "clientVersion": client_version,
@@ -404,41 +391,6 @@ API_ENDPOINTS = {
404
391
  "writeBlockProfile": not_implemented,
405
392
  "writeMemProfile": not_implemented,
406
393
  },
407
- "personal": {
408
- "ec_recover": not_implemented,
409
- "import_raw_key": call_eth_tester("add_account"),
410
- "list_accounts": call_eth_tester("get_accounts"),
411
- "list_wallets": not_implemented,
412
- "lock_account": excepts(
413
- ValidationError,
414
- compose(static_return(True), call_eth_tester("lock_account")),
415
- static_return(False),
416
- ),
417
- "new_account": create_new_account,
418
- "unlock_account": excepts(
419
- ValidationError,
420
- compose(static_return(True), call_eth_tester("unlock_account")),
421
- static_return(False),
422
- ),
423
- "send_transaction": personal_send_transaction,
424
- "sign": not_implemented,
425
- # deprecated
426
- "ecRecover": not_implemented,
427
- "importRawKey": call_eth_tester("add_account"),
428
- "listAccounts": call_eth_tester("get_accounts"),
429
- "lockAccount": excepts(
430
- ValidationError,
431
- compose(static_return(True), call_eth_tester("lock_account")),
432
- static_return(False),
433
- ),
434
- "newAccount": create_new_account,
435
- "unlockAccount": excepts(
436
- ValidationError,
437
- compose(static_return(True), call_eth_tester("unlock_account")),
438
- static_return(False),
439
- ),
440
- "sendTransaction": personal_send_transaction,
441
- },
442
394
  "testing": {
443
395
  "timeTravel": call_eth_tester("time_travel"),
444
396
  },
@@ -4,8 +4,10 @@ from typing import (
4
4
  Callable,
5
5
  Coroutine,
6
6
  Dict,
7
+ Literal,
7
8
  Optional,
8
9
  Union,
10
+ cast,
9
11
  )
10
12
 
11
13
  from eth_abi import (
@@ -18,9 +20,6 @@ from eth_utils import (
18
20
  is_bytes,
19
21
  )
20
22
 
21
- from web3._utils.compat import (
22
- Literal,
23
- )
24
23
  from web3.providers import (
25
24
  BaseProvider,
26
25
  )
@@ -33,6 +32,9 @@ from web3.types import (
33
32
  RPCResponse,
34
33
  )
35
34
 
35
+ from ...exceptions import (
36
+ Web3TypeError,
37
+ )
36
38
  from ...middleware import (
37
39
  async_combine_middleware,
38
40
  combine_middleware,
@@ -58,6 +60,7 @@ if TYPE_CHECKING:
58
60
 
59
61
 
60
62
  class AsyncEthereumTesterProvider(AsyncBaseProvider):
63
+ _current_request_id = 0
61
64
  _middleware = (
62
65
  default_transaction_fields_middleware,
63
66
  ethereum_tester_middleware,
@@ -98,13 +101,22 @@ class AsyncEthereumTesterProvider(AsyncBaseProvider):
98
101
  return self._request_func_cache[-1]
99
102
 
100
103
  async def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
101
- return _make_request(method, params, self.api_endpoints, self.ethereum_tester)
104
+ response = _make_request(
105
+ method,
106
+ params,
107
+ self.api_endpoints,
108
+ self.ethereum_tester,
109
+ repr(self._current_request_id),
110
+ )
111
+ self._current_request_id += 1
112
+ return response
102
113
 
103
114
  async def is_connected(self, show_traceback: bool = False) -> Literal[True]:
104
115
  return True
105
116
 
106
117
 
107
118
  class EthereumTesterProvider(BaseProvider):
119
+ _current_request_id = 0
108
120
  _middleware = (
109
121
  default_transaction_fields_middleware,
110
122
  ethereum_tester_middleware,
@@ -133,7 +145,7 @@ class EthereumTesterProvider(BaseProvider):
133
145
  elif isinstance(ethereum_tester, BaseChainBackend):
134
146
  self.ethereum_tester = EthereumTester(ethereum_tester)
135
147
  else:
136
- raise TypeError(
148
+ raise Web3TypeError(
137
149
  "Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
138
150
  "a subclass of `eth_tester.backends.base.BaseChainBackend`, "
139
151
  f"instead received {type(ethereum_tester)}. "
@@ -172,23 +184,32 @@ class EthereumTesterProvider(BaseProvider):
172
184
  return self._request_func_cache[-1]
173
185
 
174
186
  def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
175
- return _make_request(method, params, self.api_endpoints, self.ethereum_tester)
187
+ response = _make_request(
188
+ method,
189
+ params,
190
+ self.api_endpoints,
191
+ self.ethereum_tester,
192
+ repr(self._current_request_id),
193
+ )
194
+ self._current_request_id += 1
195
+ return response
176
196
 
177
197
  def is_connected(self, show_traceback: bool = False) -> Literal[True]:
178
198
  return True
179
199
 
180
200
 
181
- def _make_response(result: Any, message: str = "") -> RPCResponse:
201
+ def _make_response(result: Any, response_id: str, message: str = "") -> RPCResponse:
182
202
  if isinstance(result, Exception):
183
- return RPCResponse(
203
+ return cast(
204
+ RPCResponse,
184
205
  {
185
- "id": 1,
206
+ "id": response_id,
186
207
  "jsonrpc": "2.0",
187
- "error": RPCError({"code": -32601, "message": message}),
188
- }
208
+ "error": cast(RPCError, {"code": -32601, "message": message}),
209
+ },
189
210
  )
190
211
 
191
- return RPCResponse({"id": 1, "jsonrpc": "2.0", "result": result})
212
+ return cast(RPCResponse, {"id": response_id, "jsonrpc": "2.0", "result": result})
192
213
 
193
214
 
194
215
  def _make_request(
@@ -196,6 +217,7 @@ def _make_request(
196
217
  params: Any,
197
218
  api_endpoints: Dict[str, Dict[str, Any]],
198
219
  ethereum_tester_instance: "EthereumTester",
220
+ request_id: str,
199
221
  ) -> RPCResponse:
200
222
  # do not import eth_tester derivatives until runtime,
201
223
  # it is not a default dependency
@@ -208,11 +230,15 @@ def _make_request(
208
230
  try:
209
231
  delegator = api_endpoints[namespace][endpoint]
210
232
  except KeyError as e:
211
- return _make_response(e, f"Unknown RPC Endpoint: {method}")
233
+ return _make_response(e, request_id, message=f"Unknown RPC Endpoint: {method}")
212
234
  try:
213
235
  response = delegator(ethereum_tester_instance, params)
214
236
  except NotImplementedError as e:
215
- return _make_response(e, f"RPC Endpoint has not been implemented: {method}")
237
+ return _make_response(
238
+ e,
239
+ request_id,
240
+ message=f"RPC Endpoint has not been implemented: {method}",
241
+ )
216
242
  except TransactionFailed as e:
217
243
  first_arg = e.args[0]
218
244
  try:
@@ -229,4 +255,4 @@ def _make_request(
229
255
  reason = first_arg
230
256
  raise TransactionFailed(f"execution reverted: {reason}")
231
257
  else:
232
- return _make_response(response)
258
+ return _make_response(response, request_id)
@@ -72,7 +72,9 @@ is_not_named_block = complement(is_named_block)
72
72
  # --- Request Mapping --- #
73
73
 
74
74
  TRANSACTION_REQUEST_KEY_MAPPING = {
75
+ "blobVersionedHashes": "blob_versioned_hashes",
75
76
  "gasPrice": "gas_price",
77
+ "maxFeePerBlobGas": "max_fee_per_blob_gas",
76
78
  "maxFeePerGas": "max_fee_per_gas",
77
79
  "maxPriorityFeePerGas": "max_priority_fee_per_gas",
78
80
  "accessList": "access_list",
@@ -90,7 +92,7 @@ TRANSACTION_REQUEST_FORMATTERS = {
90
92
  "maxFeePerGas": to_integer_if_hex,
91
93
  "maxPriorityFeePerGas": to_integer_if_hex,
92
94
  "accessList": apply_list_to_array_formatter(
93
- (apply_key_map({"storageKeys": "storage_keys"}))
95
+ apply_key_map({"storageKeys": "storage_keys"})
94
96
  ),
95
97
  }
96
98
  transaction_request_formatter = apply_formatters_to_dict(TRANSACTION_REQUEST_FORMATTERS)
@@ -108,14 +110,14 @@ filter_request_remapper = apply_key_map(FILTER_REQUEST_KEY_MAPPING)
108
110
 
109
111
 
110
112
  FILTER_REQUEST_FORMATTERS = {
111
- "fromBlock": to_integer_if_hex,
112
- "toBlock": to_integer_if_hex,
113
+ "from_block": to_integer_if_hex,
114
+ "to_block": to_integer_if_hex,
113
115
  }
114
116
  filter_request_formatter = apply_formatters_to_dict(FILTER_REQUEST_FORMATTERS)
115
117
 
116
118
  filter_request_transformer = compose(
117
- filter_request_remapper,
118
119
  filter_request_formatter,
120
+ filter_request_remapper,
119
121
  )
120
122
 
121
123
 
@@ -123,10 +125,12 @@ filter_request_transformer = compose(
123
125
 
124
126
  TRANSACTION_RESULT_KEY_MAPPING = {
125
127
  "access_list": "accessList",
128
+ "blob_versioned_hashes": "blobVersionedHashes",
126
129
  "block_hash": "blockHash",
127
130
  "block_number": "blockNumber",
128
131
  "chain_id": "chainId",
129
132
  "gas_price": "gasPrice",
133
+ "max_fee_per_blob_gas": "maxFeePerBlobGas",
130
134
  "max_fee_per_gas": "maxFeePerGas",
131
135
  "max_priority_fee_per_gas": "maxPriorityFeePerGas",
132
136
  "transaction_hash": "transactionHash",
@@ -164,6 +168,8 @@ RECEIPT_RESULT_KEY_MAPPING = {
164
168
  "effective_gas_price": "effectiveGasPrice",
165
169
  "transaction_hash": "transactionHash",
166
170
  "transaction_index": "transactionIndex",
171
+ "blob_gas_used": "blobGasUsed",
172
+ "blob_gas_price": "blobGasPrice",
167
173
  }
168
174
  receipt_result_remapper = apply_key_map(RECEIPT_RESULT_KEY_MAPPING)
169
175
 
@@ -186,6 +192,9 @@ BLOCK_RESULT_KEY_MAPPING = {
186
192
  # JSON-RPC spec still says miner
187
193
  "coinbase": "miner",
188
194
  "withdrawals_root": "withdrawalsRoot",
195
+ "parent_beacon_block_root": "parentBeaconBlockRoot",
196
+ "blob_gas_used": "blobGasUsed",
197
+ "excess_blob_gas": "excessBlobGas",
189
198
  }
190
199
  block_result_remapper = apply_key_map(BLOCK_RESULT_KEY_MAPPING)
191
200
 
@@ -276,11 +285,6 @@ request_formatters = {
276
285
  ),
277
286
  # EVM
278
287
  RPCEndpoint("evm_revert"): apply_formatters_to_args(hex_to_integer),
279
- # Personal
280
- RPCEndpoint("personal_sendTransaction"): apply_formatters_to_args(
281
- transaction_request_transformer,
282
- identity,
283
- ),
284
288
  }
285
289
 
286
290
  result_formatters: Optional[Dict[RPCEndpoint, Callable[..., Any]]] = {
web3/providers/ipc.py CHANGED
@@ -26,6 +26,10 @@ from web3.types import (
26
26
  RPCResponse,
27
27
  )
28
28
 
29
+ from ..exceptions import (
30
+ Web3TypeError,
31
+ Web3ValueError,
32
+ )
29
33
  from .base import (
30
34
  JSONBaseProvider,
31
35
  )
@@ -96,7 +100,7 @@ def get_default_ipc_path() -> str:
96
100
  return r"\\.\pipe\geth.ipc"
97
101
 
98
102
  else:
99
- raise ValueError(
103
+ raise Web3ValueError(
100
104
  f"Unsupported platform '{sys.platform}'. Only darwin/linux/win32/"
101
105
  "freebsd are supported. You must specify the ipc_path"
102
106
  )
@@ -117,7 +121,7 @@ def get_dev_ipc_path() -> str:
117
121
  return r"\\.\pipe\geth.ipc"
118
122
 
119
123
  else:
120
- raise ValueError(
124
+ raise Web3ValueError(
121
125
  f"Unsupported platform '{sys.platform}'. Only darwin/linux/win32/"
122
126
  "freebsd are supported. You must specify the ipc_path"
123
127
  )
@@ -139,7 +143,7 @@ class IPCProvider(JSONBaseProvider):
139
143
  elif isinstance(ipc_path, str) or isinstance(ipc_path, Path):
140
144
  self.ipc_path = str(Path(ipc_path).expanduser().resolve())
141
145
  else:
142
- raise TypeError("ipc_path must be of type string or pathlib.Path")
146
+ raise Web3TypeError("ipc_path must be of type string or pathlib.Path")
143
147
 
144
148
  self.timeout = timeout
145
149
  self._lock = threading.Lock()
@@ -33,6 +33,7 @@ from ..._utils.caching import (
33
33
  )
34
34
  from ...exceptions import (
35
35
  ProviderConnectionError,
36
+ Web3TypeError,
36
37
  )
37
38
  from ..ipc import (
38
39
  get_default_ipc_path,
@@ -71,7 +72,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
71
72
  elif isinstance(ipc_path, str) or isinstance(ipc_path, Path):
72
73
  self.ipc_path = str(Path(ipc_path).expanduser().resolve())
73
74
  else:
74
- raise TypeError("ipc_path must be of type string or pathlib.Path")
75
+ raise Web3TypeError("ipc_path must be of type string or pathlib.Path")
75
76
 
76
77
  self._max_connection_retries = max_connection_retries
77
78
  super().__init__(**kwargs)
@@ -91,7 +92,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
91
92
  current_request_id = json.loads(request_data)["id"]
92
93
  await self._get_response_for_request_id(current_request_id, timeout=2)
93
94
  return True
94
- except (OSError, BrokenPipeError, ProviderConnectionError) as e:
95
+ except (OSError, ProviderConnectionError) as e:
95
96
  if show_traceback:
96
97
  raise ProviderConnectionError(
97
98
  f"Problem connecting to provider with error: {type(e)}: {e}"
@@ -114,11 +115,11 @@ class AsyncIPCProvider(PersistentConnectionProvider):
114
115
  except OSError as e:
115
116
  if _connection_attempts == self._max_connection_retries:
116
117
  raise ProviderConnectionError(
117
- f"Could not connect to endpoint: {self.endpoint_uri}. "
118
+ f"Could not connect to: {self.ipc_path}. "
118
119
  f"Retries exceeded max of {self._max_connection_retries}."
119
120
  ) from e
120
121
  self.logger.info(
121
- f"Could not connect to endpoint: {self.endpoint_uri}. Retrying in "
122
+ f"Could not connect to: {self.ipc_path}. Retrying in "
122
123
  f"{round(_backoff_time, 1)} seconds.",
123
124
  exc_info=True,
124
125
  )
@@ -130,9 +131,7 @@ class AsyncIPCProvider(PersistentConnectionProvider):
130
131
  self._writer.close()
131
132
  await self._writer.wait_closed()
132
133
  self._writer = None
133
- self.logger.debug(
134
- f'Successfully disconnected from endpoint: "{self.endpoint_uri}'
135
- )
134
+ self.logger.debug(f'Successfully disconnected from : "{self.ipc_path}')
136
135
 
137
136
  try:
138
137
  self._message_listener_task.cancel()
@@ -30,7 +30,6 @@ DEFAULT_PERSISTENT_CONNECTION_TIMEOUT = 30.0
30
30
  class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
31
31
  logger = logging.getLogger("web3.providers.PersistentConnectionProvider")
32
32
  has_persistent_connection = True
33
- endpoint_uri: Optional[str] = None
34
33
 
35
34
  _request_processor: RequestProcessor
36
35
  _message_listener_task: Optional["asyncio.Task[None]"] = None
@@ -50,6 +49,17 @@ class PersistentConnectionProvider(AsyncJSONBaseProvider, ABC):
50
49
  self.request_timeout = request_timeout
51
50
  self.silence_listener_task_exceptions = silence_listener_task_exceptions
52
51
 
52
+ def get_endpoint_uri_or_ipc_path(self) -> str:
53
+ if hasattr(self, "endpoint_uri"):
54
+ return str(self.endpoint_uri)
55
+ elif hasattr(self, "ipc_path"):
56
+ return str(self.ipc_path)
57
+ else:
58
+ raise AttributeError(
59
+ "`PersistentConnectionProvider` must have either `endpoint_uri` or "
60
+ "`ipc_path` attribute."
61
+ )
62
+
53
63
  async def connect(self) -> None:
54
64
  raise NotImplementedError("Must be implemented by subclasses")
55
65
 
@@ -15,6 +15,9 @@ from web3._utils.caching import (
15
15
  RequestInformation,
16
16
  generate_cache_key,
17
17
  )
18
+ from web3.exceptions import (
19
+ Web3ValueError,
20
+ )
18
21
  from web3.types import (
19
22
  RPCEndpoint,
20
23
  RPCResponse,
@@ -136,9 +139,9 @@ class RequestProcessor:
136
139
  ) -> RequestInformation:
137
140
  if "method" in response and response["method"] == "eth_subscription":
138
141
  if "params" not in response:
139
- raise ValueError("Subscription response must have params field")
142
+ raise Web3ValueError("Subscription response must have params field")
140
143
  if "subscription" not in response["params"]:
141
- raise ValueError(
144
+ raise Web3ValueError(
142
145
  "Subscription response params must have subscription field"
143
146
  )
144
147
 
@@ -266,7 +269,7 @@ class RequestProcessor:
266
269
  )
267
270
  else:
268
271
  if not cache_key:
269
- raise ValueError(
272
+ raise Web3ValueError(
270
273
  "Must provide cache key when popping a non-subscription response."
271
274
  )
272
275
 
@@ -283,10 +286,7 @@ class RequestProcessor:
283
286
  # request processor class methods
284
287
 
285
288
  def clear_caches(self) -> None:
286
- """
287
- Clear the request processor caches.
288
- """
289
-
289
+ """Clear the request processor caches."""
290
290
  self._request_information_cache.clear()
291
291
  self._request_response_cache.clear()
292
292
  self._subscription_response_queue = asyncio.Queue(
@@ -71,9 +71,9 @@ class WebSocketProvider(PersistentConnectionProvider):
71
71
  # `PersistentConnectionProvider` kwargs can be passed through
72
72
  **kwargs: Any,
73
73
  ) -> None:
74
- self.endpoint_uri = URI(endpoint_uri)
75
- if self.endpoint_uri is None:
76
- self.endpoint_uri = get_default_endpoint()
74
+ self.endpoint_uri = (
75
+ URI(endpoint_uri) if endpoint_uri is not None else get_default_endpoint()
76
+ )
77
77
 
78
78
  if not any(
79
79
  self.endpoint_uri.startswith(prefix)
@@ -20,6 +20,10 @@ from eth_utils import (
20
20
  to_dict,
21
21
  )
22
22
 
23
+ from web3._utils.empty import (
24
+ Empty,
25
+ empty,
26
+ )
23
27
  from web3._utils.http import (
24
28
  construct_user_agent,
25
29
  )
@@ -54,9 +58,9 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
54
58
  self,
55
59
  endpoint_uri: Optional[Union[URI, str]] = None,
56
60
  request_kwargs: Optional[Any] = None,
57
- exception_retry_configuration: Optional[
58
- ExceptionRetryConfiguration
59
- ] = ExceptionRetryConfiguration(errors=(ClientError, TimeoutError)),
61
+ exception_retry_configuration: Union[
62
+ ExceptionRetryConfiguration, Empty
63
+ ] = empty,
60
64
  ) -> None:
61
65
  if endpoint_uri is None:
62
66
  self.endpoint_uri = get_default_http_endpoint()
@@ -64,7 +68,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
64
68
  self.endpoint_uri = URI(endpoint_uri)
65
69
 
66
70
  self._request_kwargs = request_kwargs or {}
67
- self.exception_retry_configuration = exception_retry_configuration
71
+ self._exception_retry_configuration = exception_retry_configuration
68
72
 
69
73
  super().__init__()
70
74
 
@@ -74,12 +78,25 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
74
78
  def __str__(self) -> str:
75
79
  return f"RPC connection {self.endpoint_uri}"
76
80
 
81
+ @property
82
+ def exception_retry_configuration(self) -> ExceptionRetryConfiguration:
83
+ if isinstance(self._exception_retry_configuration, Empty):
84
+ self._exception_retry_configuration = ExceptionRetryConfiguration(
85
+ errors=(ClientError, TimeoutError)
86
+ )
87
+ return self._exception_retry_configuration
88
+
89
+ @exception_retry_configuration.setter
90
+ def exception_retry_configuration(
91
+ self, value: Union[ExceptionRetryConfiguration, Empty]
92
+ ) -> None:
93
+ self._exception_retry_configuration = value
94
+
77
95
  @to_dict
78
96
  def get_request_kwargs(self) -> Iterable[Tuple[str, Any]]:
79
97
  if "headers" not in self._request_kwargs:
80
98
  yield "headers", self.get_request_headers()
81
- for key, value in self._request_kwargs.items():
82
- yield key, value
99
+ yield from self._request_kwargs.items()
83
100
 
84
101
  def get_request_headers(self) -> Dict[str, str]:
85
102
  return {
@@ -106,7 +123,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
106
123
  except tuple(self.exception_retry_configuration.errors):
107
124
  if i < self.exception_retry_configuration.retries - 1:
108
125
  await asyncio.sleep(
109
- self.exception_retry_configuration.backoff_factor
126
+ self.exception_retry_configuration.backoff_factor * 2**i
110
127
  )
111
128
  continue
112
129
  else:
web3/providers/rpc/rpc.py CHANGED
@@ -18,6 +18,10 @@ from eth_utils import (
18
18
  )
19
19
  import requests
20
20
 
21
+ from web3._utils.empty import (
22
+ Empty,
23
+ empty,
24
+ )
21
25
  from web3._utils.http import (
22
26
  construct_user_agent,
23
27
  )
@@ -51,26 +55,16 @@ if TYPE_CHECKING:
51
55
  class HTTPProvider(JSONBaseProvider):
52
56
  logger = logging.getLogger("web3.providers.HTTPProvider")
53
57
  endpoint_uri = None
54
-
55
- _request_args = None
56
58
  _request_kwargs = None
57
59
 
58
- exception_retry_configuration: Optional[ExceptionRetryConfiguration] = None
59
-
60
60
  def __init__(
61
61
  self,
62
62
  endpoint_uri: Optional[Union[URI, str]] = None,
63
63
  request_kwargs: Optional[Any] = None,
64
64
  session: Optional[Any] = None,
65
- exception_retry_configuration: Optional[ExceptionRetryConfiguration] = (
66
- ExceptionRetryConfiguration(
67
- errors=(
68
- ConnectionError,
69
- requests.HTTPError,
70
- requests.Timeout,
71
- )
72
- )
73
- ),
65
+ exception_retry_configuration: Union[
66
+ ExceptionRetryConfiguration, Empty
67
+ ] = empty,
74
68
  ) -> None:
75
69
  if endpoint_uri is None:
76
70
  self.endpoint_uri = get_default_http_endpoint()
@@ -78,7 +72,7 @@ class HTTPProvider(JSONBaseProvider):
78
72
  self.endpoint_uri = URI(endpoint_uri)
79
73
 
80
74
  self._request_kwargs = request_kwargs or {}
81
- self.exception_retry_configuration = exception_retry_configuration
75
+ self._exception_retry_configuration = exception_retry_configuration
82
76
 
83
77
  if session:
84
78
  cache_and_return_session(self.endpoint_uri, session)
@@ -88,12 +82,29 @@ class HTTPProvider(JSONBaseProvider):
88
82
  def __str__(self) -> str:
89
83
  return f"RPC connection {self.endpoint_uri}"
90
84
 
85
+ @property
86
+ def exception_retry_configuration(self) -> ExceptionRetryConfiguration:
87
+ if isinstance(self._exception_retry_configuration, Empty):
88
+ self._exception_retry_configuration = ExceptionRetryConfiguration(
89
+ errors=(
90
+ ConnectionError,
91
+ requests.HTTPError,
92
+ requests.Timeout,
93
+ )
94
+ )
95
+ return self._exception_retry_configuration
96
+
97
+ @exception_retry_configuration.setter
98
+ def exception_retry_configuration(
99
+ self, value: Union[ExceptionRetryConfiguration, Empty]
100
+ ) -> None:
101
+ self._exception_retry_configuration = value
102
+
91
103
  @to_dict
92
104
  def get_request_kwargs(self) -> Iterable[Tuple[str, Any]]:
93
105
  if "headers" not in self._request_kwargs:
94
106
  yield "headers", self.get_request_headers()
95
- for key, value in self._request_kwargs.items():
96
- yield key, value
107
+ yield from self._request_kwargs.items()
97
108
 
98
109
  def get_request_headers(self) -> Dict[str, str]:
99
110
  return {
@@ -119,7 +130,9 @@ class HTTPProvider(JSONBaseProvider):
119
130
  )
120
131
  except tuple(self.exception_retry_configuration.errors) as e:
121
132
  if i < self.exception_retry_configuration.retries - 1:
122
- time.sleep(self.exception_retry_configuration.backoff_factor)
133
+ time.sleep(
134
+ self.exception_retry_configuration.backoff_factor * 2**i
135
+ )
123
136
  continue
124
137
  else:
125
138
  raise e
@@ -58,15 +58,6 @@ REQUEST_RETRY_ALLOWLIST = [
58
58
  "eth_sign",
59
59
  "eth_signTypedData",
60
60
  "eth_sendRawTransaction",
61
- "personal_importRawKey",
62
- "personal_newAccount",
63
- "personal_listAccounts",
64
- "personal_listWallets",
65
- "personal_lockAccount",
66
- "personal_unlockAccount",
67
- "personal_ecRecover",
68
- "personal_sign",
69
- "personal_signTypedData",
70
61
  ]
71
62
 
72
63
 
@@ -93,7 +84,7 @@ class ExceptionRetryConfiguration(BaseModel):
93
84
  self,
94
85
  errors: Sequence[Type[BaseException]] = None,
95
86
  retries: int = 5,
96
- backoff_factor: float = 0.5,
87
+ backoff_factor: float = 0.125,
97
88
  method_allowlist: Sequence[str] = None,
98
89
  ):
99
90
  super().__init__(
web3/testing.py CHANGED
@@ -12,21 +12,21 @@ from web3.module import (
12
12
 
13
13
  class Testing(Module):
14
14
  def timeTravel(self, timestamp: int) -> None:
15
- return self.w3.manager.request_blocking(RPC.testing_timeTravel, [timestamp])
15
+ self.w3.manager.request_blocking(RPC.testing_timeTravel, [timestamp])
16
16
 
17
17
  def mine(self, num_blocks: int = 1) -> None:
18
- return self.w3.manager.request_blocking(RPC.evm_mine, [num_blocks])
18
+ self.w3.manager.request_blocking(RPC.evm_mine, [num_blocks])
19
19
 
20
20
  def snapshot(self) -> int:
21
21
  self.last_snapshot_idx = self.w3.manager.request_blocking(RPC.evm_snapshot, [])
22
22
  return self.last_snapshot_idx
23
23
 
24
24
  def reset(self) -> None:
25
- return self.w3.manager.request_blocking(RPC.evm_reset, [])
25
+ self.w3.manager.request_blocking(RPC.evm_reset, [])
26
26
 
27
27
  def revert(self, snapshot_idx: Optional[int] = None) -> None:
28
28
  if snapshot_idx is None:
29
29
  revert_target = self.last_snapshot_idx
30
30
  else:
31
31
  revert_target = snapshot_idx
32
- return self.w3.manager.request_blocking(RPC.evm_revert, [revert_target])
32
+ self.w3.manager.request_blocking(RPC.evm_revert, [revert_target])