Skip to content

Replace custom-defined FilterCriteria type with the relevant type from Geth - #849

Merged
m-Peter merged 2 commits into
mainfrom
mpeter/remove-custom-filter-criteria-type
Aug 12, 2025
Merged

Replace custom-defined FilterCriteria type with the relevant type from Geth#849
m-Peter merged 2 commits into
mainfrom
mpeter/remove-custom-filter-criteria-type

Conversation

@m-Peter

@m-Peter m-Peter commented Jul 21, 2025

Copy link
Copy Markdown
Collaborator

Work towards: #840

Description

By using the FilterCriteria type from Geth, we benefit from the parsing logic of UnmarshalJSON, without having to duplicate it in our code-base.

This removes the need for the validation checks on max topics/sub-topics/addresses etc.

In addition to that, we also get the new validations for free, such as this one: ethereum/go-ethereum#31876 , by simply upgrading the Geth version, and without having to check for code-base changes to match the JSON-RPC Ethereum API specification.


For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

Summary by CodeRabbit

  • Bug Fixes

    • Enforced limits on maximum topics, sub-topics and addresses for Ethereum log filters; oversized filters now return clear errors.
  • Tests

    • Added RPC and WebSocket tests covering filter limits and subscription limits; improved test cleanup and process termination to avoid hangs.
  • Refactor

    • Simplified filter handling to use a single, consistent criteria representation and adjusted public APIs accordingly.

@coderabbitai

coderabbitai Bot commented Jul 21, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Replace local/internal filter type and pointer usage with github.com/onflow/go-ethereum/eth/filters.FilterCriteria value across API and logs service; update NewIDFilter/NewRangeFilter signatures and call sites; adjust tests (Go and JS) to the new API and add JS cases validating max topics/addresses; minor test-runner and streaming-test cleanups.

Changes

Cohort / File(s) Change Summary
API layer
api/api.go, api/pull.go, api/stream.go
Stop creating a local filter copy; logsFilter.criteria is a value filters.FilterCriteria; constructors/signatures updated to accept criteria by value; pass criteria directly to logs.NewIDFilter / logs.NewRangeFilter.
Logs filtering service
services/logs/filter.go, services/logs/filter_test.go
Replace internal FilterCriteria with external filters.FilterCriteria value; update RangeFilter/IDFilter to store criteria by value; change NewIDFilter/NewRangeFilter signatures (ID derived from criteria.BlockHash), adjust ExactMatch/bloomMatch signatures; remove local maxTopics/maxAddresses validation logic; update tests to the new signatures and types.
JS test runner helper
tests/helpers.go
Add --exit flag to Mocha invocation to ensure the process terminates after tests.
JS web3 tests
tests/web3js/eth_filter_endpoints_test.js, tests/web3js/eth_logs_filtering_test.js, tests/web3js/eth_streaming_filters_test.js
Add tests enforcing max topics, sub-topics, and addresses for both block-range and block-hash filters; streaming tests: remove debug log, use ws.currentProvider.disconnect() instead of process.exit and ensure provider teardown.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API
    participant LogsService

    Client->>API: eth_getLogs or subscribe with filters.FilterCriteria
    API->>LogsService: Call NewIDFilter(criteria) or NewRangeFilter(from,to,criteria)
    LogsService->>LogsService: Validate criteria (uses criteria.BlockHash for ID if ID filter)
    LogsService-->>API: Return filter or validation error
    API-->>Client: Return logs or RPC error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested reviewers

  • peterargue
  • zhangchiqing
  • janezpodhostnik

Poem

I hopped through code with careful pace,
One criteria now fills the place.
No more copies, pointers dropped,
Tests keep topics from the top.
A rabbit smiles — filters neatly lopped! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 675a659 and 51c7965.

📒 Files selected for processing (3)
  • tests/web3js/eth_filter_endpoints_test.js (1 hunks)
  • tests/web3js/eth_logs_filtering_test.js (1 hunks)
  • tests/web3js/eth_streaming_filters_test.js (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/web3js/eth_logs_filtering_test.js (1)
tests/web3js/config.js (1)
  • web3 (2-2)
tests/web3js/eth_filter_endpoints_test.js (2)
tests/web3js/eth_logs_filtering_test.js (20)
  • web3 (4-4)
  • latestBlock (8-8)
  • latestBlock (196-196)
  • latestBlock (236-236)
  • latestBlock (271-271)
  • blockRangeFilter (29-34)
  • blockRangeFilter (198-209)
  • blockRangeFilter (245-250)
  • blockRangeFilter (280-285)
  • response (15-15)
  • response (211-211)
  • response (252-252)
  • response (287-287)
  • helpers (3-3)
  • blockHashFilter (10-14)
  • blockHashFilter (216-226)
  • blockHashFilter (257-261)
  • blockHashFilter (292-296)
  • i (239-239)
  • i (274-274)
tests/web3js/config.js (1)
  • web3 (2-2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (11)
tests/web3js/eth_filter_endpoints_test.js (3)

16-55: LGTM! Well-structured test for max topics validation.

The test correctly validates both block range and block hash filters with 5 topics (exceeding the typical 4-topic limit), and properly asserts the expected error message from Geth's validation.


57-90: LGTM! Comprehensive test for max addresses validation.

The test properly creates 1001 addresses to exceed the limit, tests both filter types, and validates the expected error message. The loop correctly uses let i for proper scoping.


92-126: LGTM! Effective test for max sub-topics validation.

The test correctly constructs a sub-topics array with 1001 entries and uses it as topics: [subTopics] to test the sub-topic limit enforcement. The loop variable is properly declared with let i.

tests/web3js/eth_logs_filtering_test.js (3)

194-232: LGTM! Proper implementation of max topics validation test.

The test correctly validates the 5-topic limit for both block range and block hash filters, and properly asserts the expected error messages from Geth's FilterCriteria validation.


234-267: LGTM! Well-implemented max addresses validation test.

The test properly constructs an array of 1001 addresses to exceed the limit and validates both filter types. The loop variable is correctly declared with let i, avoiding the global variable issue mentioned in previous reviews.


269-302: LGTM! Correct implementation of max sub-topics validation test.

The test effectively creates a sub-topics array with 1001 entries and uses it within the topics array to test sub-topic limits. The loop variable is properly scoped with let i.

tests/web3js/eth_streaming_filters_test.js (5)

6-6: LGTM! Good addition of the global web3 instance.

This provides consistency with other test files and enables reuse of the configured web3 instance across tests.


174-175: LGTM! Proper WebSocket cleanup.

Replacing process.exit(0) with ws.currentProvider.disconnect() provides proper cleanup without terminating the entire process, allowing other tests to run.


177-229: LGTM! Well-structured streaming filter validation for max topics.

The test correctly validates the 5-topic limit for streaming subscriptions using both block range and block hash filters. The error handling properly catches exceptions and validates the expected error messages with err.innerError.message.


231-278: LGTM! Comprehensive streaming filter validation for max addresses.

The test properly creates 1001 addresses to exceed the limit and validates both filter types for streaming subscriptions. The loop variable is correctly declared with let i, and WebSocket cleanup is handled appropriately.


281-328: LGTM! Effective streaming filter validation for max sub-topics.

The test correctly constructs a sub-topics array with 1001 entries and tests it with both filter types for streaming subscriptions. The loop variable is properly scoped with let i, and the test includes proper WebSocket cleanup.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mpeter/remove-custom-filter-criteria-type

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@m-Peter
m-Peter force-pushed the mpeter/remove-custom-filter-criteria-type branch from 10dfebf to 2003bf4 Compare July 28, 2025 07:37
@zhangchiqing

Copy link
Copy Markdown
Member

The changes are looking good. I wonder what's the reason we made the custom defined filter criteria. Was it to prevent some issue?

Comment thread services/logs/filter.go
Comment on lines -33 to -38
if len(topics) > maxTopics {
return nil, fmt.Errorf("max topics exceeded, only %d allowed, got %d", maxTopics, len(topics))
}
if len(addresses) > maxAddresses {
return nil, fmt.Errorf("max addresses exceeded, only %d allowed, got %d", maxAddresses, len(addresses))
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

are these limits enforced somewhere else?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, exactly, that's the main idea behind this PR.

The FilterCriteria type from Geth, enforces the validation logic inside the UnmarshalJSON method.

More specifically:

Whenever a JSON-RPC call, accepts a parameter of FilterCriteria, for example:

// GetLogs returns logs matching the given argument that are stored within the state.
func (b *BlockChainAPI) GetLogs(
	ctx context.Context,
	criteria filters.FilterCriteria,
) ([]*types.Log, error) {

Under the hood, Geth will call UnmarshalJSON on FilterCriteria, to parse the JSON object, to the appropriate FilterCriteria object, and runs any validation logic. If the validation fails, it will return the appropriate error.

@m-Peter

m-Peter commented Aug 6, 2025

Copy link
Copy Markdown
Collaborator Author

The changes are looking good. I wonder what's the reason we made the custom defined filter criteria. Was it to prevent some issue?

@zhangchiqing Because certain Geth types are often placed under internal/, which means that they are private and can't be imported from other packages. From time to time though, the Geth team does move certain types in public/exported packages, so that they can be imported/used from other packages. This is the case here as well. In later releases, this type became public available.

@m-Peter
m-Peter force-pushed the mpeter/remove-custom-filter-criteria-type branch from 2003bf4 to 675a659 Compare August 12, 2025 08:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2003bf4 and 675a659.

📒 Files selected for processing (9)
  • api/api.go (2 hunks)
  • api/pull.go (3 hunks)
  • api/stream.go (1 hunks)
  • services/logs/filter.go (5 hunks)
  • services/logs/filter_test.go (8 hunks)
  • tests/helpers.go (1 hunks)
  • tests/web3js/eth_filter_endpoints_test.js (1 hunks)
  • tests/web3js/eth_logs_filtering_test.js (1 hunks)
  • tests/web3js/eth_streaming_filters_test.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/helpers.go
  • tests/web3js/eth_filter_endpoints_test.js
  • api/stream.go
  • api/pull.go
  • services/logs/filter_test.go
🧰 Additional context used
🧬 Code Graph Analysis (4)
tests/web3js/eth_logs_filtering_test.js (2)
tests/web3js/config.js (1)
  • web3 (2-2)
tests/web3js/helpers.js (1)
  • web3 (5-5)
services/logs/filter.go (1)
storage/index.go (1)
  • ReceiptIndexer (61-82)
tests/web3js/eth_streaming_filters_test.js (3)
tests/web3js/eth_filter_endpoints_test.js (2)
  • web3 (4-4)
  • conf (2-2)
tests/web3js/config.js (1)
  • web3 (2-2)
tests/web3js/setup_test.js (1)
  • conf (2-2)
api/api.go (1)
services/logs/filter.go (2)
  • NewIDFilter (98-113)
  • NewRangeFilter (22-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (9)
tests/web3js/eth_logs_filtering_test.js (1)

194-232: LGTM! The test correctly validates max topics enforcement.

The test is well-structured and properly tests both block range and block hash filters with 5 topics (exceeding the limit of 4). The error message assertion matches Geth's validation behavior.

tests/web3js/eth_streaming_filters_test.js (2)

174-174: Good cleanup of WebSocket connection.

Replacing process.exit() with proper WebSocket disconnection is the correct approach for test cleanup.


177-229: LGTM! Well-structured max topics validation test.

The test properly validates the max topics limit for streaming subscriptions with appropriate error handling and cleanup.

services/logs/filter.go (4)

98-112: LGTM! Proper validation of BlockHash requirement.

The implementation correctly validates that BlockHash is non-nil and uses it as the filter ID. This aligns well with the switch to Geth's FilterCriteria type.


21-42: LGTM! Clean constructor with appropriate range validation.

The updated signature properly accepts the filters.FilterCriteria type by value, and the range validation logic is preserved.


139-162: LGTM! Efficient exact matching logic.

The function correctly accepts filters.FilterCriteria by value and maintains the proper matching logic for topics and addresses.


169-196: LGTM! Bloom filter matching properly adapted.

The bloom matching function correctly uses the external filters.FilterCriteria type while maintaining the fast probabilistic filtering logic.

api/api.go (2)

596-599: LGTM! Clean integration with the updated filter API.

The code correctly passes the criteria directly to NewIDFilter, eliminating the need for intermediate filter creation. Error handling is properly maintained.


639-642: LGTM! Simplified range filter creation.

The direct passing of criteria to NewRangeFilter aligns well with the new API design and removes unnecessary intermediate steps.

Comment thread tests/web3js/eth_logs_filtering_test.js
Comment thread tests/web3js/eth_streaming_filters_test.js
@m-Peter
m-Peter force-pushed the mpeter/remove-custom-filter-criteria-type branch from daeea24 to 51c7965 Compare August 12, 2025 09:42
@m-Peter
m-Peter merged commit b7aecfe into main Aug 12, 2025
2 checks passed
@m-Peter
m-Peter deleted the mpeter/remove-custom-filter-criteria-type branch August 12, 2025 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants