Skip to content

Commit 8a7bef1

Browse files
feat: optimize map_abi_data (#3697)
1 parent 2f3edcc commit 8a7bef1

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

newsfragments/3697.performance.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
optimize map_abi_data

web3/_utils/abi.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
)
7474
from eth_utils.toolz import (
7575
curry,
76-
partial,
7776
pipe,
7877
)
7978

@@ -115,21 +114,21 @@ def receive_func_abi_exists(contract_abi: ABI) -> Sequence[ABIReceive]:
115114
return filter_abi_by_type("receive", contract_abi)
116115

117116

118-
def get_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
117+
def get_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIComponentIndexed]:
119118
return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
120119

121120

122-
def exclude_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
121+
def exclude_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIComponentIndexed]:
123122
return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
124123

125124

126-
def filter_by_types(types: Collection[str], contract_abi: ABI) -> Sequence[ABIElement]:
125+
def filter_by_types(types: Collection[str], contract_abi: ABI) -> List[ABIElement]:
127126
return [abi_element for abi_element in contract_abi if abi_element["type"] in types]
128127

129128

130129
def filter_by_argument_name(
131130
argument_names: Collection[str], contract_abi: ABI
132-
) -> Sequence[ABIElement]:
131+
) -> List[ABIElement]:
133132
"""
134133
Return a list of each ``ABIElement`` which contains arguments matching provided
135134
names.
@@ -186,7 +185,7 @@ def get_name_from_abi_element_identifier(
186185

187186
def get_abi_element_signature(
188187
abi_element_identifier: ABIElementIdentifier,
189-
abi_element_argument_types: Optional[Sequence[str]] = None,
188+
abi_element_argument_types: Optional[Iterable[str]] = None,
190189
) -> str:
191190
element_name = get_name_from_abi_element_identifier(abi_element_identifier)
192191
argument_types = ",".join(abi_element_argument_types or [])
@@ -585,9 +584,9 @@ def normalize_event_input_types(
585584

586585
@curry
587586
def map_abi_data(
588-
normalizers: Sequence[Callable[[TypeStr, Any], Tuple[TypeStr, Any]]],
589-
types: Sequence[TypeStr],
590-
data: Sequence[Any],
587+
normalizers: Iterable[Callable[[TypeStr, Any], Tuple[TypeStr, Any]]],
588+
types: Iterable[TypeStr],
589+
data: Iterable[Any],
591590
) -> Any:
592591
"""
593592
Applies normalizers to your data, in the context of the relevant types.
@@ -611,17 +610,21 @@ def normalizer(datatype, data):
611610
2. Recursively mapping each of the normalizers to the data
612611
3. Stripping the types back out of the tree
613612
"""
614-
pipeline = itertools.chain(
615-
[abi_data_tree(types)],
616-
map(data_tree_map, normalizers),
617-
[partial(recursive_map, strip_abi_type)],
613+
return pipe(
614+
data,
615+
# 1. Decorating the data tree with types
616+
abi_data_tree(types),
617+
# 2. Recursively mapping each of the normalizers to the data
618+
*map(data_tree_map, normalizers),
619+
# 3. Stripping the types back out of the tree
620+
strip_abi_types,
618621
)
619622

620-
return pipe(data, *pipeline)
621-
622623

623624
@curry
624-
def abi_data_tree(types: Sequence[TypeStr], data: Sequence[Any]) -> List[Any]:
625+
def abi_data_tree(
626+
types: Iterable[TypeStr], data: Iterable[Any]
627+
) -> List["ABITypedData"]:
625628
"""
626629
Decorate the data tree with pairs of (type, data). The pair tuple is actually an
627630
ABITypedData, but can be accessed as a tuple.
@@ -631,10 +634,7 @@ def abi_data_tree(types: Sequence[TypeStr], data: Sequence[Any]) -> List[Any]:
631634
>>> abi_data_tree(types=["bool[2]", "uint"], data=[[True, False], 0])
632635
[("bool[2]", [("bool", True), ("bool", False)]), ("uint256", 0)]
633636
"""
634-
return [
635-
abi_sub_tree(data_type, data_value)
636-
for data_type, data_value in zip(types, data)
637-
]
637+
return list(map(abi_sub_tree, types, data))
638638

639639

640640
@curry
@@ -723,6 +723,10 @@ def strip_abi_type(elements: Any) -> Any:
723723
return elements
724724

725725

726+
def strip_abi_types(elements: Any) -> Any:
727+
return recursive_map(strip_abi_type, elements)
728+
729+
726730
def build_non_strict_registry() -> ABIRegistry:
727731
# We make a copy here just to make sure that eth-abi's default registry is not
728732
# affected by our custom encoder subclasses

0 commit comments

Comments
 (0)