web3 7.0.0b3__py3-none-any.whl → 7.0.0b4__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 (79) 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 +12 -12
  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 +20 -18
  23. web3/_utils/fee_utils.py +2 -4
  24. web3/_utils/filters.py +17 -12
  25. web3/_utils/formatters.py +2 -2
  26. web3/_utils/math.py +3 -2
  27. web3/_utils/method_formatters.py +24 -5
  28. web3/_utils/module.py +2 -1
  29. web3/_utils/module_testing/eth_module.py +62 -69
  30. web3/_utils/module_testing/go_ethereum_personal_module.py +1 -1
  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 -1
  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 +12 -7
  41. web3/contract/base_contract.py +50 -56
  42. web3/contract/contract.py +12 -6
  43. web3/contract/utils.py +11 -6
  44. web3/datastructures.py +22 -12
  45. web3/eth/async_eth.py +33 -28
  46. web3/eth/base_eth.py +7 -3
  47. web3/eth/eth.py +18 -13
  48. web3/exceptions.py +30 -59
  49. web3/gas_strategies/time_based.py +2 -4
  50. web3/geth.py +1 -3
  51. web3/main.py +6 -2
  52. web3/manager.py +7 -5
  53. web3/method.py +13 -5
  54. web3/middleware/base.py +4 -2
  55. web3/middleware/filter.py +27 -17
  56. web3/middleware/formatting.py +6 -3
  57. web3/middleware/names.py +4 -1
  58. web3/middleware/signing.py +6 -2
  59. web3/middleware/stalecheck.py +2 -1
  60. web3/providers/eth_tester/defaults.py +1 -1
  61. web3/providers/eth_tester/main.py +5 -4
  62. web3/providers/eth_tester/middleware.py +10 -1
  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 +23 -6
  69. web3/providers/rpc/rpc.py +27 -16
  70. web3/testing.py +4 -4
  71. web3/tools/benchmark/main.py +13 -9
  72. web3/tools/benchmark/utils.py +1 -1
  73. web3/tracing.py +9 -5
  74. web3/types.py +19 -22
  75. {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/METADATA +13 -28
  76. {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/RECORD +79 -79
  77. {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/LICENSE +0 -0
  78. {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/WHEEL +0 -0
  79. {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/top_level.txt +0 -0
web3/geth.py CHANGED
@@ -5,6 +5,7 @@ from typing import (
5
5
  Dict,
6
6
  List,
7
7
  Optional,
8
+ Protocol,
8
9
  Tuple,
9
10
  )
10
11
 
@@ -18,9 +19,6 @@ from hexbytes.main import (
18
19
  HexBytes,
19
20
  )
20
21
 
21
- from web3._utils.compat import (
22
- Protocol,
23
- )
24
22
  from web3._utils.rpc_abi import (
25
23
  RPC,
26
24
  )
web3/main.py CHANGED
@@ -84,6 +84,10 @@ from web3.eth import (
84
84
  AsyncEth,
85
85
  Eth,
86
86
  )
87
+ from web3.exceptions import (
88
+ Web3TypeError,
89
+ Web3ValueError,
90
+ )
87
91
  from web3.geth import (
88
92
  AsyncGeth,
89
93
  AsyncGethAdmin,
@@ -283,7 +287,7 @@ class BaseWeb3:
283
287
  input_bytes = to_bytes(primitive, hexstr=hexstr, text=text)
284
288
  return eth_utils_keccak(input_bytes)
285
289
 
286
- raise TypeError(
290
+ raise Web3TypeError(
287
291
  f"You called keccak with first arg {primitive!r} and keywords "
288
292
  f"{{'text': {text!r}, 'hexstr': {hexstr!r}}}. You must call it with "
289
293
  "one of these approaches: keccak(text='txt'), keccak(hexstr='0x747874'), "
@@ -304,7 +308,7 @@ class BaseWeb3:
304
308
  and list of corresponding values -- `[20, [-1, 5, 0], True]`
305
309
  """
306
310
  if len(abi_types) != len(values):
307
- raise ValueError(
311
+ raise Web3ValueError(
308
312
  "Length mismatch between provided abi types and values. Got "
309
313
  f"{len(abi_types)} types and {len(values)} values."
310
314
  )
web3/manager.py CHANGED
@@ -35,6 +35,8 @@ from web3.exceptions import (
35
35
  BadResponseFormat,
36
36
  MethodUnavailable,
37
37
  ProviderConnectionError,
38
+ Web3TypeError,
39
+ Web3ValueError,
38
40
  )
39
41
  from web3.middleware import (
40
42
  AttributeDictMiddleware,
@@ -238,7 +240,7 @@ class RequestManager:
238
240
  error = response.get("error")
239
241
  # Raise the error when the value is a string
240
242
  if error is None or isinstance(error, str):
241
- raise ValueError(error)
243
+ raise Web3ValueError(error)
242
244
 
243
245
  # Errors must include an integer code
244
246
  code = error.get("code")
@@ -259,7 +261,7 @@ class RequestManager:
259
261
 
260
262
  apply_error_formatters(error_formatters, response)
261
263
 
262
- raise ValueError(error)
264
+ raise Web3ValueError(error)
263
265
 
264
266
  # Format and validate results
265
267
  elif "result" in response:
@@ -323,8 +325,8 @@ class RequestManager:
323
325
  cast("AsyncWeb3", self.w3), cast("MiddlewareOnion", self.middleware_onion)
324
326
  )
325
327
  self.logger.debug(
326
- "Making request to open socket connection - "
327
- f"uri: {provider.endpoint_uri}, method: {method}"
328
+ "Making request to open socket connection: "
329
+ f"{provider.get_endpoint_uri_or_ipc_path()}, method: {method}"
328
330
  )
329
331
  response = await request_func(method, params)
330
332
  return await self._process_response(response)
@@ -337,7 +339,7 @@ class RequestManager:
337
339
 
338
340
  async def _message_stream(self) -> AsyncGenerator[RPCResponse, None]:
339
341
  if not isinstance(self._provider, PersistentConnectionProvider):
340
- raise TypeError(
342
+ raise Web3TypeError(
341
343
  "Only providers that maintain an open, persistent connection "
342
344
  "can listen to streams."
343
345
  )
web3/method.py CHANGED
@@ -32,7 +32,9 @@ from web3._utils.rpc_abi import (
32
32
  RPC,
33
33
  )
34
34
  from web3.exceptions import (
35
+ Web3TypeError,
35
36
  Web3ValidationError,
37
+ Web3ValueError,
36
38
  )
37
39
  from web3.types import (
38
40
  RPCEndpoint,
@@ -66,7 +68,9 @@ def _set_mungers(
66
68
  return (
67
69
  mungers
68
70
  if mungers
69
- else [default_munger] if is_property else [default_root_munger]
71
+ else [default_munger]
72
+ if is_property
73
+ else [default_root_munger]
70
74
  )
71
75
 
72
76
 
@@ -84,7 +88,8 @@ TFunc = TypeVar("TFunc", bound=Callable[..., Any])
84
88
 
85
89
 
86
90
  class Method(Generic[TFunc]):
87
- """Method object for web3 module methods
91
+ """
92
+ Method object for web3 module methods
88
93
 
89
94
  Calls to the Method go through these steps:
90
95
 
@@ -147,7 +152,7 @@ class Method(Generic[TFunc]):
147
152
  self, obj: Optional["Module"] = None, obj_type: Optional[Type["Module"]] = None
148
153
  ) -> TFunc:
149
154
  if obj is None:
150
- raise TypeError(
155
+ raise Web3TypeError(
151
156
  "Direct calls to methods are not supported. "
152
157
  "Methods must be called from an module instance, "
153
158
  "usually attached to a web3 instance."
@@ -163,7 +168,7 @@ class Method(Generic[TFunc]):
163
168
  return self.json_rpc_method
164
169
  elif isinstance(self.json_rpc_method, (str,)):
165
170
  return lambda *_: self.json_rpc_method
166
- raise ValueError(
171
+ raise Web3ValueError(
167
172
  "``json_rpc_method`` config invalid. May be a string or function"
168
173
  )
169
174
 
@@ -175,7 +180,9 @@ class Method(Generic[TFunc]):
175
180
  lambda args, munger: munger(module, *args, **kwargs), self.mungers, args
176
181
  )
177
182
 
178
- def process_params(self, module: "Module", *args: Any, **kwargs: Any) -> Tuple[
183
+ def process_params(
184
+ self, module: "Module", *args: Any, **kwargs: Any
185
+ ) -> Tuple[
179
186
  Tuple[Union[RPCEndpoint, Callable[..., RPCEndpoint]], Tuple[Any, ...]],
180
187
  Tuple[
181
188
  Union[TReturn, Dict[str, Callable[..., Any]]],
@@ -226,5 +233,6 @@ class DeprecatedMethod:
226
233
  warnings.warn(
227
234
  f"{self.old_name} is deprecated in favor of {self.new_name}",
228
235
  category=DeprecationWarning,
236
+ stacklevel=2,
229
237
  )
230
238
  return self.method.__get__(obj, obj_type)
web3/middleware/base.py CHANGED
@@ -48,7 +48,9 @@ class Web3Middleware:
48
48
  def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
49
49
  return method, params
50
50
 
51
- def response_processor(self, method: "RPCEndpoint", response: "RPCResponse") -> Any:
51
+ def response_processor(
52
+ self, method: "RPCEndpoint", response: "RPCResponse"
53
+ ) -> "RPCResponse":
52
54
  return response
53
55
 
54
56
  # -- async -- #
@@ -76,7 +78,7 @@ class Web3Middleware:
76
78
  self,
77
79
  method: "RPCEndpoint",
78
80
  response: "RPCResponse",
79
- ) -> Any:
81
+ ) -> "RPCResponse":
80
82
  return response
81
83
 
82
84
 
web3/middleware/filter.py CHANGED
@@ -42,6 +42,9 @@ from web3._utils.formatters import (
42
42
  from web3._utils.rpc_abi import (
43
43
  RPC,
44
44
  )
45
+ from web3.exceptions import (
46
+ Web3TypeError,
47
+ )
45
48
  from web3.middleware.base import (
46
49
  Web3Middleware,
47
50
  )
@@ -71,7 +74,8 @@ else:
71
74
 
72
75
 
73
76
  def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, int]]:
74
- """Creates a segment counting generator
77
+ """
78
+ Creates a segment counting generator
75
79
 
76
80
  The generator returns tuple pairs of integers
77
81
  that correspond to segments in the provided range.
@@ -84,6 +88,7 @@ def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, i
84
88
 
85
89
 
86
90
  Example:
91
+ -------
87
92
 
88
93
  >>> segment_counter = segment_count(start=0, stop=10, step=3)
89
94
  >>> next(segment_counter)
@@ -94,6 +99,7 @@ def segment_count(start: int, stop: int, step: int = 5) -> Iterable[Tuple[int, i
94
99
  (6, 9)
95
100
  >>> next(segment_counter) # Remainder is also returned
96
101
  (9, 10)
102
+
97
103
  """
98
104
  return gen_bounded_segments(start, stop, step)
99
105
 
@@ -104,10 +110,9 @@ def gen_bounded_segments(start: int, stop: int, step: int) -> Iterable[Tuple[int
104
110
  if start + step >= stop:
105
111
  yield (start, stop)
106
112
  return
107
- for segment in zip(
113
+ yield from zip(
108
114
  range(start, stop - step + 1, step), range(start + step, stop + 1, step)
109
- ):
110
- yield segment
115
+ )
111
116
 
112
117
  remainder = (stop - start) % step
113
118
  # Handle the remainder
@@ -118,13 +123,14 @@ def gen_bounded_segments(start: int, stop: int, step: int) -> Iterable[Tuple[int
118
123
  def block_ranges(
119
124
  start_block: BlockNumber, last_block: Optional[BlockNumber], step: int = 5
120
125
  ) -> Iterable[Tuple[BlockNumber, BlockNumber]]:
121
- """Returns 2-tuple ranges describing ranges of block from start_block to last_block
126
+ """
127
+ Returns 2-tuple ranges describing ranges of block from start_block to last_block
122
128
 
123
129
  Ranges do not overlap to facilitate use as ``toBlock``, ``fromBlock``
124
130
  json-rpc arguments, which are both inclusive.
125
131
  """
126
132
  if last_block is not None and start_block > last_block:
127
- raise TypeError(
133
+ raise Web3TypeError(
128
134
  "Incompatible start and stop arguments.",
129
135
  "Start must be less than or equal to stop.",
130
136
  )
@@ -138,7 +144,8 @@ def block_ranges(
138
144
  def iter_latest_block(
139
145
  w3: "Web3", to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None
140
146
  ) -> Iterable[BlockNumber]:
141
- """Returns a generator that dispenses the latest block, if
147
+ """
148
+ Returns a generator that dispenses the latest block, if
142
149
  any new blocks have been mined since last iteration.
143
150
 
144
151
  If there are no new blocks or the latest block is greater than
@@ -160,8 +167,7 @@ def iter_latest_block(
160
167
 
161
168
  while True:
162
169
  latest_block = w3.eth.block_number
163
- # type ignored b/c is_bounded_range prevents unsupported comparison
164
- if is_bounded_range and latest_block > to_block: # type: ignore
170
+ if is_bounded_range and latest_block > to_block:
165
171
  yield None
166
172
  # No new blocks since last iteration.
167
173
  if _last is not None and _last == latest_block:
@@ -176,7 +182,8 @@ def iter_latest_block_ranges(
176
182
  from_block: BlockNumber,
177
183
  to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
178
184
  ) -> Iterable[Tuple[Optional[BlockNumber], Optional[BlockNumber]]]:
179
- """Returns an iterator unloading ranges of available blocks
185
+ """
186
+ Returns an iterator unloading ranges of available blocks
180
187
 
181
188
  starting from `fromBlock` to the latest mined block,
182
189
  until reaching toBlock. e.g.:
@@ -212,7 +219,8 @@ def get_logs_multipart(
212
219
  topics: List[Optional[Union[_Hash32, List[_Hash32]]]],
213
220
  max_blocks: int,
214
221
  ) -> Iterable[List[LogReceipt]]:
215
- """Used to break up requests to ``eth_getLogs``
222
+ """
223
+ Used to break up requests to ``eth_getLogs``
216
224
 
217
225
  The getLog request is partitioned into multiple calls of the max number of blocks
218
226
  ``max_blocks``.
@@ -247,9 +255,8 @@ class RequestLogs:
247
255
  if from_block is None or from_block == "latest":
248
256
  self._from_block = BlockNumber(w3.eth.block_number + 1)
249
257
  elif is_string(from_block) and is_hex(from_block):
250
- self._from_block = BlockNumber(hex_to_integer(from_block)) # type: ignore
258
+ self._from_block = BlockNumber(hex_to_integer(from_block))
251
259
  else:
252
- # cast b/c LatestBlockParam is handled above
253
260
  self._from_block = from_block
254
261
  self._to_block = to_block
255
262
  self.filter_changes = self._get_filter_changes()
@@ -265,7 +272,7 @@ class RequestLogs:
265
272
  elif self._to_block == "latest":
266
273
  to_block = self.w3.eth.block_number
267
274
  elif is_string(self._to_block) and is_hex(self._to_block):
268
- to_block = BlockNumber(hex_to_integer(self._to_block)) # type: ignore
275
+ to_block = BlockNumber(hex_to_integer(self._to_block))
269
276
  else:
270
277
  to_block = self._to_block
271
278
 
@@ -352,7 +359,8 @@ def block_hashes_in_range(
352
359
  async def async_iter_latest_block(
353
360
  w3: "AsyncWeb3", to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None
354
361
  ) -> AsyncIterable[BlockNumber]:
355
- """Returns a generator that dispenses the latest block, if
362
+ """
363
+ Returns a generator that dispenses the latest block, if
356
364
  any new blocks have been mined since last iteration.
357
365
 
358
366
  If there are no new blocks or the latest block is greater than
@@ -390,7 +398,8 @@ async def async_iter_latest_block_ranges(
390
398
  from_block: BlockNumber,
391
399
  to_block: Optional[Union[BlockNumber, LatestBlockParam]] = None,
392
400
  ) -> AsyncIterable[Tuple[Optional[BlockNumber], Optional[BlockNumber]]]:
393
- """Returns an iterator unloading ranges of available blocks
401
+ """
402
+ Returns an iterator unloading ranges of available blocks
394
403
 
395
404
  starting from `from_block` to the latest mined block,
396
405
  until reaching to_block. e.g.:
@@ -423,7 +432,8 @@ async def async_get_logs_multipart(
423
432
  topics: List[Optional[Union[_Hash32, List[_Hash32]]]],
424
433
  max_blocks: int,
425
434
  ) -> AsyncIterable[List[LogReceipt]]:
426
- """Used to break up requests to ``eth_getLogs``
435
+ """
436
+ Used to break up requests to ``eth_getLogs``
427
437
 
428
438
  The getLog request is partitioned into multiple calls of the max number of blocks
429
439
  ``max_blocks``.
@@ -3,6 +3,7 @@ from typing import (
3
3
  Any,
4
4
  Callable,
5
5
  Coroutine,
6
+ Literal,
6
7
  Optional,
7
8
  Union,
8
9
  cast,
@@ -14,6 +15,9 @@ from eth_utils.toolz import (
14
15
  merge,
15
16
  )
16
17
 
18
+ from web3.exceptions import (
19
+ Web3ValueError,
20
+ )
17
21
  from web3.middleware.base import (
18
22
  Web3MiddlewareBuilder,
19
23
  )
@@ -21,7 +25,6 @@ from web3.types import (
21
25
  EthSubscriptionParams,
22
26
  Formatters,
23
27
  FormattersDict,
24
- Literal,
25
28
  RPCEndpoint,
26
29
  RPCResponse,
27
30
  )
@@ -118,7 +121,7 @@ class FormattingMiddlewareBuilder(Web3MiddlewareBuilder):
118
121
  if (
119
122
  sync_formatters_builder is None and async_formatters_builder is not None
120
123
  ) or (sync_formatters_builder is not None and async_formatters_builder is None):
121
- raise ValueError(
124
+ raise Web3ValueError(
122
125
  "Must specify both sync_formatters_builder and async_formatters_builder"
123
126
  )
124
127
 
@@ -128,7 +131,7 @@ class FormattingMiddlewareBuilder(Web3MiddlewareBuilder):
128
131
  or result_formatters is not None
129
132
  or error_formatters is not None
130
133
  ):
131
- raise ValueError(
134
+ raise Web3ValueError(
132
135
  "Cannot specify formatters_builder and formatters at the same time"
133
136
  )
134
137
 
web3/middleware/names.py CHANGED
@@ -31,6 +31,9 @@ from .._utils.abi import (
31
31
  from .._utils.formatters import (
32
32
  recursive_map,
33
33
  )
34
+ from ..exceptions import (
35
+ Web3TypeError,
36
+ )
34
37
  from .base import (
35
38
  Web3Middleware,
36
39
  )
@@ -92,7 +95,7 @@ async def async_apply_ens_to_address_conversion(
92
95
  return (formatted_params_dict, *params[1:])
93
96
 
94
97
  else:
95
- raise TypeError(
98
+ raise Web3TypeError(
96
99
  f"ABI definitions must be a list or dictionary, "
97
100
  f"got {abi_types_for_method!r}"
98
101
  )
@@ -55,6 +55,9 @@ from web3._utils.transactions import (
55
55
  fill_nonce,
56
56
  fill_transaction_defaults,
57
57
  )
58
+ from web3.exceptions import (
59
+ Web3TypeError,
60
+ )
58
61
  from web3.middleware.base import (
59
62
  Web3MiddlewareBuilder,
60
63
  )
@@ -108,7 +111,7 @@ def gen_normalized_accounts(
108
111
 
109
112
  @singledispatch
110
113
  def to_account(val: Any) -> LocalAccount:
111
- raise TypeError(
114
+ raise Web3TypeError(
112
115
  "key must be one of the types: "
113
116
  "eth_keys.datatype.PrivateKey, eth_account.signers.local.LocalAccount, "
114
117
  "or raw private key as a hex string or byte string. "
@@ -132,7 +135,8 @@ to_account.register(bytes, private_key_to_account)
132
135
 
133
136
 
134
137
  def format_transaction(transaction: TxParams) -> TxParams:
135
- """Format transaction so that it can be used correctly in the signing middleware.
138
+ """
139
+ Format transaction so that it can be used correctly in the signing middleware.
136
140
 
137
141
  Converts bytes to hex strings and other types that can be passed to
138
142
  the underlying layers. Also has the effect of normalizing 'from' for
@@ -16,6 +16,7 @@ from toolz import (
16
16
 
17
17
  from web3.exceptions import (
18
18
  StaleBlockchain,
19
+ Web3ValueError,
19
20
  )
20
21
  from web3.middleware.base import (
21
22
  Web3Middleware,
@@ -54,7 +55,7 @@ class StalecheckMiddlewareBuilder(Web3MiddlewareBuilder):
54
55
  skip_stalecheck_for_methods: Collection[str] = SKIP_STALECHECK_FOR_METHODS,
55
56
  ) -> Web3Middleware:
56
57
  if allowable_delay <= 0:
57
- raise ValueError(
58
+ raise Web3ValueError(
58
59
  "You must set a positive allowable_delay in seconds for this middleware"
59
60
  )
60
61
  middleware = StalecheckMiddlewareBuilder(w3)
@@ -218,7 +218,7 @@ def _generate_random_private_key() -> HexStr:
218
218
  WARNING: This is not a secure way to generate private keys and should only
219
219
  be used for testing purposes.
220
220
  """
221
- return encode_hex(bytes(bytearray((random.randint(0, 255) for _ in range(32)))))
221
+ return encode_hex(bytes(bytearray(random.randint(0, 255) for _ in range(32))))
222
222
 
223
223
 
224
224
  @without_params
@@ -4,6 +4,7 @@ from typing import (
4
4
  Callable,
5
5
  Coroutine,
6
6
  Dict,
7
+ Literal,
7
8
  Optional,
8
9
  Union,
9
10
  )
@@ -18,9 +19,6 @@ from eth_utils import (
18
19
  is_bytes,
19
20
  )
20
21
 
21
- from web3._utils.compat import (
22
- Literal,
23
- )
24
22
  from web3.providers import (
25
23
  BaseProvider,
26
24
  )
@@ -33,6 +31,9 @@ from web3.types import (
33
31
  RPCResponse,
34
32
  )
35
33
 
34
+ from ...exceptions import (
35
+ Web3TypeError,
36
+ )
36
37
  from ...middleware import (
37
38
  async_combine_middleware,
38
39
  combine_middleware,
@@ -133,7 +134,7 @@ class EthereumTesterProvider(BaseProvider):
133
134
  elif isinstance(ethereum_tester, BaseChainBackend):
134
135
  self.ethereum_tester = EthereumTester(ethereum_tester)
135
136
  else:
136
- raise TypeError(
137
+ raise Web3TypeError(
137
138
  "Expected ethereum_tester to be of type `eth_tester.EthereumTester` or "
138
139
  "a subclass of `eth_tester.backends.base.BaseChainBackend`, "
139
140
  f"instead received {type(ethereum_tester)}. "
@@ -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)
@@ -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
 
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