feat(scan): refresh validators and tokens on new blocks#103
Conversation
Both pages waited a full poll interval (15s and 30s) to reflect chain changes. Added useRefetchOnNewBlock, which refetches shortly after each new block from the existing newHeads websocket, throttled to once per 10s so fast block times do not flood the per-IP request budget. Mirrors the home page live-refresh trigger.
📝 WalkthroughWalkthroughA new Sequence Diagram(s)Tokens page: sequenceDiagram
participant useLatestBlock
participant useRefetchOnNewBlock
participant useTokens
useLatestBlock->>useRefetchOnNewBlock: head?.number advances
useRefetchOnNewBlock->>useTokens: call refetch() when throttle window allows
Validators page: sequenceDiagram
participant useLatestBlock
participant useRefetchOnNewBlock
participant useValidators
useLatestBlock->>useRefetchOnNewBlock: head?.number advances
useRefetchOnNewBlock->>useValidators: call refetch() when throttle window allows
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/scan/lib/ws.ts (1)
168-183: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHook logic is sound; two behavioral nuances worth confirming.
The throttle is correct and won't flood (one
refetchperminIntervalMs, no re-render loop since the dep is the primitivehead?.number). Two points to confirm are intended:
Leading-edge throttle with drop, no trailing call. A block that lands inside the throttle window is dropped, not deferred. On fast chains the next block after the window triggers the refresh, so freshness is fine; if blocks go quiet right after a dropped one, the page only updates on the next poll (15s/30s). That polling fallback makes this acceptable, just worth acknowledging.
refetchexcluded from deps is an implicit caller contract. This is safe foruseTokens/useValidatorstoday because theirrefetchidentity only changes onnetworkchange, which also resetsheadand re-runs the effect with the fresh closure. But the hook silently assumes a stablerefetch; an inline/unstablerefetchfrom a future caller would go stale. Consider documenting that in the hook comment.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/scan/lib/ws.ts` around lines 168 - 183, Document the caller contract for useRefetchOnNewBlock: it uses a leading-edge throttle with dropped intermediate blocks and intentionally omits refetch from the effect deps, so callers must pass a stable refetch. Add a brief note near useRefetchOnNewBlock explaining that useTokens and useValidators are safe because their refetch is network-stable, and that inline/unstable refetch functions would become stale.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/scan/lib/ws.ts`:
- Around line 168-183: Document the caller contract for useRefetchOnNewBlock: it
uses a leading-edge throttle with dropped intermediate blocks and intentionally
omits refetch from the effect deps, so callers must pass a stable refetch. Add a
brief note near useRefetchOnNewBlock explaining that useTokens and useValidators
are safe because their refetch is network-stable, and that inline/unstable
refetch functions would become stale.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4d4a3011-61f3-4f76-afb8-16a085cd0fce
📒 Files selected for processing (3)
apps/scan/app/[locale]/tokens/page.tsxapps/scan/app/[locale]/validators/page.tsxapps/scan/lib/ws.ts
The validators and tokens pages waited a full poll interval (15s and 30s) to reflect chain changes. They now refresh shortly after each new block, using the newHeads websocket the home page already relies on.
What changed
Added useRefetchOnNewBlock(network, refetch) in lib/ws.ts. It subscribes to the shared newHeads websocket and calls the hook's refetch on each new block, throttled to once per 10s. The throttle matters because testnet blocks are ~0.5s apart; without it, slow-changing data like the validator set and token list would refetch many times a second and blow the 60 req/min per-IP budget the poll intervals are sized for.
Wired it into the validators and tokens pages.
Testing
typecheck and build pass. Verified on testnet: the websocket delivers newHeads (the home page refetches per block), and the validators page tightens from a 15s poll to ~10s block-synced refreshes. The tokens page benefits once its EVM-factory cache is warm; during the initial factory walk the in-flight guard dedupes the trigger and it falls back to the 30s poll. No regressions, no console errors.
Notes
Conservative throttle (10s). Could be lowered per page if a fresher view is wanted, within the rate budget. The same hook can be applied to other slow-polling pages later.
Summary by CodeRabbit