Skip to content

Removed the ability to filter by pending blocks #3430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 1 addition & 15 deletions docs/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ See an advanced example of fetching log history :ref:`here <advanced_token_fetch

The :meth:`web3.eth.Eth.filter` method can be used to set up filters for:

* Pending Transactions: ``w3.eth.filter("pending")``

* New Blocks ``w3.eth.filter("latest")``

* Event Logs
Expand All @@ -117,7 +115,6 @@ The :meth:`web3.eth.Eth.filter` method can be used to set up filters for:
.. note ::

Creating event filters requires that your Ethereum node has an API support enabled for filters.
Note that Infura support for filters does not offer access to `pending` filters.
To get event logs on other stateless nodes please see :class:`web3.contract.ContractEvents`.


Expand Down Expand Up @@ -189,15 +186,6 @@ will return a new :class:`BlockFilter` object.

``TransactionFilter`` is a subclass of :class:`Filter`.

You can setup a filter for new blocks using ``web3.eth.filter('pending')`` which
will return a new :class:`TransactionFilter` object.

.. code-block:: python

new_transaction_filter = w3.eth.filter('pending')
new_transaction_filter.get_new_entries()


Event Log Filters
-----------------

Expand Down Expand Up @@ -328,13 +316,11 @@ entries to a handler.

def main():
block_filter = w3.eth.filter('latest')
tx_filter = w3.eth.filter('pending')
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(
asyncio.gather(
log_loop(block_filter, 2),
log_loop(tx_filter, 2)))
log_loop(block_filter, 2))
finally:
loop.close()

Expand Down
7 changes: 1 addition & 6 deletions docs/web3.eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1109,16 +1109,11 @@ with the filtering API.

.. py:method:: Eth.filter(filter_params)

* Delegates to ``eth_newFilter``, ``eth_newBlockFilter``, and
``eth_newPendingTransactionFilter`` RPC Methods.
* Delegates to ``eth_newFilter``, ``eth_newBlockFilter`` RPC Methods.

This method delegates to one of three RPC methods depending on the value of
``filter_params``.

* If ``filter_params`` is the string ``'pending'`` then a new filter is
registered using the ``eth_newPendingTransactionFilter`` RPC method.
This will create a new filter that will be called for each new unmined
transaction that the node receives.
* If ``filter_params`` is the string ``'latest'`` then a new filter is
registered using the ``eth_newBlockFilter`` RPC method. This will create
a new filter that will be called each time the node receives a new block.
Expand Down
14 changes: 4 additions & 10 deletions tests/core/eth-module/test_eth_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
from web3._utils.filters import (
AsyncBlockFilter,
AsyncLogFilter,
AsyncTransactionFilter,
BlockFilter,
LogFilter,
TransactionFilter,
)
from web3.providers.eth_tester.main import (
AsyncEthereumTesterProvider,
Expand All @@ -21,10 +19,8 @@
def test_eth_filter_creates_correct_filter_type(w3):
filter1 = w3.eth.filter("latest")
assert isinstance(filter1, BlockFilter)
filter2 = w3.eth.filter("pending")
assert isinstance(filter2, TransactionFilter)
filter3 = w3.eth.filter({})
assert isinstance(filter3, LogFilter)
filter2 = w3.eth.filter({})
assert isinstance(filter2, LogFilter)


# --- async --- #
Expand All @@ -41,7 +37,5 @@ async def async_w3():
async def test_async_eth_filter_creates_correct_filter_type(async_w3):
filter1 = await async_w3.eth.filter("latest")
assert isinstance(filter1, AsyncBlockFilter)
filter2 = await async_w3.eth.filter("pending")
assert isinstance(filter2, AsyncTransactionFilter)
filter3 = await async_w3.eth.filter({})
assert isinstance(filter3, AsyncLogFilter)
filter2 = await async_w3.eth.filter({})
assert isinstance(filter2, AsyncLogFilter)
59 changes: 0 additions & 59 deletions tests/core/filtering/test_filter_against_pending_transactions.py

This file was deleted.

5 changes: 0 additions & 5 deletions tests/core/middleware/test_filter_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,6 @@ def test_iter_latest_block_ranges(
assert actual_tuple == expected_tuple


def test_pending_block_filter_middleware(w3):
with pytest.raises(NotImplementedError):
w3.eth.filter("pending")


def test_LocalFilterMiddleware(w3, iter_block_number):
block_filter = w3.eth.filter("latest")
block_filter.get_new_entries()
Expand Down
14 changes: 3 additions & 11 deletions tests/core/utilities/test_select_filter_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@

@pytest.mark.parametrize(
"value, expected",
(
("latest", "new_block_filter"),
("pending", "new_pending_tx_filter"),
({"to": "0x" + "00" * 20}, "new_filter"),
),
(("latest", "new_block_filter"), ({"to": "0x" + "00" * 20}, "new_filter")),
)
def test_select_filter_method(value, expected):
filter_method = select_filter_method(
if_new_block_filter="new_block_filter",
if_new_pending_transaction_filter="new_pending_tx_filter",
if_new_filter="new_filter",
if_new_block_filter="new_block_filter", if_new_filter="new_filter"
)
assert filter_method(value) == expected

Expand All @@ -36,9 +30,7 @@ def test_select_filter_method(value, expected):
)
def test_select_filter_method_raises_error(value, error):
filter_method = select_filter_method(
if_new_block_filter="new_block_filter",
if_new_pending_transaction_filter="new_pending_tx_filter",
if_new_filter="new_filter",
if_new_block_filter="new_block_filter", if_new_filter="new_filter"
)
with pytest.raises(error):
filter_method(value)
9 changes: 3 additions & 6 deletions web3/_utils/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,27 +382,24 @@ def __init__(self, filter_id: Union[str, FilterParams, HexStr]) -> None:
def select_filter_method(
value: Union[str, FilterParams, HexStr],
if_new_block_filter: RPCEndpoint,
if_new_pending_transaction_filter: RPCEndpoint,
if_new_filter: RPCEndpoint,
) -> Optional[RPCEndpoint]:
if is_string(value):
if value == "latest":
return if_new_block_filter
elif value == "pending":
return if_new_pending_transaction_filter
elif is_hex(value):
raise _UseExistingFilter(value)
else:
raise Web3ValidationError(
"Filter argument needs to be either 'latest',"
" 'pending', or a hex-encoded filter_id. Filter argument"
"Filter argument needs to be either 'latest'"
" or a hex-encoded filter_id. Filter argument"
f" is: {value}"
)
elif isinstance(value, dict):
return if_new_filter
else:
raise Web3ValidationError(
"Filter argument needs to be either the string "
"'pending' or 'latest', a filter_id, "
"'latest', a filter_id, "
f"or a filter params dictionary. Filter argument is: {value}"
)
11 changes: 1 addition & 10 deletions web3/_utils/method_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,13 +934,6 @@ def filter_wrapper(
return AsyncBlockFilter(filter_id, eth_module=cast("AsyncEth", module))
else:
return BlockFilter(filter_id, eth_module=cast("Eth", module))
elif method == RPC.eth_newPendingTransactionFilter:
if module.is_async:
return AsyncTransactionFilter(
filter_id, eth_module=cast("AsyncEth", module)
)
else:
return TransactionFilter(filter_id, eth_module=cast("Eth", module))
elif method == RPC.eth_newFilter:
if module.is_async:
return AsyncLogFilter(filter_id, eth_module=cast("AsyncEth", module))
Expand All @@ -949,13 +942,11 @@ def filter_wrapper(
else:
raise NotImplementedError(
"Filter wrapper needs to be used with either "
f"{RPC.eth_newBlockFilter}, {RPC.eth_newPendingTransactionFilter}"
f" or {RPC.eth_newFilter}"
f"{RPC.eth_newBlockFilter} or {RPC.eth_newFilter}"
)


FILTER_RESULT_FORMATTERS: Dict[RPCEndpoint, Callable[..., Any]] = {
RPC.eth_newPendingTransactionFilter: filter_wrapper,
RPC.eth_newBlockFilter: filter_wrapper,
RPC.eth_newFilter: filter_wrapper,
}
Expand Down
25 changes: 0 additions & 25 deletions web3/_utils/module_testing/eth_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -2463,20 +2463,6 @@ async def test_async_eth_new_block_filter(self, async_w3: "AsyncWeb3") -> None:
result = await async_w3.eth.uninstall_filter(filter.filter_id)
assert result is True

@pytest.mark.asyncio
async def test_async_eth_new_pending_transaction_filter(
self, async_w3: "AsyncWeb3"
) -> None:
filter = await async_w3.eth.filter("pending")
assert is_string(filter.filter_id)

changes = await async_w3.eth.get_filter_changes(filter.filter_id)
assert is_list_like(changes)
assert not changes

result = await async_w3.eth.uninstall_filter(filter.filter_id)
assert result is True

@pytest.mark.asyncio
async def test_async_eth_uninstall_filter(self, async_w3: "AsyncWeb3") -> None:
filter = await async_w3.eth.filter({})
Expand Down Expand Up @@ -4493,17 +4479,6 @@ def test_eth_new_block_filter(self, w3: "Web3") -> None:
result = w3.eth.uninstall_filter(filter.filter_id)
assert result is True

def test_eth_new_pending_transaction_filter(self, w3: "Web3") -> None:
filter = w3.eth.filter("pending")
assert is_string(filter.filter_id)

changes = w3.eth.get_filter_changes(filter.filter_id)
assert is_list_like(changes)
assert not changes

result = w3.eth.uninstall_filter(filter.filter_id)
assert result is True

def test_eth_get_logs_without_logs(
self, w3: "Web3", block_with_txn_with_log: BlockData
) -> None:
Expand Down
1 change: 0 additions & 1 deletion web3/_utils/rpc_abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ class RPC:
eth_getWork = RPCEndpoint("eth_getWork")
eth_newBlockFilter = RPCEndpoint("eth_newBlockFilter")
eth_newFilter = RPCEndpoint("eth_newFilter")
eth_newPendingTransactionFilter = RPCEndpoint("eth_newPendingTransactionFilter")
eth_protocolVersion = RPCEndpoint("eth_protocolVersion")
eth_sendRawTransaction = RPCEndpoint("eth_sendRawTransaction")
eth_sendTransaction = RPCEndpoint("eth_sendTransaction")
Expand Down
6 changes: 2 additions & 4 deletions web3/eth/async_eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,15 +637,13 @@ async def sign_typed_data(
async def get_uncle_count(self, block_identifier: BlockIdentifier) -> int:
return await self._get_uncle_count(block_identifier)

# eth_newFilter, eth_newBlockFilter, eth_newPendingTransactionFilter
# eth_newFilter, eth_newBlockFilter

filter: Method[
Callable[[Optional[Union[str, FilterParams, HexStr]]], Awaitable[AsyncFilter]]
] = Method(
method_choice_depends_on_args=select_filter_method(
if_new_block_filter=RPC.eth_newBlockFilter,
if_new_pending_transaction_filter=RPC.eth_newPendingTransactionFilter,
if_new_filter=RPC.eth_newFilter,
if_new_block_filter=RPC.eth_newBlockFilter, if_new_filter=RPC.eth_newFilter
),
mungers=[BaseEth.filter_munger],
)
Expand Down
6 changes: 3 additions & 3 deletions web3/eth/base_eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ def filter_munger(
if isinstance(filter_params, dict):
return [filter_params]
elif is_string(filter_params):
if filter_params in {"latest", "pending"}:
if filter_params == "latest":
return [filter_params]
else:
raise Web3ValueError(
"The filter API only accepts the values of `pending` or "
"`latest` for string based filters"
"The filter API only accepts the value of"
" `latest` for string based filters"
)
elif filter_id and not filter_params:
return [filter_id]
Expand Down
6 changes: 2 additions & 4 deletions web3/eth/eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,15 +600,13 @@ def modify_transaction(
mungers=[default_root_munger],
)

# eth_newFilter, eth_newBlockFilter, eth_newPendingTransactionFilter
# eth_newFilter, eth_newBlockFilter

filter: Method[
Callable[[Optional[Union[str, FilterParams, HexStr]]], Filter]
] = Method(
method_choice_depends_on_args=select_filter_method(
if_new_block_filter=RPC.eth_newBlockFilter,
if_new_pending_transaction_filter=RPC.eth_newPendingTransactionFilter,
if_new_filter=RPC.eth_newFilter,
if_new_block_filter=RPC.eth_newBlockFilter, if_new_filter=RPC.eth_newFilter
),
mungers=[BaseEth.filter_munger],
)
Expand Down
8 changes: 2 additions & 6 deletions web3/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,8 @@ def process_params(
# the first parameter determines which method needs to be called
self.json_rpc_method = self.method_choice_depends_on_args(value=params[0])

pending_or_latest_filter_methods = [
RPC.eth_newPendingTransactionFilter,
RPC.eth_newBlockFilter,
]
if self.json_rpc_method in pending_or_latest_filter_methods:
# For pending or latest filter methods, use params to determine
if self.json_rpc_method == RPC.eth_newBlockFilter:
# For latest filter method, use params to determine
# which method to call, but don't pass them through with the request
params = []

Expand Down
3 changes: 0 additions & 3 deletions web3/providers/eth_tester/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,6 @@ def create_new_account(eth_tester: "EthereumTester") -> HexAddress:
"compileSerpent": not_implemented,
"newFilter": create_log_filter,
"newBlockFilter": call_eth_tester("create_block_filter"),
"newPendingTransactionFilter": call_eth_tester(
"create_pending_transaction_filter"
),
"uninstallFilter": excepts(
FilterNotFound,
compose(
Expand Down
1 change: 0 additions & 1 deletion web3/providers/eth_tester/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ def is_hexstr(value: Any) -> bool:
),
RPCEndpoint("eth_newFilter"): integer_to_hex,
RPCEndpoint("eth_newBlockFilter"): integer_to_hex,
RPCEndpoint("eth_newPendingTransactionFilter"): integer_to_hex,
RPCEndpoint("eth_getLogs"): apply_formatter_if(
is_array_of_dicts,
apply_list_to_array_formatter(log_result_remapper),
Expand Down
Loading