web3 7.0.0b8__py3-none-any.whl → 7.0.0b9__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 (44) hide show
  1. ens/async_ens.py +16 -7
  2. ens/base_ens.py +3 -1
  3. ens/exceptions.py +2 -7
  4. ens/utils.py +0 -17
  5. web3/_utils/abi.py +100 -257
  6. web3/_utils/compat/__init__.py +1 -0
  7. web3/_utils/contracts.py +116 -205
  8. web3/_utils/encoding.py +4 -5
  9. web3/_utils/events.py +28 -33
  10. web3/_utils/fee_utils.py +2 -2
  11. web3/_utils/filters.py +2 -5
  12. web3/_utils/http_session_manager.py +30 -7
  13. web3/_utils/method_formatters.py +3 -3
  14. web3/_utils/module_testing/eth_module.py +59 -37
  15. web3/_utils/module_testing/module_testing_utils.py +43 -1
  16. web3/_utils/module_testing/persistent_connection_provider.py +2 -0
  17. web3/_utils/module_testing/web3_module.py +8 -8
  18. web3/_utils/normalizers.py +10 -8
  19. web3/_utils/validation.py +5 -7
  20. web3/contract/async_contract.py +18 -17
  21. web3/contract/base_contract.py +116 -80
  22. web3/contract/contract.py +16 -17
  23. web3/contract/utils.py +86 -55
  24. web3/eth/async_eth.py +1 -2
  25. web3/eth/eth.py +1 -2
  26. web3/exceptions.py +22 -9
  27. web3/gas_strategies/time_based.py +4 -0
  28. web3/manager.py +34 -12
  29. web3/middleware/filter.py +3 -3
  30. web3/middleware/signing.py +6 -1
  31. web3/types.py +5 -45
  32. web3/utils/__init__.py +48 -4
  33. web3/utils/abi.py +575 -10
  34. {web3-7.0.0b8.dist-info → web3-7.0.0b9.dist-info}/METADATA +7 -5
  35. {web3-7.0.0b8.dist-info → web3-7.0.0b9.dist-info}/RECORD +39 -44
  36. {web3-7.0.0b8.dist-info → web3-7.0.0b9.dist-info}/WHEEL +1 -1
  37. web3/tools/benchmark/__init__.py +0 -0
  38. web3/tools/benchmark/main.py +0 -190
  39. web3/tools/benchmark/node.py +0 -120
  40. web3/tools/benchmark/reporting.py +0 -39
  41. web3/tools/benchmark/utils.py +0 -69
  42. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  43. {web3-7.0.0b8.dist-info → web3-7.0.0b9.dist-info}/LICENSE +0 -0
  44. {web3-7.0.0b8.dist-info → web3-7.0.0b9.dist-info}/top_level.txt +0 -0
web3/_utils/contracts.py CHANGED
@@ -4,10 +4,10 @@ from typing import (
4
4
  Any,
5
5
  Callable,
6
6
  Dict,
7
+ List,
7
8
  Optional,
8
9
  Sequence,
9
10
  Tuple,
10
- Type,
11
11
  Union,
12
12
  cast,
13
13
  )
@@ -19,6 +19,14 @@ from eth_abi.registry import (
19
19
  registry as default_registry,
20
20
  )
21
21
  from eth_typing import (
22
+ ABI,
23
+ ABICallable,
24
+ ABIConstructor,
25
+ ABIElement,
26
+ ABIEvent,
27
+ ABIFallback,
28
+ ABIFunction,
29
+ ABIReceive,
22
30
  ChecksumAddress,
23
31
  HexStr,
24
32
  TypeStr,
@@ -26,11 +34,9 @@ from eth_typing import (
26
34
  from eth_utils import (
27
35
  add_0x_prefix,
28
36
  encode_hex,
29
- function_abi_to_4byte_selector,
30
- is_binary_address,
31
- is_checksum_address,
32
- is_list_like,
33
- is_text,
37
+ filter_abi_by_name,
38
+ filter_abi_by_type,
39
+ get_abi_input_types,
34
40
  )
35
41
  from eth_utils.toolz import (
36
42
  pipe,
@@ -40,31 +46,20 @@ from hexbytes import (
40
46
  )
41
47
 
42
48
  from web3._utils.abi import (
43
- abi_to_signature,
44
- check_if_arguments_can_be_encoded,
45
- filter_by_argument_count,
46
49
  filter_by_argument_name,
47
- filter_by_encodability,
48
- filter_by_name,
49
- filter_by_type,
50
- get_abi_input_types,
51
- get_aligned_abi_inputs,
52
- get_fallback_func_abi,
53
- get_receive_func_abi,
54
50
  map_abi_data,
55
- merge_args_and_kwargs,
56
51
  named_tree,
57
52
  )
53
+ from web3._utils.abi_element_identifiers import (
54
+ FallbackFn,
55
+ ReceiveFn,
56
+ )
58
57
  from web3._utils.blocks import (
59
58
  is_hex_encoded_block_hash,
60
59
  )
61
60
  from web3._utils.encoding import (
62
61
  to_hex,
63
62
  )
64
- from web3._utils.function_identifiers import (
65
- FallbackFn,
66
- ReceiveFn,
67
- )
68
63
  from web3._utils.method_formatters import (
69
64
  to_integer_if_hex,
70
65
  )
@@ -81,13 +76,16 @@ from web3.exceptions import (
81
76
  Web3ValueError,
82
77
  )
83
78
  from web3.types import (
84
- ABI,
85
- ABIEvent,
86
- ABIFunction,
79
+ ABIElementIdentifier,
87
80
  BlockIdentifier,
88
81
  BlockNumber,
89
82
  TxParams,
90
83
  )
84
+ from web3.utils.abi import (
85
+ check_if_arguments_can_be_encoded,
86
+ get_abi_element,
87
+ get_abi_element_info,
88
+ )
91
89
 
92
90
  if TYPE_CHECKING:
93
91
  from web3 import ( # noqa: F401
@@ -96,44 +94,22 @@ if TYPE_CHECKING:
96
94
  )
97
95
 
98
96
 
99
- def extract_argument_types(*args: Sequence[Any]) -> str:
100
- """
101
- Takes a list of arguments and returns a string representation of the argument types,
102
- appropriately collapsing `tuple` types into the respective nested types.
103
- """
104
- collapsed_args = []
105
-
106
- for arg in args:
107
- if is_list_like(arg):
108
- collapsed_nested = []
109
- for nested in arg:
110
- if is_list_like(nested):
111
- collapsed_nested.append(f"({extract_argument_types(nested)})")
112
- else:
113
- collapsed_nested.append(_get_argument_readable_type(nested))
114
- collapsed_args.append(",".join(collapsed_nested))
115
- else:
116
- collapsed_args.append(_get_argument_readable_type(arg))
117
-
118
- return ",".join(collapsed_args)
119
-
120
-
121
97
  def find_matching_event_abi(
122
98
  abi: ABI,
123
99
  event_name: Optional[str] = None,
124
100
  argument_names: Optional[Sequence[str]] = None,
125
101
  ) -> ABIEvent:
126
- filters = [
127
- functools.partial(filter_by_type, "event"),
102
+ filters: List[functools.partial[Sequence[ABIElement]]] = [
103
+ functools.partial(filter_abi_by_type, "event"),
128
104
  ]
129
105
 
130
106
  if event_name is not None:
131
- filters.append(functools.partial(filter_by_name, event_name))
107
+ filters.append(functools.partial(filter_abi_by_name, event_name))
132
108
 
133
109
  if argument_names is not None:
134
110
  filters.append(functools.partial(filter_by_argument_name, argument_names))
135
111
 
136
- event_abi_candidates = pipe(abi, *filters)
112
+ event_abi_candidates: Sequence[ABIEvent] = pipe(abi, *filters)
137
113
 
138
114
  if len(event_abi_candidates) == 1:
139
115
  return event_abi_candidates[0]
@@ -143,82 +119,24 @@ def find_matching_event_abi(
143
119
  raise Web3ValueError("Multiple events found")
144
120
 
145
121
 
146
- def find_matching_fn_abi(
147
- abi: ABI,
148
- abi_codec: ABICodec,
149
- fn_identifier: Optional[Union[str, Type[FallbackFn], Type[ReceiveFn]]] = None,
150
- args: Optional[Sequence[Any]] = None,
151
- kwargs: Optional[Any] = None,
152
- ) -> ABIFunction:
153
- args = args or tuple()
154
- kwargs = kwargs or dict()
155
- num_arguments = len(args) + len(kwargs)
156
-
157
- if fn_identifier is FallbackFn:
158
- return get_fallback_func_abi(abi)
159
-
160
- if fn_identifier is ReceiveFn:
161
- return get_receive_func_abi(abi)
162
-
163
- if not is_text(fn_identifier):
164
- raise Web3TypeError("Unsupported function identifier")
165
-
166
- name_filter = functools.partial(filter_by_name, fn_identifier)
167
- arg_count_filter = functools.partial(filter_by_argument_count, num_arguments)
168
- encoding_filter = functools.partial(filter_by_encodability, abi_codec, args, kwargs)
169
-
170
- function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter)
171
-
172
- if len(function_candidates) == 1:
173
- return function_candidates[0]
174
- else:
175
- matching_identifiers = name_filter(abi)
176
- matching_function_signatures = [
177
- abi_to_signature(func) for func in matching_identifiers
178
- ]
179
-
180
- arg_count_matches = len(arg_count_filter(matching_identifiers))
181
- encoding_matches = len(encoding_filter(matching_identifiers))
182
-
183
- if arg_count_matches == 0:
184
- diagnosis = (
185
- "\nFunction invocation failed due to improper number of arguments."
186
- )
187
- elif encoding_matches == 0:
188
- diagnosis = (
189
- "\nFunction invocation failed due to no matching argument types."
190
- )
191
- elif encoding_matches > 1:
192
- diagnosis = (
193
- "\nAmbiguous argument encoding. "
194
- "Provided arguments can be encoded to multiple functions "
195
- "matching this call."
196
- )
197
-
198
- collapsed_args = extract_argument_types(args)
199
- collapsed_kwargs = dict(
200
- {(k, extract_argument_types([v])) for k, v in kwargs.items()}
201
- )
202
- message = (
203
- f"\nCould not identify the intended function with name `{fn_identifier}`, "
204
- f"positional arguments with type(s) `{collapsed_args}` and "
205
- f"keyword arguments with type(s) `{collapsed_kwargs}`."
206
- f"\nFound {len(matching_identifiers)} function(s) with "
207
- f"the name `{fn_identifier}`: {matching_function_signatures}{diagnosis}"
208
- )
209
-
210
- raise Web3ValidationError(message)
211
-
212
-
213
122
  def encode_abi(
214
123
  w3: Union["AsyncWeb3", "Web3"],
215
- abi: ABIFunction,
124
+ abi: ABIElement,
216
125
  arguments: Sequence[Any],
217
126
  data: Optional[HexStr] = None,
218
127
  ) -> HexStr:
219
- argument_types = get_abi_input_types(abi)
220
-
221
- if not check_if_arguments_can_be_encoded(abi, w3.codec, arguments, {}):
128
+ argument_types = []
129
+ try:
130
+ argument_types = get_abi_input_types(abi)
131
+ except ValueError:
132
+ # Use the default argument_types if the abi doesn't have inputs
133
+ pass
134
+
135
+ if not check_if_arguments_can_be_encoded(
136
+ abi,
137
+ *arguments,
138
+ abi_codec=w3.codec,
139
+ ):
222
140
  raise Web3TypeError(
223
141
  "One or more arguments could not be encoded to the necessary "
224
142
  f"ABI type. Expected types are: {', '.join(argument_types)}"
@@ -250,25 +168,33 @@ def encode_abi(
250
168
  def prepare_transaction(
251
169
  address: ChecksumAddress,
252
170
  w3: Union["AsyncWeb3", "Web3"],
253
- fn_identifier: Union[str, Type[FallbackFn], Type[ReceiveFn]],
171
+ abi_element_identifier: ABIElementIdentifier,
254
172
  contract_abi: Optional[ABI] = None,
255
- fn_abi: Optional[ABIFunction] = None,
173
+ abi_callable: Optional[ABICallable] = None,
256
174
  transaction: Optional[TxParams] = None,
257
175
  fn_args: Optional[Sequence[Any]] = None,
258
176
  fn_kwargs: Optional[Any] = None,
259
177
  ) -> TxParams:
260
178
  """
261
- :parameter `is_function_abi` is used to distinguish function abi from contract abi
262
179
  Returns a dictionary of the transaction that could be used to call this
263
180
  TODO: make this a public API
264
181
  TODO: add new prepare_deploy_transaction API
265
182
  """
266
- if fn_abi is None:
267
- fn_abi = find_matching_fn_abi(
268
- contract_abi, w3.codec, fn_identifier, fn_args, fn_kwargs
183
+ fn_args = fn_args or []
184
+ fn_kwargs = fn_kwargs or {}
185
+ if abi_callable is None:
186
+ abi_callable = cast(
187
+ ABICallable,
188
+ get_abi_element(
189
+ contract_abi,
190
+ abi_element_identifier,
191
+ *fn_args,
192
+ abi_codec=w3.codec,
193
+ **fn_kwargs,
194
+ ),
269
195
  )
270
196
 
271
- validate_payable(transaction, fn_abi)
197
+ validate_payable(transaction, abi_callable)
272
198
 
273
199
  if transaction is None:
274
200
  prepared_transaction: TxParams = {}
@@ -283,9 +209,9 @@ def prepare_transaction(
283
209
 
284
210
  prepared_transaction["data"] = encode_transaction_data(
285
211
  w3,
286
- fn_identifier,
212
+ abi_element_identifier,
287
213
  contract_abi,
288
- fn_abi,
214
+ abi_callable,
289
215
  fn_args,
290
216
  fn_kwargs,
291
217
  )
@@ -294,34 +220,36 @@ def prepare_transaction(
294
220
 
295
221
  def encode_transaction_data(
296
222
  w3: Union["AsyncWeb3", "Web3"],
297
- fn_identifier: Union[str, Type[FallbackFn], Type[ReceiveFn]],
223
+ abi_element_identifier: ABIElementIdentifier,
298
224
  contract_abi: Optional[ABI] = None,
299
- fn_abi: Optional[ABIFunction] = None,
225
+ abi_callable: Optional[ABICallable] = None,
300
226
  args: Optional[Sequence[Any]] = None,
301
227
  kwargs: Optional[Any] = None,
302
228
  ) -> HexStr:
303
- if fn_identifier is FallbackFn:
304
- fn_abi, fn_selector, fn_arguments = get_fallback_function_info(
305
- contract_abi, fn_abi
229
+ info_abi: ABIElement
230
+ if abi_element_identifier is FallbackFn:
231
+ info_abi, info_selector, info_arguments = get_fallback_function_info(
232
+ contract_abi, cast(ABIFallback, abi_callable)
306
233
  )
307
- elif fn_identifier is ReceiveFn:
308
- fn_abi, fn_selector, fn_arguments = get_receive_function_info(
309
- contract_abi, fn_abi
234
+ elif abi_element_identifier is ReceiveFn:
235
+ info_abi, info_selector, info_arguments = get_receive_function_info(
236
+ contract_abi, cast(ABIReceive, abi_callable)
310
237
  )
311
- elif is_text(fn_identifier):
312
- fn_abi, fn_selector, fn_arguments = get_function_info(
313
- # type ignored b/c fn_id here is always str b/c FallbackFn is handled above
314
- fn_identifier, # type: ignore
315
- w3.codec,
238
+ elif isinstance(abi_element_identifier, str):
239
+ fn_info = get_abi_element_info(
316
240
  contract_abi,
317
- fn_abi,
318
- args,
319
- kwargs,
241
+ abi_element_identifier,
242
+ *args,
243
+ abi_codec=w3.codec,
244
+ **kwargs,
320
245
  )
246
+ info_abi = fn_info["abi"]
247
+ info_selector = fn_info["selector"]
248
+ info_arguments = fn_info["arguments"]
321
249
  else:
322
250
  raise Web3TypeError("Unsupported function identifier")
323
251
 
324
- return add_0x_prefix(encode_abi(w3, fn_abi, fn_arguments, fn_selector))
252
+ return add_0x_prefix(encode_abi(w3, info_abi, info_arguments, info_selector))
325
253
 
326
254
 
327
255
  def decode_transaction_data(
@@ -329,85 +257,67 @@ def decode_transaction_data(
329
257
  data: HexStr,
330
258
  normalizers: Sequence[Callable[[TypeStr, Any], Tuple[TypeStr, Any]]] = None,
331
259
  ) -> Dict[str, Any]:
332
- data = HexBytes(data)
260
+ data_bytes = HexBytes(data)
333
261
  types = get_abi_input_types(fn_abi)
334
262
  abi_codec = ABICodec(default_registry)
335
- decoded = abi_codec.decode(types, HexBytes(data[4:]))
263
+ decoded = abi_codec.decode(types, data_bytes[4:])
336
264
  if normalizers:
337
265
  decoded = map_abi_data(normalizers, types, decoded)
338
266
  return named_tree(fn_abi["inputs"], decoded)
339
267
 
340
268
 
341
- def get_fallback_function_info(
342
- contract_abi: Optional[ABI] = None, fn_abi: Optional[ABIFunction] = None
343
- ) -> Tuple[ABIFunction, HexStr, Tuple[Any, ...]]:
344
- if fn_abi is None:
345
- fn_abi = get_fallback_func_abi(contract_abi)
269
+ def get_constructor_function_info(
270
+ contract_abi: Optional[ABI] = None, constructor_abi: Optional[ABIConstructor] = None
271
+ ) -> Tuple[ABIConstructor, HexStr, Tuple[Any, ...]]:
272
+ if constructor_abi is None:
273
+ constructor_abi = cast(
274
+ ABIConstructor, get_abi_element(contract_abi, "constructor")
275
+ )
346
276
  fn_selector = encode_hex(b"")
347
277
  fn_arguments: Tuple[Any, ...] = tuple()
348
- return fn_abi, fn_selector, fn_arguments
278
+ return constructor_abi, fn_selector, fn_arguments
349
279
 
350
280
 
351
- def get_receive_function_info(
352
- contract_abi: Optional[ABI] = None, fn_abi: Optional[ABIFunction] = None
353
- ) -> Tuple[ABIFunction, HexStr, Tuple[Any, ...]]:
354
- if fn_abi is None:
355
- fn_abi = get_receive_func_abi(contract_abi)
281
+ def get_fallback_function_info(
282
+ contract_abi: Optional[ABI] = None, fallback_abi: Optional[ABIFallback] = None
283
+ ) -> Tuple[ABIFallback, HexStr, Tuple[Any, ...]]:
284
+ if fallback_abi is None:
285
+ fallback_abi = cast(ABIFallback, get_abi_element(contract_abi, "fallback"))
356
286
  fn_selector = encode_hex(b"")
357
287
  fn_arguments: Tuple[Any, ...] = tuple()
358
- return fn_abi, fn_selector, fn_arguments
288
+ return fallback_abi, fn_selector, fn_arguments
359
289
 
360
290
 
361
- def get_function_info(
362
- fn_name: str,
363
- abi_codec: ABICodec,
364
- contract_abi: Optional[ABI] = None,
365
- fn_abi: Optional[ABIFunction] = None,
366
- args: Optional[Sequence[Any]] = None,
367
- kwargs: Optional[Any] = None,
368
- ) -> Tuple[ABIFunction, HexStr, Tuple[Any, ...]]:
369
- if args is None:
370
- args = tuple()
371
- if kwargs is None:
372
- kwargs = {}
373
-
374
- if fn_abi is None:
375
- fn_abi = find_matching_fn_abi(contract_abi, abi_codec, fn_name, args, kwargs)
376
-
377
- fn_selector = encode_hex(function_abi_to_4byte_selector(fn_abi))
378
-
379
- fn_arguments = merge_args_and_kwargs(fn_abi, args, kwargs)
380
-
381
- _, aligned_fn_arguments = get_aligned_abi_inputs(fn_abi, fn_arguments)
382
-
383
- return fn_abi, fn_selector, aligned_fn_arguments
291
+ def get_receive_function_info(
292
+ contract_abi: Optional[ABI] = None, receive_abi: Optional[ABIReceive] = None
293
+ ) -> Tuple[ABIReceive, HexStr, Tuple[Any, ...]]:
294
+ if receive_abi is None:
295
+ receive_abi = cast(ABIReceive, get_abi_element(contract_abi, "receive"))
296
+ fn_selector = encode_hex(b"")
297
+ fn_arguments: Tuple[Any, ...] = tuple()
298
+ return receive_abi, fn_selector, fn_arguments
384
299
 
385
300
 
386
- def validate_payable(transaction: TxParams, abi: ABIFunction) -> None:
301
+ def validate_payable(transaction: TxParams, abi_callable: ABICallable) -> None:
387
302
  """
388
303
  Raise Web3ValidationError if non-zero ether
389
304
  is sent to a non-payable function.
390
305
  """
391
- if "value" in transaction:
392
- if to_integer_if_hex(transaction["value"]) != 0:
393
- if (
394
- "payable" in abi
395
- and not abi["payable"]
396
- or "stateMutability" in abi
397
- and abi["stateMutability"] == "nonpayable"
398
- ):
399
- raise Web3ValidationError(
400
- "Sending non-zero ether to a contract function "
401
- "with payable=False. Please ensure that "
402
- "transaction's value is 0."
403
- )
404
-
405
-
406
- def _get_argument_readable_type(arg: Any) -> str:
407
- if is_checksum_address(arg) or is_binary_address(arg):
408
- return "address"
409
-
410
- return arg.__class__.__name__
306
+ if (
307
+ "value" in transaction
308
+ and to_integer_if_hex(transaction["value"]) != 0
309
+ and (
310
+ "payable" in abi_callable
311
+ and not abi_callable["payable"]
312
+ or "stateMutability" in abi_callable
313
+ and abi_callable["stateMutability"] == "nonpayable"
314
+ )
315
+ ):
316
+ raise Web3ValidationError(
317
+ "Sending non-zero ether to a contract function "
318
+ "with payable=False. Please ensure that "
319
+ "transaction's value is 0."
320
+ )
411
321
 
412
322
 
413
323
  def parse_block_identifier(
@@ -468,3 +378,4 @@ async def async_parse_block_identifier_int(
468
378
  if block_num < 0:
469
379
  raise BlockNumberOutOfRange
470
380
  return BlockNumber(block_num)
381
+ return BlockNumber(block_num)
web3/_utils/encoding.py CHANGED
@@ -255,12 +255,11 @@ def to_4byte_hex(hex_or_str_or_bytes: Union[HexStr, str, bytes, int]) -> HexStr:
255
255
  return pad_hex(hex_str, size_of_4bytes)
256
256
 
257
257
 
258
- # type ignored because subclassing BaseArrayEncoder which has type Any
259
- class DynamicArrayPackedEncoder(BaseArrayEncoder): # type: ignore[misc]
258
+ class DynamicArrayPackedEncoder(BaseArrayEncoder):
260
259
  is_dynamic = True
261
260
 
262
261
  def encode(self, value: Sequence[Any]) -> bytes:
263
- encoded_elements = self.encode_elements(value)
262
+ encoded_elements = self.encode_elements(value) # type: ignore[no-untyped-call]
264
263
  encoded_value = encoded_elements
265
264
 
266
265
  return encoded_value
@@ -279,10 +278,10 @@ def encode_single_packed(_type: TypeStr, value: Any) -> bytes:
279
278
  )
280
279
 
281
280
  abi_type = abi_type_parser.parse(_type)
282
- if has_arrlist(_type):
281
+ if has_arrlist(_type): # type: ignore[no-untyped-call]
283
282
  item_encoder = registry.get_encoder(abi_type.item_type.to_type_str())
284
283
  if abi_type.arrlist[-1] != 1:
285
- return DynamicArrayPackedEncoder(item_encoder=item_encoder).encode(value)
284
+ return DynamicArrayPackedEncoder(item_encoder=item_encoder).encode(value) # type: ignore[no-untyped-call] # noqa: E501
286
285
  else:
287
286
  raise NotImplementedError(
288
287
  "Fixed arrays are not implemented in this packed encoder prototype"
web3/_utils/events.py CHANGED
@@ -27,6 +27,9 @@ from eth_abi.codec import (
27
27
  ABICodec,
28
28
  )
29
29
  from eth_typing import (
30
+ ABIComponent,
31
+ ABIComponentIndexed,
32
+ ABIEvent,
30
33
  ChecksumAddress,
31
34
  HexStr,
32
35
  Primitives,
@@ -34,7 +37,6 @@ from eth_typing import (
34
37
  )
35
38
  from eth_utils import (
36
39
  encode_hex,
37
- event_abi_to_log_topic,
38
40
  is_list_like,
39
41
  keccak,
40
42
  to_bytes,
@@ -42,6 +44,11 @@ from eth_utils import (
42
44
  to_hex,
43
45
  to_tuple,
44
46
  )
47
+ from eth_utils.abi import (
48
+ collapse_if_tuple,
49
+ event_abi_to_log_topic,
50
+ get_abi_input_names,
51
+ )
45
52
  from eth_utils.curried import (
46
53
  apply_formatter_if,
47
54
  )
@@ -57,7 +64,6 @@ import web3
57
64
  from web3._utils.abi import (
58
65
  exclude_indexed_event_inputs,
59
66
  get_indexed_event_inputs,
60
- get_normalized_abi_arg_type,
61
67
  map_abi_data,
62
68
  named_tree,
63
69
  normalize_event_input_types,
@@ -75,19 +81,16 @@ from web3.datastructures import (
75
81
  from web3.exceptions import (
76
82
  InvalidEventABI,
77
83
  LogTopicError,
78
- MismatchedABI,
79
84
  Web3ValueError,
80
85
  )
81
86
  from web3.types import (
82
- ABIEvent,
83
- ABIEventParams,
84
87
  BlockIdentifier,
85
88
  EventData,
86
89
  FilterParams,
87
90
  LogReceipt,
88
91
  )
89
- from web3.utils import (
90
- get_abi_input_names,
92
+ from web3.utils.abi import (
93
+ get_event_log_topics,
91
94
  )
92
95
 
93
96
  if TYPE_CHECKING:
@@ -110,11 +113,11 @@ def _log_entry_data_to_bytes(
110
113
  def construct_event_topic_set(
111
114
  event_abi: ABIEvent,
112
115
  abi_codec: ABICodec,
113
- arguments: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
116
+ arguments: Optional[Union[List[Any], Tuple[Any], Dict[str, Any]]] = None,
114
117
  ) -> List[HexStr]:
115
118
  if arguments is None:
116
119
  arguments = {}
117
- if isinstance(arguments, (list, tuple)):
120
+ elif isinstance(arguments, (list, tuple)):
118
121
  if len(arguments) != len(event_abi["inputs"]):
119
122
  raise Web3ValueError(
120
123
  "When passing an argument list, the number of arguments must "
@@ -124,11 +127,9 @@ def construct_event_topic_set(
124
127
  arg["name"]: [arg_value]
125
128
  for arg, arg_value in zip(event_abi["inputs"], arguments)
126
129
  }
127
-
128
130
  normalized_args = {
129
131
  key: value if is_list_like(value) else [value]
130
- # type ignored b/c arguments is always a dict at this point
131
- for key, value in arguments.items() # type: ignore
132
+ for key, value in arguments.items()
132
133
  }
133
134
 
134
135
  event_topic = encode_hex(event_abi_to_log_topic(event_abi))
@@ -206,7 +207,7 @@ def is_dynamic_sized_type(type_str: TypeStr) -> bool:
206
207
 
207
208
  @to_tuple
208
209
  def get_event_abi_types_for_decoding(
209
- event_inputs: Sequence[ABIEventParams],
210
+ event_inputs: Sequence[Union[ABIComponent, ABIComponentIndexed]],
210
211
  ) -> Iterable[TypeStr]:
211
212
  """
212
213
  Event logs use the `keccak(value)` for indexed inputs of type `bytes` or
@@ -214,10 +215,10 @@ def get_event_abi_types_for_decoding(
214
215
  decode the log entries using the correct types.
215
216
  """
216
217
  for input_abi in event_inputs:
217
- if input_abi["indexed"] and is_dynamic_sized_type(input_abi["type"]):
218
+ if input_abi.get("indexed") and is_dynamic_sized_type(input_abi["type"]):
218
219
  yield "bytes32"
219
220
  else:
220
- yield get_normalized_abi_arg_type(input_abi)
221
+ yield collapse_if_tuple(input_abi)
221
222
 
222
223
 
223
224
  @curry
@@ -230,22 +231,14 @@ def get_event_data(
230
231
  Given an event ABI and a log entry for that event, return the decoded
231
232
  event data
232
233
  """
233
- if event_abi["anonymous"]:
234
- log_topics = log_entry["topics"]
235
- elif not log_entry["topics"]:
236
- raise MismatchedABI("Expected non-anonymous event to have 1 or more topics")
237
- elif event_abi_to_log_topic(dict(event_abi)) != _log_entry_data_to_bytes(
238
- log_entry["topics"][0]
239
- ):
240
- raise MismatchedABI("The event signature did not match the provided ABI")
241
- else:
242
- log_topics = log_entry["topics"][1:]
243
-
234
+ log_topics = get_event_log_topics(event_abi, log_entry["topics"])
244
235
  log_topics_bytes = [_log_entry_data_to_bytes(topic) for topic in log_topics]
245
236
  log_topics_abi = get_indexed_event_inputs(event_abi)
246
237
  log_topic_normalized_inputs = normalize_event_input_types(log_topics_abi)
247
238
  log_topic_types = get_event_abi_types_for_decoding(log_topic_normalized_inputs)
248
- log_topic_names = get_abi_input_names(ABIEvent({"inputs": log_topics_abi}))
239
+ log_topic_names = get_abi_input_names(
240
+ ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_topics_abi})
241
+ )
249
242
 
250
243
  if len(log_topics_bytes) != len(log_topic_types):
251
244
  raise LogTopicError(
@@ -256,7 +249,9 @@ def get_event_data(
256
249
  log_data_abi = exclude_indexed_event_inputs(event_abi)
257
250
  log_data_normalized_inputs = normalize_event_input_types(log_data_abi)
258
251
  log_data_types = get_event_abi_types_for_decoding(log_data_normalized_inputs)
259
- log_data_names = get_abi_input_names(ABIEvent({"inputs": log_data_abi}))
252
+ log_data_names = get_abi_input_names(
253
+ ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_data_abi})
254
+ )
260
255
 
261
256
  # sanity check that there are not name intersections between the topic
262
257
  # names and the data argument names.
@@ -462,8 +457,8 @@ class AsyncEventFilterBuilder(BaseEventFilterBuilder):
462
457
  if not isinstance(async_w3, web3.AsyncWeb3):
463
458
  raise Web3ValueError(f"Invalid web3 argument: got: {async_w3!r}")
464
459
 
465
- for arg in AttributeDict.values(self.args):
466
- arg._immutable = True # type: ignore[attr-defined]
460
+ for arg in self.args.values():
461
+ arg._immutable = True
467
462
  self._immutable = True
468
463
 
469
464
  log_filter = await async_w3.eth.filter(self.filter_params)
@@ -490,12 +485,12 @@ def _build_argument_filters_from_event_abi(
490
485
  for item in event_abi["inputs"]:
491
486
  key = item["name"]
492
487
  value: "BaseArgumentFilter"
493
- if item["indexed"] is True:
488
+ if item.get("indexed") is True:
494
489
  value = TopicArgumentFilter(
495
- abi_codec=abi_codec, arg_type=get_normalized_abi_arg_type(item)
490
+ abi_codec=abi_codec, arg_type=collapse_if_tuple(item)
496
491
  )
497
492
  else:
498
- value = DataArgumentFilter(arg_type=get_normalized_abi_arg_type(item))
493
+ value = DataArgumentFilter(arg_type=collapse_if_tuple(item))
499
494
  yield key, value
500
495
 
501
496