Skip to content

fix(exec3): prevent execution loop on zero-gas block regions during initial sync#151

Open
martianacademy wants to merge 1 commit into
0xPolygon:release/3.2from
martianacademy:fix/empty-block-execution-loop
Open

fix(exec3): prevent execution loop on zero-gas block regions during initial sync#151
martianacademy wants to merge 1 commit into
0xPolygon:release/3.2from
martianacademy:fix/empty-block-execution-loop

Conversation

@martianacademy
Copy link
Copy Markdown

Fixes: #150

Problem

When syncing Polygon bor-mainnet from genesis (--no-downloader), the execution stage enters an infinite loop at ~block 856,625. The node repeatedly processes the same 5,000 block batch without advancing because:

  1. Early Polygon blocks have zero gas/zero transactions
  2. LoopBlockLimit (5000) fires and breaks the execution loop
  3. Commitment cannot be saved (txNum is between step boundaries)
  4. Next ExecV3 call reads the same old commitment position → infinite loop

Fix

Add totalGasUsed > 0 to the block limit condition:

- if blockLimit > 0 && blockNum-startBlockNum+1 >= blockLimit {
+ if blockLimit > 0 && blockNum-startBlockNum+1 >= blockLimit && totalGasUsed > 0 {

This lets execution continue through zero-gas block regions (~80K blk/s, essentially free) until blocks with actual state changes are reached where commitment CAN be saved.

Testing

  • Before: Node stuck at block 856,625 (infinite loop)
  • After: Node advanced past 1,100,000+ blocks and counting
  • totalGasUsed is already tracked in the execution loop (line 727), no new variables needed
  • Zero-gas blocks produce no state changes, so processing more is safe and fast

During initial sync of chains with extended zero-gas block regions (e.g.
early Polygon blocks 0-1.2M), the LoopBlockLimit fires after processing
empty blocks but the commitment system cannot save state at the current
txNum (between step boundaries). This causes the next ExecV3 invocation
to read the same old commitment position, creating an infinite loop.

Adding totalGasUsed > 0 to the block limit condition allows execution
to continue through empty-block regions until real transactions are
reached where commitment can be saved.

Fixes: 0xPolygon#150
Copilot AI review requested due to automatic review settings May 5, 2026 07:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR changes the ExecV3 sync-loop exit condition in execution/stagedsync/exec3.go so initial sync can continue through Polygon’s early zero-gas block ranges instead of repeatedly restarting from the same commitment point.

Changes:

  • Adds totalGasUsed > 0 to the LoopBlockLimit guard in ExecV3.
  • Alters initial-sync batching behavior so zero-gas batches no longer immediately return ErrLoopExhausted.
  • Targets the Polygon bor-mainnet infinite-loop scenario described in issue #150.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// until we reach a transaction whose comittement which is writable to the db, otherwise the update will get lost
if !initialCycle || lastExecutedStep > 0 && lastExecutedStep > lastFrozenStep && !dbg.DiscardCommitment() {
if blockLimit > 0 && blockNum-startBlockNum+1 >= blockLimit {
if blockLimit > 0 && blockNum-startBlockNum+1 >= blockLimit && totalGasUsed > 0 {
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.

fix(exec3): execution loops infinitely on zero-gas block regions during initial sync (Polygon bor-mainnet)

2 participants