Skip to content

pallet-revive: implement the eth_newFilter polling filter API#12685

Open
soloking1412 wants to merge 2 commits into
paritytech:masterfrom
soloking1412:revive-eth-rpc-filter-api
Open

pallet-revive: implement the eth_newFilter polling filter API#12685
soloking1412 wants to merge 2 commits into
paritytech:masterfrom
soloking1412:revive-eth-rpc-filter-api

Conversation

@soloking1412

Copy link
Copy Markdown
Contributor

Summary

Implements the standard Ethereum polling filter API for pallet-revive's eth-rpc server:

  • eth_newFilter
  • eth_newBlockFilter
  • eth_getFilterChanges
  • eth_getFilterLogs
  • eth_uninstallFilter

Until now the server only offered eth_subscribe (a WebSocket push API) for watching
logs and new blocks. The HTTP polling filter family — its counterpart, used by clients
that cannot hold a WebSocket open (many indexers, serverless functions, and the default
transports of several Ethereum client libraries) — was unimplemented, so that tooling
could not watch the chain.

Behaviour (matches go-ethereum)

  • eth_newFilter(filter) installs a log filter (address / topics / range) and returns an id.
  • eth_newBlockFilter() installs a filter reporting the hashes of blocks added after install.
  • eth_getFilterChanges(id) returns the logs (log filter) or block hashes (block filter)
    seen since the previous poll, advancing the filter's cursor.
  • eth_getFilterLogs(id) returns all logs matching a log filter over its full range.
  • eth_uninstallFilter(id) removes a filter, returning whether it existed.

An unknown or expired id returns -32000 "filter not found", as in go-ethereum.

Design

Filters are pull-based rather than backed by a live stream. A new FilterManager
(src/filters.rs) keeps, per filter, only the next block to report from; eth_getFilterChanges
computes the delta on demand by reusing the existing eth_getLogs range query (log filters)
or resolving block hashes (block filters), then advances the cursor. The registry lock is
never held across an .await.

Two deliberate hardening choices:

  • Filter ids are 128-bit random, so a client cannot enumerate or tamper with filters it
    does not own (same rationale as go-ethereum's random ids).
  • Filters unpolled for five minutes are evicted, bounding the memory an abandoned client
    can retain (mirrors go-ethereum's filter deadline).

eth_newPendingTransactionFilter is intentionally out of scope: the server does not expose a
pending-transaction pool (the same reason eth_subscribe has no newPendingTransactions kind).

Testing

  • Unit tests for the FilterManager registry (install / poll / advance / uninstall / expiry,
    unique ids).
  • An end-to-end test_filter_lifecycle integration test (in the node-backed
    run_all_eth_rpc_tests suite) that deploys a log-emitting contract and exercises
    eth_newFiltereth_getFilterChangeseth_getFilterLogs, the empty second poll,
    eth_uninstallFilter (including the "filter not found" error afterwards), and a block filter.
  • cargo fmt, cargo clippy --all-targets, and the unit tests are clean; the integration test
    runs in CI like the rest of this crate's suite.

Part of the RFC-0172 effort to make pallet-revive's RPC conform to execution-apis / go-ethereum.

@soloking1412
soloking1412 requested a review from a team as a code owner July 18, 2026 17:52
@soloking1412

Copy link
Copy Markdown
Contributor Author

/cmd label T7-smart_contracts

@paritytech-cmd-bot-polkadot-sdk paritytech-cmd-bot-polkadot-sdk Bot added the T7-smart_contracts This PR/Issue is related to smart contracts. label Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T7-smart_contracts This PR/Issue is related to smart contracts.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant