feat(indexer): push result cap and ordering into KV block search (PLT-748)#3689
feat(indexer): push result cap and ordering into KV block search (PLT-748)#3689amir-deris wants to merge 1 commit into
Conversation
PR SummaryMedium Risk Overview Block search is the main behavioral change: the KV block indexer adds a bounded fast path that scans height-ordered keys, point-probes other equality/ Tx search passes the same options through the API, but the KV tx indexer still ignores them (noted as PLT-748); sorting and capping remain in RPC. Mocks, null/psql sinks, and tests were updated for the new signatures; Reviewed by Cursor Bugbot for commit 0f29829. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3689 +/- ##
==========================================
- Coverage 59.26% 58.34% -0.93%
==========================================
Files 2272 2185 -87
Lines 188030 178390 -9640
==========================================
- Hits 111442 104080 -7362
+ Misses 66568 65077 -1491
+ Partials 10020 9233 -787
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
A focused, well-documented refactor that pushes the result cap and ordering into the KV block indexer's scan path; the new fast/fallback paths faithfully reproduce the legacy match semantics and are well covered by tests. No correctness or security issues found — only minor non-blocking notes.
Findings: 0 blocking | 5 non-blocking | 1 posted inline
Blockers
- None at the file/PR level.
Non-blocking
- Second-opinion passes: Codex reported no material findings; the Cursor review file (cursor-review.md) is empty (no output produced). Noting per review instructions.
- Test coverage gap: TestBlockIndexerBounded covers equality drivers and a single lower-bound height range (desc), but not (a) a pure block.height-range driver in ascending order, (b) a dual-bounded range (
block.height >= x AND block.height <= y), or (c) context-cancellation returning partial results in the bounded path. The logic appears correct for all three; adding cases would lock the behavior in. - Minor perf: the pure block.height-range driver scans from the height extremum instead of seeking to the range boundary, so a bounded query like
block.height <= Kon a tall chain still iterates every height above K (cheap range-reject, no point-probe). This matches the old O(total) cost, so it's not a regression — a future optimization could seek the iterator to the bound. - The
seendedup map in searchBounded is effectively defensive: block event keys are unique per (compositeKey, eventValue, height) because the type suffix is always "finalize_block", so a height cannot repeat within a single driver scan today. Fine to keep for robustness; just noting it is not exercised. - 1 suggestion(s)/nit(s) flagged inline on specific lines.
| // and ordering down to the scan. | ||
| results, err := sink.SearchTxEvents(ctx, q, indexer.SearchOptions{ | ||
| Limit: env.Config.MaxTxSearchResults, | ||
| OrderDesc: req.OrderBy != "asc", |
There was a problem hiding this comment.
[nit] Nit: OrderDesc: req.OrderBy != "asc" maps any invalid order_by (e.g. "foo") to desc. Harmless today because the tx indexer ignores opts entirely and the switch below (lines 83-100) still validates order_by and returns ErrInvalidRequest. Worth keeping the TODO(PLT-748) note in mind: once the tx scan path honors these opts, order_by should be validated before it's turned into OrderDesc so a bad value can't silently drive the scan.
Summary
BlockSearch/TxSearchpreviously fetched the entire match set from the KVindexer, sorted it, and only then applied
MaxTxSearchResultsat the RPC layer.For broad queries this materializes and sorts far more heights than the caller
will ever see. This PR pushes the result cap and ordering down into the
indexer so a broad block query is bounded at the scan path.
What changed
indexer.SearchOptions{Limit, OrderDesc}threaded through theTxIndexer/BlockIndexerinterfaces, theEventSinkinterface, the KVsink, and the null/mock implementations.
block/kv) — bounded search:planBounded/searchBounded): when every condition is anequality (point-probeable) or a
block.heightrange (evaluable from thecandidate height), drive a single height-ordered scan in
order_byorder,point-probe the remaining conditions per candidate, and stop at
Limit.Memory is bounded by results kept, not by total match cardinality.
intersect+collectBounded): queries withCONTAINS/MATCHES/EXISTSor non-height ranges can't be point-probed, sothe intersection is materialized as before, then ordered and capped.
BlockSearch: validatesorder_byup front, passes it and the capinto the indexer, and keeps the post-sort cap as a safety net for sinks that
ignore the limit.
TxSearch: passesSearchOptionsthrough now, but the tx scan path isnot yet bounded — marked with
TODO(PLT-748); behavior is unchanged for tx.Tests
TestBlockIndexerBoundedcovers the fast path (equality driver, multi-equalityprobe, equality + height range, pure height-range driver) and the fallback
path (
CONTAINS), across asc/desc and bounded/unbounded limits.SearchOptionsargument.Follow-up
TODO(PLT-748)intx.go).PLT-748