diff --git a/src/ape/api/providers.py b/src/ape/api/providers.py index 042eeb07a5..ea4c771a38 100644 --- a/src/ape/api/providers.py +++ b/src/ape/api/providers.py @@ -909,7 +909,7 @@ def poll_blocks( # type: ignore[empty-body] def poll_logs( # type: ignore[empty-body] self, stop_block: int | None = None, - address: "AddressType | None" = None, + address: "list[AddressType] | AddressType | None" = None, topics: list[str | list[str]] | None = None, required_confirmations: int | None = None, new_block_timeout: int | None = None, @@ -928,7 +928,7 @@ def poll_logs( # type: ignore[empty-body] Args: stop_block (Optional[int]): Optionally set a future block number to stop at. Defaults to never-ending. - address (Optional[str]): The address of the contract to filter logs by. + address (Union[list[str], str, None]): The address of the contract(s) to filter logs by. Defaults to all addresses. topics (Optional[list[Union[str, list[str]]]]): The topics to filter logs by. Defaults to all topics. diff --git a/src/ape_ethereum/provider.py b/src/ape_ethereum/provider.py index 17d14d3492..6f988a0d9b 100644 --- a/src/ape_ethereum/provider.py +++ b/src/ape_ethereum/provider.py @@ -1104,7 +1104,7 @@ def assert_chain_activity(): def poll_logs( self, stop_block: int | None = None, - address: "AddressType | None" = None, + address: "list[AddressType] | AddressType | None" = None, topics: list[str | list[str]] | None = None, required_confirmations: int | None = None, new_block_timeout: int | None = None, @@ -1128,7 +1128,7 @@ def poll_logs( "events": events, } if address is not None: - log_params["addresses"] = [address] + log_params["addresses"] = address if isinstance(address, list) else [address] if topics is not None: log_params["topic_filter"] = topics diff --git a/tests/functional/test_provider.py b/tests/functional/test_provider.py index c51f1edc1d..fa8641217d 100644 --- a/tests/functional/test_provider.py +++ b/tests/functional/test_provider.py @@ -259,6 +259,32 @@ def test_get_contract_logs_single_log(chain, contract_instance, owner, eth_teste assert topics == expected_topics +def test_poll_logs_forwards_multiple_addresses(mocker, contract_instance, owner, geth_provider): + from ape_ethereum.provider import Web3Provider + + block_number = 0 + mock_block = mocker.MagicMock(number=block_number) + # NOTE: need to patch source, which is parent class + mocker.patch.object(Web3Provider, "poll_blocks", return_value=iter([mock_block])) + get_contract_logs_spy = mocker.patch.object( + Web3Provider, + "get_contract_logs", + return_value=iter([]), + ) + + addresses = [contract_instance.address, owner.address] + _ = list( + geth_provider.poll_logs( + stop_block=block_number + 100, + address=addresses, + events=[contract_instance.NumberChange.abi], + ) + ) + + log_filter = get_contract_logs_spy.call_args.args[0] + assert log_filter.addresses == addresses + + def test_get_contract_logs_single_log_query_multiple_values( chain, contract_instance, owner, eth_tester_provider ):