Skip to content

fix: F-2026-18802 | [Dual Defense] EVM FilterLogs Fixed 9000-Block Chunks Stall Cursor With No Adaptive Shrink - #324

Merged
Aman035 merged 2 commits into
audit-fixesfrom
F-2026-18802
Aug 21, 2026
Merged

fix: F-2026-18802 | [Dual Defense] EVM FilterLogs Fixed 9000-Block Chunks Stall Cursor With No Adaptive Shrink#324
Aman035 merged 2 commits into
audit-fixesfrom
F-2026-18802

Conversation

@Aman035

@Aman035 Aman035 commented Aug 21, 2026

Copy link
Copy Markdown
Member

F-2026-18802 Fixed log-query span stalls the cursor

Issue

  • processBlockRange walked in fixed 9000 block slices with no adaptation.
  • A rejected eth_getLogs aborted the range and the caller returned before advancing, so the next tick reissued the identical query.
  • Providers cap the result set, not the block count, so a dense window is rejected at a span that is normally fine.
  • Progress was committed only after the whole range succeeded, so a late failure meant completed chunks were re-fetched every tick.

Fix

  • Retry the same start over a smaller span, halving until it fits or hitting a 100 block floor.
  • Shrink by the width actually attempted, not the nominal span. Near the end of a range the span clamps to toBlock, so halving the span alone resends the identical query first.
  • Linear shrink, not a recursive split, which would issue exponentially many calls against our own RPCs.
  • processBlockRange returns the first block it did not cover, and the caller commits that progress whether or not an error follows.

Not done, with reasons

  • Rec 1 ends "then advance". We do not step over a window that fails at the floor. At 100 blocks the span is not the constraint, so the failure is the RPC, and advancing would drop any deposits in those blocks permanently.
  • Rec 2, address or topic split: a narrower window already reduces the same quantity.
  • Rec 4, metrics: logged at warn per rejection and error at the floor. No metrics pipeline exists in the client.

Solana

  • Same sticky cursor, but the fix does not port and no blocks are missed there.
  • It walks backward from newest, so partial progress is a suffix while the cursor tracks the oldest unprocessed slot.
  • No span to shrink: the page size is the server's choice.

Tests

  • Driven against a local JSON-RPC server that rejects over-wide queries and records every span requested.
  • Exact coverage asserted across 12 range shapes: single block, block zero, exact span, one over, one under, multiple spans, remainders, three shrink profiles, odd start.
  • No gap around a shrink, and a partial run hands back a boundary that leaves no hole on resume.
  • An unreadable window errors and leaves the cursor unmoved.
  • Mutation checked: a one block boundary skip fails coverage, removing the shrink fails the fit test, discarding partial progress fails the progress test.

@Aman035
Aman035 merged commit b93ea41 into audit-fixes Aug 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant