test(realtime): executing test for the issue #23 body-cap fallback wiring (Closes #145)#146
Merged
Merged
Conversation
…cap fallback wiring at runtime (#145) The existing regression (realtime-getlogs-fallback.test.ts) covers only the extracted helpers. This adds an executing test that drives the exposed createRealtimeSync `sync(headBlock, blockCallback)` generator over one new head block, exercising the private `fetchBlockEventData` closure end-to-end: (A) a ResponseBodyTooLargeError from the unfiltered full-block eth_getLogs is caught, recovered via the filtered per-filter fallback, and the block is ingested with the assembled logs. (B) the `usedFilteredLogsFallback === false || logs.length > 0` guard makes validateLogsAndBlock skip happen ONLY on the empty-fallback path (a non-empty logsBloom block whose filtered fallback returns zero logs is still ingested rather than throwing "logs array has length 0"). Mutation-verified: deleting the .catch fallback turns both RED; dropping the empty-fallback guard turns (B) RED while (A) stays GREEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
|
Independently reproduced the mutation-verification before merge (both against the 0.16.8 wiring):
Both-version |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #145.
Problem
The issue #23 fix (PR #144) added a filtered-
eth_getLogsfallback for the realtime block-data path when the unfiltered full-blocketh_getLogsexceeds viem's ~10 MiB response-body cap. Its regression test (portal/realtime-getlogs-fallback.test.ts) covers only the extracted helpers (buildFilteredBlockLogRequests,eth_getFilteredBlockLogs,isResponseBodyTooLargeError,shouldRetry,validateLogsAndBlock). The wiring that assembles them insidecreateRealtimeSync's privatefetchBlockEventDataclosure — thelogsPromise.catchand theusedFilteredLogsFallback === false || logs.length > 0guard — was proven only by inspection, never executed by a test.Approach
portal/realtime-fallback-e2e.test.tsdrives the exposedcreateRealtimeSync(...).sync(headBlock, blockCallback)async generator over one new head block, exercisingfetchBlockEventDataend-to-end.args.rpc.requestis mocked to route by method and by whether aneth_getLogscall is the unfiltered full-block fetch (params carry notopics) or a filtered fallback fetch (params carrytopics): the unfiltered fetch throws a real-shapedResponseBodyTooLargeError(matched byname), and the filtered fetch returns controlled logs. The head block is passed pre-fetched (withtransactions), so only the logs leg touches the RPC — keeping the mock surface toeth_getLogsalone. No anvil / no network.Two assertions
.catchfires on the oversized error, recovers via the filtered fallback, and the block is ingested (ablockevent is yielded) carrying the assembled log. Also asserts the unfiltered fetch was attempted before the filtered one.logsBloom(built as the exact inverse ofisInBloomso the filter'stopic0is present, forcingshouldRequestLogs) whose filtered fallback returns[]is still ingested, instead of throwing"logs array has length 0". This pins thatvalidateLogsAndBlockis skipped only on the empty-fallback path.Mutation verification
Applied to the patched
src/sync-realtime/index.tsin the built tree:.catchrethrow unconditionally (delete the fallback): both (A) and (B) FAIL — the oversized error propagates, no block is ingested.usedFilteredLogsFallback === false ||guard sovalidateLogsAndBlockalways runs: (B) FAILS (throws on 0 logs vs non-empty bloom) while (A) stays GREEN — confirming the guard is specifically load-bearing for the empty-fallback case, not incidentally covered.Both restored → GREEN. Gates green on both pinned versions (0.16.8 and 0.16.6): 328 tests / 18 files each. Biome clean (error level).
Draft pending independent review.
🤖 Generated with Claude Code