Points: 200
Labels: frontend, hooks, reliability, rpc, ux
Background: useTransaction.ts polls server.getTransaction(txHash) every POLL_INTERVAL_MS = 2000 with no backoff — if the RPC endpoint is slow or briefly unavailable, polling continues at the same rate, generating unnecessary network load. On a 4GB RAM device on a slow mobile connection, a fixed 2-second poll for a 30-second timeout window is 15 HTTP requests for a single transaction. More critically, the current implementation silently continues polling after an RPC error (the .catch just schedules the next poll). There is no distinction between "RPC temporarily unavailable" (should back off) and "transaction not yet found" (should keep polling normally). There is also no budget: a user who leaves a tab open indefinitely will poll forever.
Task: Rewrite the polling logic in useTransaction.ts to use exponential backoff: start at 1s, double each retry (1s → 2s → 4s → 8s → capped at 15s). Track consecutive RPC errors separately from NOT_FOUND results — after 3 consecutive RPC errors, set status to failed with error "RPC unreachable — please check your connection". Add a maxAttempts: number option (default 12) to useTransaction. Cancel all timers via AbortController or useEffect cleanup ref to prevent memory leaks when the component unmounts mid-poll.
Key files: - frontend/src/hooks/useTransaction.ts — full rewrite of polling logic; add maxAttempts option; exponential backoff; consecutive error tracking
frontend/src/__tests__/ — add useTransaction.test.ts testing: backoff timing, consecutive error threshold, cleanup on unmount
Acceptance criteria: - [ ] Poll intervals follow Math.min(1000 * 2^attempt, 15000) formula
Points: 200
Labels: frontend, hooks, reliability, rpc, ux
Background:
useTransaction.tspollsserver.getTransaction(txHash)everyPOLL_INTERVAL_MS = 2000with no backoff — if the RPC endpoint is slow or briefly unavailable, polling continues at the same rate, generating unnecessary network load. On a 4GB RAM device on a slow mobile connection, a fixed 2-second poll for a 30-second timeout window is 15 HTTP requests for a single transaction. More critically, the current implementation silently continues polling after an RPC error (the.catchjust schedules the next poll). There is no distinction between "RPC temporarily unavailable" (should back off) and "transaction not yet found" (should keep polling normally). There is also no budget: a user who leaves a tab open indefinitely will poll forever.Task: Rewrite the polling logic in
useTransaction.tsto use exponential backoff: start at 1s, double each retry (1s → 2s → 4s → 8s → capped at 15s). Track consecutive RPC errors separately fromNOT_FOUNDresults — after 3 consecutive RPC errors, set status to failed with error "RPC unreachable — please check your connection". Add amaxAttempts: numberoption (default 12) touseTransaction. Cancel all timers viaAbortControlleroruseEffectcleanup ref to prevent memory leaks when the component unmounts mid-poll.Key files: -
frontend/src/hooks/useTransaction.ts— full rewrite of polling logic; add maxAttempts option; exponential backoff; consecutive error trackingfrontend/src/__tests__/— add useTransaction.test.ts testing: backoff timing, consecutive error threshold, cleanup on unmountAcceptance criteria: - [ ] Poll intervals follow Math.min(1000 * 2^attempt, 15000) formula