fix: source round length and lock state on-chain in the round tracker#735
Conversation
RoundStatus still mixed sources after #731: round timing came from the RoundsManager via /current-round, but roundLength and the lock state came from the subgraph (protocol.roundLength / protocol.lockPeriod). The lock state was re-derived client-side (blocksRemaining <= lockPeriod) because the subgraph, being event-driven, can't keep a per-block boolean fresh. Extend /api/current-round to also return roundLength and locked (from RoundsManager.roundLength and currentRoundLocked), and read both from useCurrentRoundData. The lock state now comes straight from currentRoundLocked — one authoritative snapshot instead of re-deriving it — and the round tracker (ring, blocks remaining, lock badge) is fully on-chain and consistent. The spinner now only waits on the on-chain round data, so the tracker renders even when the subgraph is fully down; the subgraph-only stats (fees, rewards, supply) are hidden in that case. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 44 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe current-round API now returns contract-derived lock and round-length data. ChangesCurrent round state
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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.
Pull request overview
This PR completes the shift of the round tracker to a single on-chain source by extending /api/current-round to include roundLength and locked from RoundsManager, and updating RoundStatus to use that data instead of the subgraph for timing/lock-related UI.
Changes:
- Extend
/api/current-roundresponse to includelocked(currentRoundLocked) androundLength(roundLength) fromRoundsManager. - Update
CurrentRoundInfotype to includelockedandroundLength. - Update
RoundStatusto compute progress/remaining blocks and lock badge fromuseCurrentRoundData, and to render even when the subgraphprotocoldata is unavailable (hiding subgraph-only stat rows in that case).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pages/api/current-round.tsx | Adds on-chain reads for currentRoundLocked and roundLength to the current round API response. |
| lib/api/types/get-current-round.ts | Extends CurrentRoundInfo with locked and roundLength. |
| components/RoundStatus/index.tsx | Switches round progress/lock UI to on-chain fields and allows rendering during subgraph outages. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const [ | ||
| id, | ||
| startBlock, | ||
| initialized, | ||
| locked, |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/RoundStatus/index.tsx (1)
40-70: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftNo test coverage for the migrated timing/lock calculations.
blocksRemaining,percentage, andisRoundLockedall switched from subgraph-derived (protocol.*) to on-chain (currentRoundInfo.*) sources — a meaningful behavior change with no accompanying tests in this changeset for the new calculation paths or the loading/lock states.🤖 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 `@components/RoundStatus/index.tsx` around lines 40 - 70, Add tests for the RoundStatus timing and lock calculations covering on-chain currentRoundInfo values, including blocksRemaining, percentage, and isRoundLocked. Include uninitialized/loading data and locked/unlocked states, and verify the rendered output reflects each calculation path.
🤖 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.
Inline comments:
In `@components/RoundStatus/index.tsx`:
- Around line 62-70: Update the isRoundLocked state used by the header badge and
tooltip in RoundStatus to preserve an explicit loading state while
currentRoundInfo is unavailable, rather than defaulting to false. Render a
neutral loading or skeleton indicator for that state, and keep the existing
locked/unlocked labels and icons once currentRoundInfo has resolved.
---
Outside diff comments:
In `@components/RoundStatus/index.tsx`:
- Around line 40-70: Add tests for the RoundStatus timing and lock calculations
covering on-chain currentRoundInfo values, including blocksRemaining,
percentage, and isRoundLocked. Include uninitialized/loading data and
locked/unlocked states, and verify the rendered output reflects each calculation
path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: de6ba784-fa7c-4355-b8b3-5ff15cf15cdb
📒 Files selected for processing (3)
components/RoundStatus/index.tsxlib/api/types/get-current-round.tspages/api/current-round.tsx
isRoundLocked falls back to false before currentRoundInfo resolves, so the header badge asserted "Initialized" while the round data was still loading. Render a skeleton until currentRoundInfo is available, matching the spinner in the content area below. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…livepeer#735) * fix: source round length and lock state on-chain in the round tracker RoundStatus still mixed sources after livepeer#731: round timing came from the RoundsManager via /current-round, but roundLength and the lock state came from the subgraph (protocol.roundLength / protocol.lockPeriod). The lock state was re-derived client-side (blocksRemaining <= lockPeriod) because the subgraph, being event-driven, can't keep a per-block boolean fresh. Extend /api/current-round to also return roundLength and locked (from RoundsManager.roundLength and currentRoundLocked), and read both from useCurrentRoundData. The lock state now comes straight from currentRoundLocked — one authoritative snapshot instead of re-deriving it — and the round tracker (ring, blocks remaining, lock badge) is fully on-chain and consistent. The spinner now only waits on the on-chain round data, so the tracker renders even when the subgraph is fully down; the subgraph-only stats (fees, rewards, supply) are hidden in that case. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * chore: drop redundant comment in RoundStatus Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix: show a loading skeleton for the round lock badge isRoundLocked falls back to false before currentRoundInfo resolves, so the header badge asserted "Initialized" while the round data was still loading. Render a skeleton until currentRoundInfo is available, matching the spinner in the content area below. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
…livepeer#735) * fix: source round length and lock state on-chain in the round tracker RoundStatus still mixed sources after livepeer#731: round timing came from the RoundsManager via /current-round, but roundLength and the lock state came from the subgraph (protocol.roundLength / protocol.lockPeriod). The lock state was re-derived client-side (blocksRemaining <= lockPeriod) because the subgraph, being event-driven, can't keep a per-block boolean fresh. Extend /api/current-round to also return roundLength and locked (from RoundsManager.roundLength and currentRoundLocked), and read both from useCurrentRoundData. The lock state now comes straight from currentRoundLocked — one authoritative snapshot instead of re-deriving it — and the round tracker (ring, blocks remaining, lock badge) is fully on-chain and consistent. The spinner now only waits on the on-chain round data, so the tracker renders even when the subgraph is fully down; the subgraph-only stats (fees, rewards, supply) are hidden in that case. * chore: drop redundant comment in RoundStatus * fix: show a loading skeleton for the round lock badge isRoundLocked falls back to false before currentRoundInfo resolves, so the header badge asserted "Initialized" while the round data was still loading. Render a skeleton until currentRoundInfo is available, matching the spinner in the content area below. ---------
Summary
Follow-up to #731. That PR moved the round timing (round id, start block, current block, initialized) to the RoundsManager contract, but
RoundStatusstill readroundLengthand the lock state from the subgraph — so the tracker remained a mixed source.This finishes the job: the round tracker is now sourced entirely from one on-chain snapshot.
What changed
/api/current-roundnow also returnsroundLength(RoundsManager.roundLength) andlocked(RoundsManager.currentRoundLocked), alongside the existing timing reads, in the same cached call (s-maxage=60).RoundStatusreadsroundLengthandlockedfromuseCurrentRoundDatainstead ofprotocol:isRoundLockednow comes straight fromcurrentRoundLocked()rather than re-derivingblocksRemaining <= lockPeriodclient-side. The subgraph had to storelockPeriodand defer the comparison to the client because, being event-driven, it can't keep a per-block boolean fresh; reading the getter directly removes that indirection and is authoritative.Notes
s-maxage=60endpoint, polled every 10s by SWR.lockedand the round timing now refresh from the same atomic snapshot.Testing
pnpm typecheck+pnpm lintpass; pre-commit hooks pass.Summary by CodeRabbit
New Features
Bug Fixes