Skip to content

Commit

Permalink
chore: web3py7 abi migration
Browse files Browse the repository at this point in the history
  • Loading branch information
darwintree committed Nov 4, 2024
1 parent 12a033f commit 40ceae5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 47 deletions.
2 changes: 1 addition & 1 deletion conflux_web3/_utils/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def cfx_encode_abi(
"""
argument_types = get_abi_input_types(abi)

if not check_if_arguments_can_be_encoded(abi, web3.codec, arguments, {}):
if not check_if_arguments_can_be_encoded(abi, *arguments, abi_codec=web3.codec):
raise TypeError(
"One or more arguments could not be encoded to the necessary "
"ABI type. Expected types are: {0}".format(
Expand Down
89 changes: 48 additions & 41 deletions conflux_web3/_utils/events.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
from typing import (
Optional,
cast,
Union,
Any,
)
import itertools

from eth_utils.abi import (
get_abi_input_names,
)
from eth_abi.codec import (
ABICodec,
)
from eth_utils.abi import (
event_abi_to_log_topic,
)

from eth_utils.conversions import (
to_bytes,
)
from eth_utils.toolz import (
curry, # type: ignore
)
from web3._utils import events

from web3._utils.events import (
get_event_abi_types_for_decoding
get_event_abi_types_for_decoding,
)
from web3._utils.abi import (
exclude_indexed_event_inputs,
get_abi_input_names,
get_indexed_event_inputs,
map_abi_data,
normalize_event_input_types,
named_tree
)
from web3.utils.abi import (
get_event_log_topics,
)
from eth_typing import (
ABIEvent,
Expand All @@ -37,7 +41,6 @@
from web3.exceptions import (
InvalidEventABI,
LogTopicError,
MismatchedABI,
)
from web3._utils.encoding import (
hexstr_if_str,
Expand All @@ -49,44 +52,49 @@
from conflux_web3.types import (
EventData,
LogReceipt,
TransactionLogReceipt
)

def _log_entry_data_to_bytes(
log_entry_data: Any,
):
return hexstr_if_str(to_bytes, log_entry_data) # type: ignore

def get_cfx_base32_normalizer(chain_id: int): # type: ignore
return lambda type_str, hex_address: (type_str, normalize_to(hex_address, chain_id, True)) if type_str == "address" else (type_str, hex_address) # type: ignore

@curry

@curry # type: ignore
def cfx_get_event_data(
abi_codec: ABICodec, event_abi: ABIEvent, log_entry: Union[TransactionLogReceipt, LogReceipt], chain_id: Optional[int]= None
abi_codec: ABICodec,
event_abi: ABIEvent,
log_entry: LogReceipt,
chain_id: Optional[int]= None
) -> EventData:
"""
Given an event ABI and a log entry for that event, return the decoded
event data.
Modified from web3._utils.events.get_event_data
event data
"""
if event_abi.get("anonymous", None):
log_topics = log_entry["topics"]
elif not log_entry["topics"]:
raise MismatchedABI("Expected non-anonymous event to have 1 or more topics")
# type ignored b/c event_abi_to_log_topic(event_abi: Dict[str, Any])
elif event_abi_to_log_topic(event_abi) != log_entry["topics"][0]: # type: ignore
raise MismatchedABI("The event signature did not match the provided ABI")
else:
log_topics = log_entry["topics"][1:]

log_topics = get_event_log_topics(event_abi, log_entry["topics"])
log_topics_bytes = [_log_entry_data_to_bytes(topic) for topic in log_topics]
log_topics_abi = get_indexed_event_inputs(event_abi)
log_topic_normalized_inputs = normalize_event_input_types(log_topics_abi)
log_topic_types = get_event_abi_types_for_decoding(log_topic_normalized_inputs)
log_topic_names = get_abi_input_names(ABIEvent({"inputs": log_topics_abi}))
log_topic_names = get_abi_input_names(
ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_topics_abi})
)

if len(log_topics) != len(log_topic_types):
if len(log_topics_bytes) != len(log_topic_types):
raise LogTopicError(
f"Expected {len(log_topic_types)} log topics. Got {len(log_topics)}"
f"Expected {len(log_topic_types)} log topics. Got {len(log_topics_bytes)}"
)

log_data = hexstr_if_str(to_bytes, log_entry["data"])
log_data = _log_entry_data_to_bytes(log_entry["data"])
log_data_abi = exclude_indexed_event_inputs(event_abi)
log_data_normalized_inputs = normalize_event_input_types(log_data_abi)
log_data_types = get_event_abi_types_for_decoding(log_data_normalized_inputs)
log_data_names = get_abi_input_names(ABIEvent({"inputs": log_data_abi}))
log_data_names = get_abi_input_names(
ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_data_abi})
)

# sanity check that there are not name intersections between the topic
# names and the data argument names.
Expand All @@ -98,28 +106,26 @@ def cfx_get_event_data(
)

decoded_log_data = abi_codec.decode(log_data_types, log_data)

return_normalizer = [
lambda type_str, hex_address: (type_str, normalize_to(hex_address, chain_id, True)) if type_str == "address" \
else (type_str, hex_address)
]

normalized_log_data = map_abi_data(
return_normalizer, log_data_types, decoded_log_data
[get_cfx_base32_normalizer(chain_id)], log_data_types, decoded_log_data
)
named_log_data = named_tree(
log_data_normalized_inputs,
normalized_log_data,
)

decoded_topic_data = [
abi_codec.decode([topic_type], topic_data)[0]
for topic_type, topic_data in zip(log_topic_types, log_topics)
for topic_type, topic_data in zip(log_topic_types, log_topics_bytes)
]
normalized_topic_data = map_abi_data(
return_normalizer, log_topic_types, decoded_topic_data
[get_cfx_base32_normalizer(chain_id)], log_topic_types, decoded_topic_data
)

event_args = dict(
itertools.chain(
zip(log_topic_names, normalized_topic_data),
zip(log_data_names, normalized_log_data),
named_log_data.items(),
)
)

Expand All @@ -132,11 +138,12 @@ def cfx_get_event_data(
"transactionHash": log_entry.get("transactionHash", None),
"address": log_entry["address"],
"blockHash": log_entry.get("blockHash", None),
"epochNumber": log_entry.get("epochNumber", None),
"epochNumber": log_entry.get("epochNumber", None)
}
if isinstance(log_entry, AttributeDict):
return cast(EventData, AttributeDict.recursive(event_data))

return cast(EventData, AttributeDict.recursive(event_data))

return event_data


# events.get_event_data = conditional_func(
Expand Down
2 changes: 1 addition & 1 deletion conflux_web3/contract/caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(
w3=self.w3,
contract_abi=self.abi,
address=self.address,
function_identifier=func["name"],
abi_element_identifier=func["name"],
decode_tuples=decode_tuples,
)

Expand Down
8 changes: 4 additions & 4 deletions conflux_web3/contract/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Optional,
)

from eth_typing import ABICallable
from web3._utils.datatypes import (
PropertyCheckingFactory,
)
Expand All @@ -19,7 +20,6 @@
)

from eth_typing import (
ABIFunction,
ABI,
)

Expand Down Expand Up @@ -59,7 +59,7 @@ def build_transaction_for_function(
function_name: Optional[ABIElementIdentifier] = None,
transaction: Optional[TxParam] = None,
contract_abi: Optional[ABI] = None,
fn_abi: Optional[ABIFunction] = None,
abi_callable: Optional[ABICallable] = None,
*args: Any,
**kwargs: Any) -> TxParam:
"""Builds a dictionary with the fields required to make the given transaction
Expand All @@ -70,9 +70,9 @@ def build_transaction_for_function(
prepared_transaction:TxParam = prepare_transaction(
address, # type: ignore
web3,
fn_identifier=function_name, # type: ignore
abi_element_identifier=function_name, # type: ignore
contract_abi=contract_abi,
fn_abi=fn_abi,
abi_callable=abi_callable,
transaction=transaction, # type: ignore
fn_args=args,
fn_kwargs=kwargs,
Expand Down

0 comments on commit 40ceae5

Please sign in to comment.