methods: fix getEvents missing events on multi-filter requests#832
methods: fix getEvents missing events on multi-filter requests#832urvisavla wants to merge 1 commit into
Conversation
…lters
getEvents filters are OR-ed together, and within a filter an empty
contractIds or type field means "match any". But combineContractIDs and
combineEventTypes unioned only the explicitly-listed values into the SQL
prefilter, so a request like
{"filters": [
{"contractIds": ["CA..."]},
{"topics": [["<transfer>"]]}
]}
restricted the DB scan to contract_id IN (CA...), silently dropping
events from other contracts that the second filter should match. The
same applied to event types.
Fix both the same way combineTopics already handles this: if any filter
leaves the dimension unconstrained, drop that DB-level restriction
entirely. The in-memory request.Matches pass still enforces the exact
per-filter semantics; the prefilter is only ever a superset again.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
There was a problem hiding this comment.
Pull request overview
Fixes getEvents correctness when multiple OR-ed filters are provided and one filter leaves contractIds or type unconstrained (“match any”), by ensuring the SQL prefilter remains a superset of per-filter semantics (with final exact matching still enforced in-memory via request.Matches).
Changes:
- Drop the DB-level
contract_idrestriction when any filter has emptycontractIds. - Drop the DB-level
event_typerestriction when any filter has emptytype. - Add unit tests for the combine helpers plus end-to-end regression tests exercising the handler against a real DB.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cmd/stellar-rpc/internal/methods/get_events.go | Adjusts contract ID / event type prefilter combination so “match any” filters don’t get starved by other filters’ SQL restrictions. |
| cmd/stellar-rpc/internal/methods/get_events_test.go | Adds focused unit tests for the combination helpers and regression tests proving multi-filter OR semantics through the handler+DB. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tamirms
left a comment
There was a problem hiding this comment.
looks good! we should include this in the changelog though
Problem
getEvents filters are OR-ed together: an event should be returned if it matches any filter. Within a single filter, an empty
contractIdsortypefield means that filter matches any contract or any event type.The handler pushes a combined prefilter down to SQL before applying exact per-filter matching in memory. For correctness the prefilter must be a superset of what the filters accept, but
combineContractIDsandcombineEventTypesbuilt it from only the explicitly listed values. When one filter listed values and another left the field empty, the empty filter's "match any" semantics were lost, and the SQL prefilter excluded rows the in-memory pass never got to see.Example
{ "filters": [ // filter 1: counter events from contract A { "contractIds": ["CCONTRACT_A..."], "topics": [["<counter symbol>"]] }, // filter 2: transfer events from ANY contract { "topics": [["<transfer symbol>"]] } ] }Filter 2 should match transfer events from any contract. Instead the query ran with
contract_id IN ('CONTRACT_A'), so transfer events from every other contract were silently missing from the response. The same happened with event types:{"type": "system"}in one filter suppressed the contract-type events matched by other filters.Notably,
combineTopicsalready handles this case correctly for topics; the contract ID and event type paths were missing the same rule.Fix
Apply the rule
combineTopicsalready uses: if any filter leaves a dimension unconstrained, drop that dimension's SQL restriction entirely. Exact filter semantics are still enforced by the existing in-memoryrequest.Matchespass; the SQL prefilter goes back to being a pure narrowing optimization.Testing
combineContractIDsandcombineEventTypescovering union/dedup, the unconstrained-filter case, no filters, and invalid input.🤖 Generated with Claude Code