Skip to content

fix(node): pause derivation during block sync#1020

Open
panos-xyz wants to merge 1 commit into
mainfrom
codex/pause-derivation-during-blocksync
Open

fix(node): pause derivation during block sync#1020
panos-xyz wants to merge 1 commit into
mainfrom
codex/pause-derivation-during-blocksync

Conversation

@panos-xyz

@panos-xyz panos-xyz commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • gate the derivation and finalizer cycle on Tendermint's WaitSync() status
  • defer first-run derivation start-height resolution until P2P block sync completes
  • preserve explicit start heights and existing persisted cursors
  • log block-sync pause/resume transitions once
  • add a deterministic in-process RPC regression test covering repeated pause cycles and successful cursor advancement after resume

Why

A from-zero full node can encounter an L1 CommitBatch before the corresponding L2 blocks arrive over P2P. The local verifier then pins its L1 cursor and retries the same eth_getLogs range until it falls outside a non-archive RPC provider's recent-history window.

Treating initial P2P catch-up as a pre-derivation lifecycle phase prevents unprocessable Rollup log polling and resolves the fresh start height only when derivation is ready to run.

Validation

  • make test
  • make lint
  • make morphnode
  • live Hoodi from-zero sync: with catching_up=true, observed one pause transition and zero new derivation eth_getLogs calls across multiple polling intervals while P2P block sync continued

Closes #1019

Summary by CodeRabbit

  • Bug Fixes
    • Derivation startup now waits for blockchain synchronization to complete before beginning polling.
    • Prevents premature start-height selection and cursor persistence during initial sync.
    • Automatically resumes L1/L2 polling once synchronization is ready.

Defer first-run L1 cursor initialization until Tendermint has caught up, preventing Rollup log polling from becoming archival during from-zero syncs.\n\nCloses #1019
@panos-xyz panos-xyz requested a review from a team as a code owner July 14, 2026 06:59
@panos-xyz panos-xyz requested review from SecurityLife and removed request for a team July 14, 2026 06:59
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 89883bac-44ab-45fd-a952-84e1fb382689

📥 Commits

Reviewing files that changed from the base of the PR and between 21d05b9 and 223bb9f.

📒 Files selected for processing (2)
  • node/derivation/derivation.go
  • node/derivation/derivation_test.go

📝 Walkthrough

Walkthrough

Derivation startup now waits for P2P block synchronization, defers first-run L1 start-height initialization, and resumes derivation and finalization after synchronization. A regression test verifies no L1 polling or cursor persistence during catch-up.

Changes

Derivation sync gating

Layer / File(s) Summary
Sync status wiring
node/derivation/derivation.go
Derivation stores an internal sync-status interface, obtains the consensus reactor when available, and defers default startHeight initialization.
Startup gating and regression coverage
node/derivation/derivation.go, node/derivation/derivation_test.go
Start() pauses derivation work while the node is catching up, resolves an unset first-run height after readiness, and tests L1 polling and cursor persistence across the sync transition.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Derivation
  participant NodeSyncStatus
  participant L1RPC
  participant DerivationDB

  Derivation->>NodeSyncStatus: Check WaitSync()
  NodeSyncStatus-->>Derivation: catching_up=true
  Derivation->>Derivation: defer derivation and finalizer
  Derivation->>NodeSyncStatus: Check WaitSync()
  NodeSyncStatus-->>Derivation: catching_up=false
  Derivation->>L1RPC: read confirmed height and rollup logs
  Derivation->>DerivationDB: persist L1 cursor
Loading

Suggested reviewers: securitylife, curryxbo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely matches the main change: pausing derivation during block sync.
Linked Issues check ✅ Passed The changes implement block-sync gating for derivation/finalization, defer first-run start height, preserve cursors, and add regression coverage.
Out of Scope Changes check ✅ Passed Only derivation startup logic and its regression test changed; no unrelated scope creep is evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/pause-derivation-during-blocksync

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@curryxbo

Copy link
Copy Markdown
Contributor

Reviewed against the derivation code — approach is sound. Two clarifications + a coverage note:

  1. Not a security regression. Pre-PR already trusts history: startHeight defaults to the latest confirmed L1 head (derivation.go:166-172), so everything below the first verified batch was already trusted. This PR only changes when that head is sampled (process-start → post-catch-up); the only delta is the initial-sync window, which an archive node would previously have verified and this skips. It preserves the existing trust model and fixes the non-archive stall.
  2. Coverage gap — from-zero only. ensureStartHeight no-ops when a cursor exists and derivation resumes from cursor+1, so an existing node restarted after downtime > the non-archive window still resumes from a stale cursor → 403, same as node: pause derivation while P2P block sync is catching up #1019. Worth stating as out-of-scope or handling via the same mechanism.
  3. layer1 correctly unaffected (tmNode==nilnodeSyncStatus==nil → gate always ready). 👍

Suggestions: log the resolved startHeight / trusted L2 boundary (the trust is currently silent); and consider an explicit, resettable trust-height knob covering both from-zero and fell-behind nodes rather than a from-zero-only auto-default.

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.

node: pause derivation while P2P block sync is catching up

2 participants