fix: unblock indexing — nullable Transaction.to + reward Pool guard#247
fix: unblock indexing — nullable Transaction.to + reward Pool guard#247rickstaa wants to merge 2 commits into
Conversation
Contract-creation txs have no recipient, so `event.transaction.to` is null and graph-node aborted on the non-nullable `Transaction.to`. `null` is the correct value (matches graph-ts `Address | null`); no mapping change needed.
reward() loaded the round's Pool with `Pool.load()` and dereferenced it via `pool!`, which aborts the subgraph if the Pool is missing (observed at block 144056642: "unexpected null in handler `reward`" at bondingManager.ts:499). Pools are created per active transcoder in newRound() from on-chain calls (getFirstTranscoderInPool / getNextTranscoderInPool). If that set comes back empty — the call reverted, or an incomplete archive node on a resync — no Pool exists for a transcoder that later calls reward(). Create the Pool on demand so a missing Pool can never hard-halt indexing.
|
Warning Review limit reached
Next review available in: 58 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: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ 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 |
|
🚀 Subgraph Studio preview deployed
curl -H 'Content-Type: application/json' \
-d '{"query":"{ protocol(id: \"0\") { inflation } }"}' \
https://api.studio.thegraph.com/query/31909/livepeer-ci/pr-247-4aa21cd-29754385784 |
…h resyncs (#749) Stopgap while the subgraph resyncs from scratch (livepeer/subgraph#247), which leaves the manually surfaced LIP-118 poll showing 0% support and 0% participation even for people who already voted. Revert this and #734 once the subgraph has reindexed the poll. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot <copilot-pull-request-reviewer[bot]@users.noreply.github.com>
Stopgap while the subgraph resyncs from scratch (livepeer/subgraph#247). The withdrawal list comes from the subgraph, so locks created after indexing stalled are missing from it: an unbond appears to do nothing, and a user with no acknowledgement may reasonably unbond again, moving more stake out for a second full unbonding period. Once such a lock matures it is also withdrawable on-chain while remaining invisible in the UI. Lock ids are sequential and never reused, so anything the subgraph has not seen sits above its highest known id. Add /api/unbonding-locks/[address], which reads that tail from the contract, and append it to the subgraph's list rather than replacing it. The round comes from /api/current-round with it, since a stale round files a matured lock as pending and hides its withdraw button. Only fetched when the subgraph reports degraded and the user is viewing their own account, so a healthy subgraph behaves exactly as before, with no extra request. The scan is bounded to 200 ids so a direct call cannot ask for an unbounded read. This is a bandaid, not a feature: it duplicates state the subgraph owns and should be reverted once indexing has recovered. It also disables itself as that happens, since the ids it fetches are those above what the subgraph reports. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-Authored-By: CodeRabbit <coderabbitai[bot]@users.noreply.github.com>
) Stopgap while the subgraph resyncs from scratch (livepeer/subgraph#247). Locks created after indexing stalled are missing from the withdrawal list, so an unbond appears to do nothing, and a matured lock stays invisible while being withdrawable on-chain. Lock ids are sequential and never reused, so anything the subgraph has not seen sits above its highest known id. Add /api/unbonding-locks/[address] to read that tail from the contract and append it to the subgraph's list rather than replacing it, with the round from /api/current-round since a stale round hides a matured lock's withdraw button. Only fetched when the subgraph reports degraded and on the user's own account, capped at 200 ids. Revert once the subgraph has reindexed. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: CodeRabbit <coderabbitai[bot]@users.noreply.github.com>
Single PR to unblock the Livepeer subgraph in one deploy. Combines two independent fixes (also open separately as #245 and #246):
1.
Transaction.tonullable (#245)Fixes the deterministic halt at block 485100965 — a Tenderize unlock deployed via a constructor has no recipient, so
event.transaction.tois null, butTransaction.towasString!:Change:
schema.graphqlTransaction.to: String!→String. Matches graph-ts (to: Address | null) and Ethereum (a creation txtois null). No mapping change.2. Pool guard in
reward()(#246)Stops
reward()hard-aborting on a missing Pool at block 144056642:Change: create the Pool on demand when
Pool.load()is null.Why combined
Grafting is disabled, so any redeploy triggers a full resync. On that resync, block 144056642 (reward) comes before 485100965 (
to), so both fixes are needed for the subgraph to sync cleanly past the current halt. Deploy this branch to fix production in one shot.Validation
Both reproduced and fixed locally against an Arbitrum One archive RPC — the pre-fix build aborts at 485100965 and 144056642, this branch indexes past both.
yarn codegen+yarn buildpass.Full root-cause notes in #245 (deterministic
tobug) and #246 (defensive Pool guard).🤖 Generated with Claude Code