Skip to content

fix: compare poll endBlock against L1 block number instead of L2 on Arbitrum#213

Merged
rickstaa merged 1 commit intolivepeer:mainfrom
adamsoffer:claude/jolly-lamarr
Mar 4, 2026
Merged

fix: compare poll endBlock against L1 block number instead of L2 on Arbitrum#213
rickstaa merged 1 commit intolivepeer:mainfrom
adamsoffer:claude/jolly-lamarr

Conversation

@adamsoffer
Copy link
Contributor

Summary

  • Poll tally handlers (updatePollTallyOnReward, OnBond, OnUnbond, OnRebond) compare poll.endBlock against event.block.number to check if a poll is still active. On Arbitrum, poll.endBlock is on the L1 block scale (~24M) since Solidity's block.number returns L1-approximate values, but event.block.number in The Graph is the L2 sequential block (~437M). The check always evaluates as "poll ended," so voteStake never updates after the initial vote.
  • Replace event.block.number with getBlockNum() (which calls roundsManager.blockNum() and returns the L1 block number) in all three endBlock checks so both sides of the comparison are on the same scale.

Evidence

Comparing voteStake (Vote entity) vs totalStake (Transcoder entity) for orchestrators with nonVoteStake: 0 on the current active poll (0x9bddf5c1766924e5ea601eb0bb00dc022f5980d0):

Orchestrator voteStake totalStake Gap Voted
0xbd677e...22bd 368,095 369,482 +1,387 02/26
0x5d98...5e60 413,586 415,239 +1,652 02/27
0x9d61...e3c8 287,696 287,696 0 03/02

The gap grows proportionally with time since the vote (accumulated daily rewards). Reward events fire and update Transcoder.totalStake correctly, but the poll tally handlers skip the voteStake update because they think the poll has already ended.

Test plan

  • Verify subgraph builds (yarn prepare && yarn build)
  • Deploy to a staging subgraph and confirm voteStake updates on subsequent Reward/Bond/Unbond/Rebond events for active polls
  • Verify that the endBlock check still correctly stops updates after a poll actually ends

🤖 Generated with Claude Code

…rbitrum

Poll tally handlers compared poll.endBlock (L1 scale, ~24M) against
event.block.number (L2 scale, ~437M), causing the "poll ended" check
to always pass. This prevented voteStake from updating after the
initial vote, so stake changes (rewards, bonding, unbonding) during
an active poll were never reflected in the tally.

Replace event.block.number with getBlockNum() (which calls
roundsManager.blockNum() and returns the L1 block number on Arbitrum)
so both sides of the comparison are on the same scale.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@adamsoffer adamsoffer requested a review from rickstaa as a code owner March 2, 2026 19:15
@rickstaa
Copy link
Member

rickstaa commented Mar 4, 2026

@adamsoffer good find. Approved, as logic checks out will run some validations and then we can merge and publish a patched version.

@rickstaa rickstaa closed this Mar 4, 2026
@rickstaa rickstaa reopened this Mar 4, 2026
@rickstaa
Copy link
Member

rickstaa commented Mar 4, 2026

@rickstaa rickstaa merged commit be668d6 into livepeer:main Mar 4, 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.

2 participants