Skip to content

Commit 87b7159

Browse files
committed
Add support for nested tuples to event filters and logs
- Nested tuples seemed to be broken when parsing event filters. This commit piggy backs off previous work and uses the collapse_if_tuple() method in the _build_argument_filters_from_even_abi() method. From testing, this seemes to have been a missing piece to get these issues resolved and the added test passing.
1 parent 1d7a03c commit 87b7159

File tree

6 files changed

+352
-178
lines changed

6 files changed

+352
-178
lines changed

tests/core/contracts/contract_sources/Emitter.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pragma solidity ^0.8.7;
1+
pragma solidity ^0.8.11;
22

33

44
contract Emitter {
@@ -11,7 +11,6 @@ contract Emitter {
1111
event LogString(string v);
1212
event LogBytes(bytes v);
1313

14-
// Indexed
1514
event LogSingleWithIndex(uint indexed arg0);
1615
event LogSingleAnonymous(uint indexed arg0) anonymous;
1716
event LogDoubleWithIndex(uint arg0, uint indexed arg1);
@@ -23,10 +22,13 @@ contract Emitter {
2322
event LogAddressIndexed(address indexed arg0, address arg1);
2423
event LogAddressNotIndexed(address arg0, address arg1);
2524

26-
// Nested type functionality
25+
struct NestedTestTuple {
26+
uint c;
27+
}
2728
struct TestTuple {
2829
uint a;
2930
uint b;
31+
NestedTestTuple nested;
3032
}
3133
event LogStructArgs(uint arg0, TestTuple arg1);
3234

tests/core/contracts/test_extracting_event_data.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ def Emitter(web3, EMITTER):
3131
@pytest.fixture()
3232
def emitter(web3, Emitter, wait_for_transaction, wait_for_block, address_conversion_func):
3333
wait_for_block(web3)
34-
deploy_txn_hash = Emitter.constructor().transact({'from': web3.eth.coinbase, 'gas': 1000000})
34+
deploy_txn_hash = Emitter.constructor().transact({'from': web3.eth.coinbase, 'gas': 10000000})
3535
deploy_receipt = web3.eth.wait_for_transaction_receipt(deploy_txn_hash)
3636
contract_address = address_conversion_func(deploy_receipt['contractAddress'])
3737

38-
bytecode = web3.eth.get_code(contract_address)
39-
assert bytecode == Emitter.bytecode_runtime
38+
bytecode_runtime = web3.eth.get_code(contract_address)
39+
assert bytecode_runtime == Emitter.bytecode_runtime
40+
4041
_emitter = Emitter(address=contract_address)
4142
assert _emitter.address == contract_address
4243
return _emitter
@@ -759,3 +760,14 @@ def test_single_log_processing_with_errors(
759760

760761
with pytest.raises(LogTopicError, match="Expected 1 log topics. Got 0"):
761762
event_instance.processLog(dup_txn_receipt['logs'][0])
763+
764+
765+
def test_event_with_nested_tuple_types(web3, emitter):
766+
struct_args_filter = emitter.events.LogStructArgs.createFilter(fromBlock=0)
767+
768+
tx_hash = emitter.functions.logStruct(1, (2, 3, (4, ))).transact({'gas': 100000})
769+
web3.eth.wait_for_transaction_receipt(tx_hash)
770+
771+
entries = struct_args_filter.get_all_entries()
772+
773+
assert entries != []

tests/core/filtering/test_contract_getLogs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def test_contract_get_available_events(
66
"""We can iterate over available contract events"""
77
contract = emitter
88
events = list(contract.events)
9-
assert len(events) == 18
9+
assert len(events) == 19
1010

1111

1212
def test_contract_getLogs_all(

web3/_utils/events.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
to_hex,
4040
to_tuple,
4141
)
42-
from eth_utils.abi import collapse_if_tuple
42+
from eth_utils.abi import (
43+
collapse_if_tuple,
44+
)
4345
from eth_utils.curried import (
4446
apply_formatter_if,
4547
)
@@ -194,7 +196,7 @@ def get_event_abi_types_for_decoding(event_inputs: Sequence[ABIEventParams]) ->
194196
if input_abi['indexed'] and is_dynamic_sized_type(input_abi['type']):
195197
yield 'bytes32'
196198
else:
197-
yield collapse_if_tuple(input_abi)
199+
yield collapse_if_tuple(dict(input_abi))
198200

199201

200202
@curry
@@ -431,9 +433,9 @@ def _build_argument_filters_from_event_abi(
431433
key = item['name']
432434
value: 'BaseArgumentFilter'
433435
if item['indexed'] is True:
434-
value = TopicArgumentFilter(abi_codec=abi_codec, arg_type=item['type'])
436+
value = TopicArgumentFilter(abi_codec=abi_codec, arg_type=collapse_if_tuple(dict(item)))
435437
else:
436-
value = DataArgumentFilter(arg_type=item['type'])
438+
value = DataArgumentFilter(arg_type=collapse_if_tuple(dict(item)))
437439
yield key, value
438440

439441

@@ -479,7 +481,7 @@ class DataArgumentFilter(BaseArgumentFilter):
479481
# type ignore b/c conflict with BaseArgumentFilter.match_values type
480482
@property
481483
def match_values(self) -> Tuple[TypeStr, Tuple[Any, ...]]: # type: ignore
482-
return (self.arg_type, self._match_values)
484+
return self.arg_type, self._match_values
483485

484486

485487
class TopicArgumentFilter(BaseArgumentFilter):

web3/_utils/filters.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ class TransactionFilter(Filter):
186186
class LogFilter(Filter):
187187
data_filter_set = None
188188
data_filter_set_regex = None
189+
data_filter_set_function = None
189190
log_entry_formatter = None
190191
filter_params: FilterParams = None
191192
builder: EventFilterBuilder = None

0 commit comments

Comments
 (0)