diff --git a/tests/core/middleware/test_request_param_normalizer.py b/tests/core/middleware/test_request_param_normalizer.py new file mode 100644 index 0000000000..7977447d8f --- /dev/null +++ b/tests/core/middleware/test_request_param_normalizer.py @@ -0,0 +1,35 @@ +import pytest + +from web3 import Web3 +from web3.middleware import ( # noqa: F401 + construct_result_generator_middleware, + request_parameter_normalizer, +) +from web3.providers.base import ( + BaseProvider, +) + + +@pytest.fixture +def w3_base(): + return Web3(providers=[BaseProvider()], middlewares=[]) + + +@pytest.fixture +def result_generator_middleware(): + return construct_result_generator_middleware({ + 'eth_getLogs': lambda _, params: params, + }) + + +@pytest.fixture +def w3(w3_base, result_generator_middleware): + w3_base.middleware_stack.add(result_generator_middleware) + w3_base.middleware_stack.add(request_parameter_normalizer) + return w3_base + + +def test_eth_getLogs_param_normalization(w3): + result = w3.eth.getLogs({ + 'from': 'latest', 'address': '0x1111111111111111111111111111111111111111'}) + assert isinstance(result[0]['address'], list) diff --git a/web3/manager.py b/web3/manager.py index 338ccd0c46..2ca9c214a6 100644 --- a/web3/manager.py +++ b/web3/manager.py @@ -16,6 +16,7 @@ name_to_address_middleware, normalize_errors_middleware, pythonic_middleware, + request_parameter_normalizer, validation_middleware, ) from web3.providers import ( @@ -70,6 +71,7 @@ def default_middlewares(web3): Leaving ens unspecified will prevent the middleware from resolving names. ''' return [ + (request_parameter_normalizer, 'request_param_normalizer'), (gas_price_strategy_middleware, 'gas_price_strategy'), (name_to_address_middleware(web3), 'name_to_address'), (attrdict_middleware, 'attrdict'), diff --git a/web3/middleware/__init__.py b/web3/middleware/__init__.py index 9a3721ff03..e6b609aa93 100644 --- a/web3/middleware/__init__.py +++ b/web3/middleware/__init__.py @@ -34,6 +34,9 @@ from .normalize_errors import ( # noqa: F401 normalize_errors_middleware, ) +from .normalize_request_parameters import ( # noqa: F401 + request_parameter_normalizer, +) from .pythonic import ( # noqa: F401 pythonic_middleware, ) diff --git a/web3/middleware/normalize_request_parameters.py b/web3/middleware/normalize_request_parameters.py new file mode 100644 index 0000000000..bc6ffa3ed0 --- /dev/null +++ b/web3/middleware/normalize_request_parameters.py @@ -0,0 +1,25 @@ +from eth_utils import ( + is_string, +) + +from web3.utils.formatters import ( + apply_formatter_at_index, + apply_formatter_if, + apply_formatters_to_dict, +) + +from .formatting import ( + construct_formatting_middleware, +) + +FILTER_PARAM_NORMALIZERS = apply_formatters_to_dict({ + 'address': apply_formatter_if(is_string, lambda x: [x])}) + +METHOD_NORMALIZERS = { + 'eth_getLogs': apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0), + 'eth_newFilter': apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0) +} + +request_parameter_normalizer = construct_formatting_middleware( + request_formatters=METHOD_NORMALIZERS, +) diff --git a/web3/utils/module_testing/eth_module.py b/web3/utils/module_testing/eth_module.py index 631f149eac..e0d144eecd 100644 --- a/web3/utils/module_testing/eth_module.py +++ b/web3/utils/module_testing/eth_module.py @@ -677,6 +677,16 @@ def test_eth_getLogs_without_logs(self, web3, block_with_txn_with_log): result = web3.eth.getLogs(filter_params) assert len(result) == 0 + # Test with multiple `address` + + # filter with other address + filter_params = { + "fromBlock": 0, + "address": [UNKNOWN_ADDRESS, UNKNOWN_ADDRESS], + } + result = web3.eth.getLogs(filter_params) + assert len(result) == 0 + def test_eth_getLogs_with_logs( self, web3, diff --git a/web3/utils/rpc_abi.py b/web3/utils/rpc_abi.py index 9adfa89bde..2392e8b3a9 100644 --- a/web3/utils/rpc_abi.py +++ b/web3/utils/rpc_abi.py @@ -24,7 +24,7 @@ FILTER_PARAMS_ABIS = { 'to': 'address', - 'address': 'address', + 'address': 'address[]', } TRACE_PARAMS_ABIS = {