Skip to content

test: support eth_*Filter RPCs #136

Draft
JonathanOppenheimer wants to merge 12 commits intoalarso16/get-logsfrom
JonathanOppenheimer/filter-apis
Draft

test: support eth_*Filter RPCs #136
JonathanOppenheimer wants to merge 12 commits intoalarso16/get-logsfrom
JonathanOppenheimer/filter-apis

Conversation

@JonathanOppenheimer
Copy link
Member

@JonathanOppenheimer JonathanOppenheimer commented Feb 2, 2026

Adds support for the standard Ethereum JSON-RPC filter APIs:

  • eth_newFilter - Create log filter with optional criteria (address, topics)
  • eth_newBlockFilter - Create filter for new blocks
  • eth_newPendingTransactionFilter - Create filter for pending transactions
  • eth_getFilterChanges - Poll for new events since last poll
  • eth_getFilterLogs - Get all logs matching a filter
  • eth_uninstallFilter - Remove a filter

This should not be merged until after #120 is merged.

@JonathanOppenheimer JonathanOppenheimer self-assigned this Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer added the testing Related to testing efforts label Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer added the DO NOT MERGE This PR is not meant to be merged in its current state label Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer changed the title test: support eth_filters RPCs test: support eth_filters RPCs Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer changed the title test: support eth_filters RPCs test: support eth_filter RPCs Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer changed the title test: support eth_filter RPCs test: support eth_*filter RPCs Feb 2, 2026
@JonathanOppenheimer JonathanOppenheimer changed the title test: support eth_*filter RPCs test: support eth_*Filter RPCs Feb 2, 2026
t.Helper()
var filterID string
require.NoError(t, sut.CallContext(ctx, &filterID, method, args...))
require.NotEmpty(t, filterID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
require.NotEmpty(t, filterID)
require.NotEmpty(t, filterID)
t.Cleanup(func() {
uinstallFilter(t, filterID)
})

I think this would be fine, since it matches the exact functionality you implemented, but it doesn't give you the chance to forget the defer statement

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is a good change, we can't call t.Run (which uninstall filter uses), inside of t.cleanup. I'm going to leave as is, unless you have another suggestion (I would like to use testRPC in uninstallFilter)

JonathanOppenheimer and others added 2 commits February 3, 2026 11:35
Co-authored-by: Austin Larson <78000745+alarso16@users.noreply.github.com>
Signed-off-by: Jonathan Oppenheimer <147infiniti@gmail.com>
@JonathanOppenheimer JonathanOppenheimer removed the DO NOT MERGE This PR is not meant to be merged in its current state label Feb 4, 2026
@JonathanOppenheimer JonathanOppenheimer marked this pull request as draft February 4, 2026 18:19
createFilter := func(t *testing.T, ctx context.Context, sut *SUT, method string, args ...any) string {
t.Helper()
var filterID string
require.NoError(t, sut.CallContext(ctx, &filterID, method, args...))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StephenButtolph -- the CallContext usage here feels unavoidable due to the need to capture the filterID. Is it acceptable here?

verifyFilterDeleted := func(t *testing.T, ctx context.Context, sut *SUT, filterID string) {
t.Helper()
var changes []common.Hash
require.ErrorContains(t, sut.CallContext(ctx, &changes, "eth_getFilterChanges", filterID), "filter not found")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, I want to verify and error. we could add a new RPC helper that does error checking rather than success cases, but that would be an additional indirection.

verifyFilterDeleted(t, ctx, sut, filterID)
})

t.Run("newPendingTransactionFilter", func(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is appropriately set up. I could turn it into a big test table, but then one of the test table entries would be a function which is a smell I think.

JonathanOppenheimer and others added 3 commits February 10, 2026 12:45
Signed-off-by: Jonathan Oppenheimer <147infiniti@gmail.com>
Signed-off-by: Jonathan Oppenheimer <147infiniti@gmail.com>
// - eth_getRawTransactionByBlockNumberAndIndex
// - eth_getRawTransactionByHash
// - eth_pendingTransactions
// Standard Ethereum node APIS:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect placed

Signed-off-by: Jonathan Oppenheimer <147infiniti@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Related to testing efforts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants