From 062a33e2086a6e485fb83a47b59a112916ef71dc Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Tue, 6 Jan 2026 22:42:23 +0900 Subject: [PATCH 1/6] feat: Kona Rollup Node Light CL --- protocol/kona-node-light-cl.md | 264 +++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 protocol/kona-node-light-cl.md diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md new file mode 100644 index 00000000..54a1e362 --- /dev/null +++ b/protocol/kona-node-light-cl.md @@ -0,0 +1,264 @@ +# kona-node: Light CL (Follow Mode) + +| | | +| ------------------ |-----------------------------------| +| Author | _@pcw109550_ | +| Created at | _2026-01-06_ | +| Initial Reviewers | _@theochap_ | +| Need Approval From | | +| Status | _Draft_ | + +## Summary + +This document describes the design and implementation of Light CL (follow mode) as implemented in kona-node. In this mode, the node disables local L1->L2 derivation and instead mirrors the safe, finalized, and currentL1 views from an external OP Stack Consensus Layer (CL) node, while continuing to execute the local Execution Layer (EL) and maintain unsafe chain progression. + +Light CL follow mode reduces responsibility coupling within the consensus layer by separating derivation from execution and synchronization. Rather than producing safe and finalized blocks locally, kona-node ingests externally derived consensus data, validates it against canonical L1, and injects it into the local engine using well-defined rules that preserve existing OP Stack behavior, including unsafe consolidation and reorganization semantics. + +This document is descriptive of the kona-node implementation, but normative with respect to Light CL invariants and behavior. It focuses on *how* follow mode is realized in kona-node, including architectural changes, core algorithms, actor interactions, and failure modes. + +## Problem Statement + Context + +In normal operation, an OP Stack consensus layer (CL) node is responsible for multiple tightly coupled tasks: + +- Tracking unsafe, safe, and finalized views of the L2 chain +- Driving the Execution Layer (EL) to match those views +- Deriving safe and finalized L2 blocks from L1 data +- Maintaining the L1 derivation cursor (`currentL1`) + +This coupling increases complexity, makes failure isolation harder, and prevents certain deployment and interoperability patterns. In particular, it is difficult to operate a CL node that executes and synchronizes L2 state without also deriving L2 state from L1. + +Light CL follow mode addresses this by explicitly removing derivation responsibilities from the node. Safe, finalized, and currentL1 information is sourced from an external CL that performs derivation, while kona-node focuses on validation, execution, and synchronization. + +## Design Goals + +Light CL follow mode is designed to: + +- Fully disable local derivation logic +- Preserve unsafe chain progression semantics +- Mirror externally derived safe/finalized/currentL1 data +- Validate external data against canonical L1 +- Preserve existing unsafe consolidation and reorg behavior +- Minimize changes to existing execution and networking logic + +Non-goals include re-deriving or re-verifying derivation correctness locally, or providing recovery mechanisms beyond those already inherent in following an external source. + +## Light CL Core Semantics + +### Responsibilities Dropped + +When follow mode is enabled, kona-node does not: + +- Run any L1->L2 derivation pipeline +- Emit safe attributes +- Schedule derivation stages +- Advance safe or finalized heads based on local derivation + +### Responsibilities Retained + +In follow mode, kona-node continues to: + +- Track and advance the unsafe L2 head +- Execute L2 blocks via the Execution Layer +- Maintain P2P networking and receive unsafe blocks +- Produce unsafe blocks when operating as a sequencer +- Track canonical L1 and system configuration updates + +### Authority and Trust Model + +- Canonical L1 is the ultimate source of truth. +- External CL data (safe, finalized, currentL1) is assumed to be correctly derived, subject to L1 consistency checks. +- Local unsafe state is authoritative only until overridden by validated external safe data. + +A hard invariant in follow mode is: The node must never emit safe attributes locally. + +## External Source Contract + +Follow mode requires an external CL endpoint exposing the `optimism_syncStatus` RPC API. This API provides: + +- `safeL2` +- `finalizedL2` +- `currentL1` + +These fields are sufficient to replace local derivation output. No additional APIs are required. + +The external source is trusted to have performed derivation correctly. Kona-node does not re-derive or re-verify derivation correctness; it only validates consistency with canonical L1. + +## L1 Canonicality Validation + +Although derivation is disabled, kona-node still requires an L1 RPC endpoint. This is necessary for: + +- Tracking system configuration updates +- Tracking L1 origin for sequencer operation +- Validating external consensus data + +Before external data is injected, kona-node validates that: + +- L1 origins referenced by external safe/finalized blocks are canonical +- The external `currentL1` corresponds to a canonical L1 block + +If validation fails, the external data is dropped and not applied. This validation is necessary but not sufficient for correctness; it acts as a safety gate rather than full verification. + +## Proposed Solution + +### Follow Mode Architecture + +When follow mode is enabled (`--l2.follow.source=[L2_CL_RPC]` provided): + +1. The Rollup Node Service spawns a FollowActor and does not construct a DerivationActor. +2. The EngineActor completes initial EL synchronization. +3. The EngineActor signals the FollowActor that initial EL sync has completed. +4. The FollowActor polls the external CL's `optimism_syncStatus` endpoint at a fixed interval. +5. External data is validated against canonical L1. +6. Validated follow data is sent to the EngineActor. +7. Unsafe blocks continue to arrive via P2P gossip or local sequencing. + +The following diagram illustrates the difference between normal operation and follow mode. +In follow mode, the DerivationActor is not constructed, and a FollowActor is introduced to +ingest and validate external consensus data before applying it to the EngineActor. + +```mermaid +flowchart TB + +%% ========================= +%% Panel A: Normal Mode +%% ========================= +subgraph A ["Normal Mode (Derivation)"] + direction TB + + subgraph A0 ["Rollup Node Service"] + direction TB + A_Derivation["DerivationActor
(L1->L2 derivation)"] + A_Engine["EngineActor
(Apply unsafe/safe/finalized)"] + A_UnsafeSrc["Unsafe Source
(P2P gossip / Sequencer)"] + end + + A_L1[(L1 RPC)] + A_EL[(Execution Layer)] + + A_L1 -->|L1 info| A_Derivation + A_UnsafeSrc -->|unsafe blocks| A_Engine + A_Derivation -->|safe/finalized/currentL1| A_Engine + A_Engine -->|engine API| A_EL +end + +%% ========================= +%% Panel B: Follow Mode +%% ========================= +subgraph B ["Follow Mode (Light CL)"] + direction TB + + subgraph B0 ["Rollup Node Service"] + direction TB + B_Follow[["FollowActor
(NEW: Poll external syncStatus)"]] + B_Engine["EngineActor
(New Follow Handler)"] + B_UnsafeSrc["Unsafe Source
(P2P gossip / Sequencer)"] + B_DerivationX[[DerivationActor
DISABLED]] + end + + B_L1[(L1 RPC)] + B_Ext[(External CL RPC
optimism_syncStatus)] + B_EL[(Execution Layer)] + + %% Connections + B_Ext -->|safe/finalized/currentL1| B_Follow + B_L1 -->|canonical L1 check| B_Follow + B_Follow -->|"FollowStatus (validated)"| B_Engine + B_UnsafeSrc -->|unsafe blocks| B_Engine + + %% Visual indicator for disabled actor + B_DerivationX -.->|NOT CONSTRUCTED| B_Engine + B_Engine -->|engine API| B_EL +end +``` + + +## Follow Mode Core Algorithm + +The follow algorithm determines how external safe/finalized data is applied relative to local unsafe state. It consists of the following cases: + +### Case 1: External Safe Ahead of Local Unsafe +The unsafe head is reset to the external safe head, and the EL is synchronized accordingly. This mirrors existing behavior where derivation advances safe beyond unsafe. + +### Case 2a: External Block Not Found Locally +This indicates that EL synchronization is still in progress. The safe head is updated, but unsafe is left unchanged to avoid interrupting block insertion. + +### Case 2b: External Query Error +The error is treated as transient and the update is skipped. + +### Case 3: Hashes Match +Unsafe is consolidated into safe. This is equivalent to consolidation when derivation is enabled. + +### Case 4: Hash Mismatch +A reorganization is detected. Unsafe is reset to the external safe head, mirroring reorg behavior under derivation. + +This algorithm preserves existing OP Stack semantics for consolidation and reorganization. + +## kona-node Implementation + +### FollowActor + +Following kona-node's actor-based architecture, external data ingestion and validation is isolated into a dedicated FollowActor. + +The FollowActor is responsible for: + +- Waiting for initial EL synchronization +- Polling the external CL +- Validating external data against L1 +- Emitting validated follow status to the EngineActor + +This actor isolates external interaction and validation logic, keeping EngineActor focused on state application and invariant preservation. + +### EngineActor Integration + +In follow mode, the EngineActor applies externally sourced consensus updates by enqueueing a new engine task type, `FollowTask`. + +`FollowTask` is intentionally implemented as a thin wrapper over `SynchronizeTask`. Its purpose is to represent an external follow update as a first-class engine event with explicit scheduling priority, logging, and error semantics. This mirrors existing engine patterns where `InsertTask`, `ConsolidateTask`, and `FinalizeTask` are queueable events that ultimately drive engine state transitions through shared synchronization logic. + +Task priority is chosen to preserve existing behavior and invariants: + +- `InsertTask` (unsafe block insertion) remains the highest-priority path to avoid starving unsafe progression from P2P gossip or local sequencing. +- `FollowTask` is prioritized above `FinalizeTask` and `ConsolidateTask` to ensure externally authoritative safe/finalized updates are applied promptly. +- In follow mode, `FinalizeTask` and `ConsolidateTask` are not expected to be scheduled, as no derived attributes are produced and follow updates replace derivation-driven safe/finalized advancement. + +### DerivationActor Omission + +DerivationActor is not constructed in follow mode. This is intentional: + +- DerivationActor owns logic that must never execute in follow mode +- Not constructing it is safer than conditionally disabling behavior + +### L2Finalizer Behavior + +L2Finalizer remains enabled but becomes effectively inactive: + +- No derived blocks are enqueued for finalization +- L1 finality continues to be tracked +- Finality injection is handled via follow updates + +This preserves L1-priority semantics without introducing special-case removal. + + +## Sequencer Compatibility + +Follow mode is compatible with sequencer operation: + +- Unsafe block production continues normally +- Safe/finalized views are externally sourced +- Unsafe blocks may be reorged to match external safe data + +Sequencer logic does not assume local derivation and remains valid under these constraints. + +## Failure Mode Analysis + +- External CL stalls: Safe and finalized progression stalls; the node remains operational. +- External CL reorgs: The node follows and reorgs accordingly. +- L1 RPC failure: Identical to failure modes in normal operation. +- External data invalid vs L1: Data is dropped and not applied. + +Follow mode intentionally trades autonomy for simplicity; recovery depends on external availability. + +## Risks & Uncertainties + +- Reliance on external CL correctness +- Assumes long-term stability of `optimism_syncStatus` semantics + From 7781ce4c71b3c4f0941743a2d25210dad69d519d Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Wed, 7 Jan 2026 22:09:53 +0900 Subject: [PATCH 2/6] Add concrete scenario --- protocol/kona-node-light-cl.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md index 54a1e362..1ef6dea7 100644 --- a/protocol/kona-node-light-cl.md +++ b/protocol/kona-node-light-cl.md @@ -27,6 +27,8 @@ In normal operation, an OP Stack consensus layer (CL) node is responsible for mu This coupling increases complexity, makes failure isolation harder, and prevents certain deployment and interoperability patterns. In particular, it is difficult to operate a CL node that executes and synchronizes L2 state without also deriving L2 state from L1. +Derivation is an expensive process, both computationally and I/O bound, and today each isolated node typically performs this work independently. As OP Stack deployments move toward interoperability scenarios, this cost becomes more pronounced: verification may require additional sanity checks across multiple L2 chains, increasing resource contention and operational overhead. In such environments, it can be desirable to delegate derivation and cross-chain sanity checking to a specialized node and have execution-focused nodes consume the resulting `{safe, finalized, currentL1}` views, rather than re-deriving them locally. + Light CL follow mode addresses this by explicitly removing derivation responsibilities from the node. Safe, finalized, and currentL1 information is sourced from an external CL that performs derivation, while kona-node focuses on validation, execution, and synchronization. ## Design Goals From 9a372965243928ead9a9371dbc3fa8c8905b0afc Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Fri, 9 Jan 2026 23:26:15 +0900 Subject: [PATCH 3/6] Apply Design Review Consensus --- protocol/kona-node-light-cl.md | 216 +++++++++++++++------------------ 1 file changed, 97 insertions(+), 119 deletions(-) diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md index 1ef6dea7..dbce234d 100644 --- a/protocol/kona-node-light-cl.md +++ b/protocol/kona-node-light-cl.md @@ -1,20 +1,20 @@ -# kona-node: Light CL (Follow Mode) +# kona-node: Light CL -| | | -| ------------------ |-----------------------------------| -| Author | _@pcw109550_ | -| Created at | _2026-01-06_ | -| Initial Reviewers | _@theochap_ | -| Need Approval From | | -| Status | _Draft_ | +| | | +| ------------------ |---------------------------------------| +| Author | _@pcw109550_ | +| Created at | _2026-01-06_ | +| Initial Reviewers | _@theochap_ | +| Need Approval From | | +| Status | _IN_REVIEW_ | ## Summary -This document describes the design and implementation of Light CL (follow mode) as implemented in kona-node. In this mode, the node disables local L1->L2 derivation and instead mirrors the safe, finalized, and currentL1 views from an external OP Stack Consensus Layer (CL) node, while continuing to execute the local Execution Layer (EL) and maintain unsafe chain progression. +This document describes the design and implementation of Light CL as implemented in kona-node. In this mode, the node disables local L1->L2 derivation and instead mirrors the safe, finalized, and currentL1 views from an external OP Stack Consensus Layer (CL) node, while continuing to execute the local Execution Layer (EL) and maintain unsafe chain progression. -Light CL follow mode reduces responsibility coupling within the consensus layer by separating derivation from execution and synchronization. Rather than producing safe and finalized blocks locally, kona-node ingests externally derived consensus data, validates it against canonical L1, and injects it into the local engine using well-defined rules that preserve existing OP Stack behavior, including unsafe consolidation and reorganization semantics. +Light CL reduces responsibility coupling within the consensus layer by separating derivation from execution and synchronization. Rather than producing safe and finalized blocks locally, kona-node ingests externally derived consensus data, validates it against canonical L1, and injects it into the local engine using well-defined rules that preserve existing OP Stack behavior, including unsafe consolidation and reorganization semantics. -This document is descriptive of the kona-node implementation, but normative with respect to Light CL invariants and behavior. It focuses on *how* follow mode is realized in kona-node, including architectural changes, core algorithms, actor interactions, and failure modes. +This document is descriptive of the kona-node implementation, but normative with respect to Light CL invariants and behavior. It focuses on *how* light CL is realized in kona-node, including architectural changes, actor interactions / updates, and failure modes. ## Problem Statement + Context @@ -29,11 +29,11 @@ This coupling increases complexity, makes failure isolation harder, and prevents Derivation is an expensive process, both computationally and I/O bound, and today each isolated node typically performs this work independently. As OP Stack deployments move toward interoperability scenarios, this cost becomes more pronounced: verification may require additional sanity checks across multiple L2 chains, increasing resource contention and operational overhead. In such environments, it can be desirable to delegate derivation and cross-chain sanity checking to a specialized node and have execution-focused nodes consume the resulting `{safe, finalized, currentL1}` views, rather than re-deriving them locally. -Light CL follow mode addresses this by explicitly removing derivation responsibilities from the node. Safe, finalized, and currentL1 information is sourced from an external CL that performs derivation, while kona-node focuses on validation, execution, and synchronization. +Light CL addresses this by explicitly removing derivation responsibilities from the node. Safe, finalized, and currentL1 information is sourced from an external CL that performs derivation, while kona-node focuses on validation, execution, and synchronization. ## Design Goals -Light CL follow mode is designed to: +Light CL is designed to: - Fully disable local derivation logic - Preserve unsafe chain progression semantics @@ -44,11 +44,11 @@ Light CL follow mode is designed to: Non-goals include re-deriving or re-verifying derivation correctness locally, or providing recovery mechanisms beyond those already inherent in following an external source. -## Light CL Core Semantics +## Light CL Semantics ### Responsibilities Dropped -When follow mode is enabled, kona-node does not: +When Light CL is enabled, kona-node does not: - Run any L1->L2 derivation pipeline - Emit safe attributes @@ -57,40 +57,50 @@ When follow mode is enabled, kona-node does not: ### Responsibilities Retained -In follow mode, kona-node continues to: +In light CL, kona-node continues to: - Track and advance the unsafe L2 head - Execute L2 blocks via the Execution Layer - Maintain P2P networking and receive unsafe blocks - Produce unsafe blocks when operating as a sequencer -- Track canonical L1 and system configuration updates +- Track canonical L1 ### Authority and Trust Model - Canonical L1 is the ultimate source of truth. -- External CL data (safe, finalized, currentL1) is assumed to be correctly derived, subject to L1 consistency checks. +- External CL data (`{safeL2, finalizedL2, currentL1}`) is assumed to be correctly derived, subject to L1 consistency checks. - Local unsafe state is authoritative only until overridden by validated external safe data. -A hard invariant in follow mode is: The node must never emit safe attributes locally. +### Bidirectional Messaging and Unidirectional Authority -## External Source Contract +In deployments where a Light CL sequencer follows a normal verifier, there is a bidirectional interaction at the network (or RPC) level. The Light CL sequencer gossips unsafe blocks that the verifier may consume as candidates, while the verifier exposes state(`{safeL2, finalizedL2, currentL1}`) that the Light CL sequencer follows. -Follow mode requires an external CL endpoint exposing the `optimism_syncStatus` RPC API. This API provides: +Despite this bidirectional messaging, authority remains strictly one-directional. Unsafe blocks are proposal-only and never advance safe state. The verifier safe chain is derived from canonical L1, and the Light CL sequencer safe chain follows the verifier safe chain, not the other way around. -- `safeL2` -- `finalizedL2` -- `currentL1` +As a result, this interaction does not introduce circular control dependencies or correctness-level race conditions. -These fields are sufficient to replace local derivation output. No additional APIs are required. +### External Source Contract -The external source is trusted to have performed derivation correctly. Kona-node does not re-derive or re-verify derivation correctness; it only validates consistency with canonical L1. +Light CL requires an external CL endpoint `L2_CL_RPC` exposing the `optimism_syncStatus` RPC API. This API response provides `{safeL2, finalizedL2, currentL1}`. These fields are sufficient to replace local derivation output. No additional APIs are required. -## L1 Canonicality Validation +The external source is trusted to have performed derivation correctly. The light CL does not check derivation correctness; it only validates consistency with canonical L1. -Although derivation is disabled, kona-node still requires an L1 RPC endpoint. This is necessary for: +#### Cycles and Authority Graph Constraints -- Tracking system configuration updates -- Tracking L1 origin for sequencer operation +While it is technically possible for a Light CL to follow another Light CL, operators must avoid cycles in the light CL dependency graph. + +Circular dependencies in `{safeL2, finalizedL2, currentL1}` authority can lead to undefined behavior and circular trust assumptions. + +Operational guidance: +- The light CL dependency graph must be acyclic +- At least one node in the graph must terminate in a deriving rollup node that directly consumes L1 data + +### L1 Canonicality Tracking and Validation + +Although local derivation is disabled, kona-node still requires an L1 RPC endpoint. This is necessary for(non-exhaustive): + +- Tracking [L1 System Config](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/protocol/system-config.md) Updates +- Tracking [L1 origin](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/glossary.md#l1-origin) for sequencer operation - Validating external consensus data Before external data is injected, kona-node validates that: @@ -100,37 +110,30 @@ Before external data is injected, kona-node validates that: If validation fails, the external data is dropped and not applied. This validation is necessary but not sufficient for correctness; it acts as a safety gate rather than full verification. -## Proposed Solution +### Finalization Source in Light CL -### Follow Mode Architecture +In light CL, kona-node no longer carries full derivation metadata and instead ingests only lightweight L2 block information(`L2BlockInfo`). Without reliable L1->L2 mapping data, the node cannot determine locally when a safe L2 block is eligible for finalization without reintroducing derivation-like tracking. To avoid this coupling, finalized state is treated as externally derived and injected directly from the external CL. + +## Proposed Solution -When follow mode is enabled (`--l2.follow.source=[L2_CL_RPC]` provided): +### Overview -1. The Rollup Node Service spawns a FollowActor and does not construct a DerivationActor. -2. The EngineActor completes initial EL synchronization. -3. The EngineActor signals the FollowActor that initial EL sync has completed. -4. The FollowActor polls the external CL's `optimism_syncStatus` endpoint at a fixed interval. -5. External data is validated against canonical L1. -6. Validated follow data is sent to the EngineActor. -7. Unsafe blocks continue to arrive via P2P gossip or local sequencing. +Kona-node updates the existing DerivationActor and EngineActor without introducing new actors. DerivationActor and EngineActor are tweaked for obtaining clear responsibility separation: -The following diagram illustrates the difference between normal operation and follow mode. -In follow mode, the DerivationActor is not constructed, and a FollowActor is introduced to -ingest and validate external consensus data before applying it to the EngineActor. +- Target Determination : Determining which L2 block should become the next safe or finalized head. +- Fork Choice Update : Applying that target to local state and performing any required reorganization. +The following diagram illustrates the difference between normal operation and light CL. ```mermaid flowchart TB -%% ========================= -%% Panel A: Normal Mode -%% ========================= subgraph A ["Normal Mode (Derivation)"] direction TB subgraph A0 ["Rollup Node Service"] direction TB A_Derivation["DerivationActor
(L1->L2 derivation)"] - A_Engine["EngineActor
(Apply unsafe/safe/finalized)"] + A_Engine["EngineActor"] A_UnsafeSrc["Unsafe Source
(P2P gossip / Sequencer)"] end @@ -138,23 +141,19 @@ subgraph A ["Normal Mode (Derivation)"] A_EL[(Execution Layer)] A_L1 -->|L1 info| A_Derivation - A_UnsafeSrc -->|unsafe blocks| A_Engine - A_Derivation -->|safe/finalized/currentL1| A_Engine + A_UnsafeSrc -->|unsafe| A_Engine + A_Derivation -->|"safe(attr)/finalized"| A_Engine A_Engine -->|engine API| A_EL end -%% ========================= -%% Panel B: Follow Mode -%% ========================= -subgraph B ["Follow Mode (Light CL)"] +subgraph B ["Light CL Mode"] direction TB subgraph B0 ["Rollup Node Service"] direction TB - B_Follow[["FollowActor
(NEW: Poll external syncStatus)"]] - B_Engine["EngineActor
(New Follow Handler)"] + B_DerivationX[["DerivationActor
(NEW: Poll external syncStatus)"]] + B_Engine["EngineActor"] B_UnsafeSrc["Unsafe Source
(P2P gossip / Sequencer)"] - B_DerivationX[[DerivationActor
DISABLED]] end B_L1[(L1 RPC)] @@ -162,87 +161,55 @@ subgraph B ["Follow Mode (Light CL)"] B_EL[(Execution Layer)] %% Connections - B_Ext -->|safe/finalized/currentL1| B_Follow - B_L1 -->|canonical L1 check| B_Follow - B_Follow -->|"FollowStatus (validated)"| B_Engine - B_UnsafeSrc -->|unsafe blocks| B_Engine + B_Ext -->|safe/finalized/currentL1| B_DerivationX + B_L1 -->|canonical L1 check| B_DerivationX + B_DerivationX -->|"safe(blockInfo)/finalized (validated)"| B_Engine + B_UnsafeSrc -->|unsafe| B_Engine %% Visual indicator for disabled actor - B_DerivationX -.->|NOT CONSTRUCTED| B_Engine B_Engine -->|engine API| B_EL end ``` +#### Unifying Safe and Finalized Target Selection +To cleanly separate the responsibility, the logic for selecting the finalized target is moved from the EngineActor to the DerivationActor. The EngineActor still executes finalization through `FinalizeTask`, but it no longer determines which block becomes finalized; it applies the finalized head selected by the DerivationActor. This change enables externally determined safe/finalized information to integrate cleanly. -## Follow Mode Core Algorithm - -The follow algorithm determines how external safe/finalized data is applied relative to local unsafe state. It consists of the following cases: - -### Case 1: External Safe Ahead of Local Unsafe -The unsafe head is reset to the external safe head, and the EL is synchronized accordingly. This mirrors existing behavior where derivation advances safe beyond unsafe. - -### Case 2a: External Block Not Found Locally -This indicates that EL synchronization is still in progress. The safe head is updated, but unsafe is left unchanged to avoid interrupting block insertion. - -### Case 2b: External Query Error -The error is treated as transient and the update is skipped. - -### Case 3: Hashes Match -Unsafe is consolidated into safe. This is equivalent to consolidation when derivation is enabled. - -### Case 4: Hash Mismatch -A reorganization is detected. Unsafe is reset to the external safe head, mirroring reorg behavior under derivation. - -This algorithm preserves existing OP Stack semantics for consolidation and reorganization. +#### DerivationActor - Target Determination -## kona-node Implementation +In normal mode: +- Derives `safeL2` as safe attributes through the local L1->L2 derivation pipeline. +- Determines `finalizedL2` by monitoring the L1 finalized head. +- Derivation Cursor as `currentL1`. -### FollowActor +In light CL mode: +- Uses external CL output (`safeL2` and `finalizedL2` provided as `L2BlockInfo`, `currentL1` as `L1BlockInfo`). +- Performs canonical L1 checks. -Following kona-node's actor-based architecture, external data ingestion and validation is isolated into a dedicated FollowActor. +In both modes, the DerivationActor is the single authority for deciding the next safe and finalized heads, and starts determining after the initial EL sync is done. -The FollowActor is responsible for: +#### EngineActor - Fork Choice Update -- Waiting for initial EL synchronization -- Polling the external CL -- Validating external data against L1 -- Emitting validated follow status to the EngineActor +The EngineActor: +- Applies the safe target via `ConsolidateTask`. +- Applies the finalized target via `FinalizeTask`. +- Performs any required reorganization using existing forkchoice mechanics. +- Drives EL state transitions for promoted blocks. -This actor isolates external interaction and validation logic, keeping EngineActor focused on state application and invariant preservation. +`ConsolidateTask` is extended to support two input types: +- Normal mode: safe attributes (`OpAttributesWithParent`) +- Light CL mode: external `L2BlockInfo`. -### EngineActor Integration +During `ConsolidateTask`, In light CL mode: +- Attribute validation is skipped because the input is `L2BlockInfo`. +- If the unsafe chain disagrees with the target, reorg is performed using fork choice. -In follow mode, the EngineActor applies externally sourced consensus updates by enqueueing a new engine task type, `FollowTask`. - -`FollowTask` is intentionally implemented as a thin wrapper over `SynchronizeTask`. Its purpose is to represent an external follow update as a first-class engine event with explicit scheduling priority, logging, and error semantics. This mirrors existing engine patterns where `InsertTask`, `ConsolidateTask`, and `FinalizeTask` are queueable events that ultimately drive engine state transitions through shared synchronization logic. - -Task priority is chosen to preserve existing behavior and invariants: - -- `InsertTask` (unsafe block insertion) remains the highest-priority path to avoid starving unsafe progression from P2P gossip or local sequencing. -- `FollowTask` is prioritized above `FinalizeTask` and `ConsolidateTask` to ensure externally authoritative safe/finalized updates are applied promptly. -- In follow mode, `FinalizeTask` and `ConsolidateTask` are not expected to be scheduled, as no derived attributes are produced and follow updates replace derivation-driven safe/finalized advancement. - -### DerivationActor Omission - -DerivationActor is not constructed in follow mode. This is intentional: - -- DerivationActor owns logic that must never execute in follow mode -- Not constructing it is safer than conditionally disabling behavior - -### L2Finalizer Behavior - -L2Finalizer remains enabled but becomes effectively inactive: - -- No derived blocks are enqueued for finalization -- L1 finality continues to be tracked -- Finality injection is handled via follow updates - -This preserves L1-priority semantics without introducing special-case removal. +`FinalizeTask` is reused unchanged. +Unsafe blocks continue to be ingested from P2P gossip or local sequencing. ## Sequencer Compatibility -Follow mode is compatible with sequencer operation: +Light CL is compatible with sequencer operation: - Unsafe block production continues normally - Safe/finalized views are externally sourced @@ -257,10 +224,21 @@ Sequencer logic does not assume local derivation and remains valid under these c - L1 RPC failure: Identical to failure modes in normal operation. - External data invalid vs L1: Data is dropped and not applied. -Follow mode intentionally trades autonomy for simplicity; recovery depends on external availability. +Light CL intentionally trades autonomy for simplicity; recovery depends on external availability. ## Risks & Uncertainties - Reliance on external CL correctness - Assumes long-term stability of `optimism_syncStatus` semantics +## Alternatives Considered + +### Follow Actor and Follow Task + +An earlier design introduced a dedicated FollowActor responsible for polling an external CL and injecting safe and finalized updates into the EngineActor via a new FollowTask. This approach treated externally derived consensus data as a parallel input path distinct from the normal derivation pipeline. + +This design was ultimately rejected for the following reasons: +- It introduced an additional actor and task type without creating a clear new responsibility boundary. +- It duplicated scheduling, prioritization, and consolidation logic that already exists in the EngineActor task pipeline. +- It required custom consolidation and reorganization logic for followed updates. + From 3b4217c9c1a8aea4c2b61362c1a7143db1fe8602 Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Sun, 11 Jan 2026 19:21:15 +0900 Subject: [PATCH 4/6] Apply second round review --- protocol/kona-node-light-cl.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md index dbce234d..84e214c5 100644 --- a/protocol/kona-node-light-cl.md +++ b/protocol/kona-node-light-cl.md @@ -10,7 +10,7 @@ ## Summary -This document describes the design and implementation of Light CL as implemented in kona-node. In this mode, the node disables local L1->L2 derivation and instead mirrors the safe, finalized, and currentL1 views from an external OP Stack Consensus Layer (CL) node, while continuing to execute the local Execution Layer (EL) and maintain unsafe chain progression. +This document describes the design and implementation of a Light CL configuration of kona-node. In this mode, L1->L2 derivation is executed by an external OP Stack Consensus Layer (CL) node rather than locally. The Light CL fetches safe, finalized, and currentL1 views via RPC call, while continuing to execute the local Execution Layer (EL) and maintain unsafe chain progression. Light CL reduces responsibility coupling within the consensus layer by separating derivation from execution and synchronization. Rather than producing safe and finalized blocks locally, kona-node ingests externally derived consensus data, validates it against canonical L1, and injects it into the local engine using well-defined rules that preserve existing OP Stack behavior, including unsafe consolidation and reorganization semantics. @@ -27,9 +27,7 @@ In normal operation, an OP Stack consensus layer (CL) node is responsible for mu This coupling increases complexity, makes failure isolation harder, and prevents certain deployment and interoperability patterns. In particular, it is difficult to operate a CL node that executes and synchronizes L2 state without also deriving L2 state from L1. -Derivation is an expensive process, both computationally and I/O bound, and today each isolated node typically performs this work independently. As OP Stack deployments move toward interoperability scenarios, this cost becomes more pronounced: verification may require additional sanity checks across multiple L2 chains, increasing resource contention and operational overhead. In such environments, it can be desirable to delegate derivation and cross-chain sanity checking to a specialized node and have execution-focused nodes consume the resulting `{safe, finalized, currentL1}` views, rather than re-deriving them locally. - -Light CL addresses this by explicitly removing derivation responsibilities from the node. Safe, finalized, and currentL1 information is sourced from an external CL that performs derivation, while kona-node focuses on validation, execution, and synchronization. +Derivation is an expensive process, both computationally and I/O bound, and today each isolated node typically performs this work independently. As OP Stack deployments move toward interoperability scenarios, this cost becomes more pronounced: verification may require additional sanity checks across multiple L2 chains, increasing resource contention and operational overhead. In such environments, it can be desirable to delegate derivation and cross-chain sanity checking to a specialized node and have execution-focused nodes consume the resulting [`DerivationState`](#derivationstate-contract) views, rather than re-deriving them locally. ## Design Goals @@ -46,6 +44,13 @@ Non-goals include re-deriving or re-verifying derivation correctness locally, or ## Light CL Semantics +### `DerivationState` Contract + +At the core of Light CL is the `DerivationState`(`{safeL2, finalizedL2, currentL1}`), a data structure that replaces the output of the local derivation pipeline. It is defined as: +- [`safeL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#safe-l2-head): `L2BlockInfo` +- [`finalizedL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#finalized-l2-head): `L2BlockInfo` +- [`currentL1`](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/protocol/derivation.md?plain=1#L552): `L1BlockInfo` + ### Responsibilities Dropped When Light CL is enabled, kona-node does not: @@ -53,7 +58,6 @@ When Light CL is enabled, kona-node does not: - Run any L1->L2 derivation pipeline - Emit safe attributes - Schedule derivation stages -- Advance safe or finalized heads based on local derivation ### Responsibilities Retained @@ -68,20 +72,19 @@ In light CL, kona-node continues to: ### Authority and Trust Model - Canonical L1 is the ultimate source of truth. -- External CL data (`{safeL2, finalizedL2, currentL1}`) is assumed to be correctly derived, subject to L1 consistency checks. -- Local unsafe state is authoritative only until overridden by validated external safe data. +- External CL data ([`DerivationState`]()) is assumed to be correctly derived, subject to L1 consistency checks. ### Bidirectional Messaging and Unidirectional Authority -In deployments where a Light CL sequencer follows a normal verifier, there is a bidirectional interaction at the network (or RPC) level. The Light CL sequencer gossips unsafe blocks that the verifier may consume as candidates, while the verifier exposes state(`{safeL2, finalizedL2, currentL1}`) that the Light CL sequencer follows. +In deployments where a Light CL sequencer delegates derivation to a normal verifier, there is a bidirectional interaction at the network (or RPC) level. The Light CL sequencer gossips unsafe blocks that the verifier may consume as candidates, while the verifier exposes [`DerivationState`](#derivationstate-contract) that the Light CL sequencer follows. -Despite this bidirectional messaging, authority remains strictly one-directional. Unsafe blocks are proposal-only and never advance safe state. The verifier safe chain is derived from canonical L1, and the Light CL sequencer safe chain follows the verifier safe chain, not the other way around. +Despite this bidirectional messaging, authority remains strictly unidirectional. Unsafe blocks are proposal-only and never advance safe state. The verifier safe chain is derived from canonical L1, and the Light CL sequencer safe chain follows the verifier safe chain, not the other way around. As a result, this interaction does not introduce circular control dependencies or correctness-level race conditions. -### External Source Contract +### External Source Contract: Derivation Delegation -Light CL requires an external CL endpoint `L2_CL_RPC` exposing the `optimism_syncStatus` RPC API. This API response provides `{safeL2, finalizedL2, currentL1}`. These fields are sufficient to replace local derivation output. No additional APIs are required. +Light CL requires an external CL endpoint `L2_CL_RPC` exposing the `optimism_syncStatus` RPC API. This API response [`syncStatus`](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/protocol/rollup-node.md#syncstatus) provides [`DerivationState`](#derivationstate-contract). These fields are sufficient to replace local derivation output and **delegating derivation** to an external source. No additional APIs are required. The external source is trusted to have performed derivation correctly. The light CL does not check derivation correctness; it only validates consistency with canonical L1. @@ -89,7 +92,7 @@ The external source is trusted to have performed derivation correctly. The light While it is technically possible for a Light CL to follow another Light CL, operators must avoid cycles in the light CL dependency graph. -Circular dependencies in `{safeL2, finalizedL2, currentL1}` authority can lead to undefined behavior and circular trust assumptions. +Circular dependencies in [`DerivationState`](#derivationstate-contract) authority can lead to undefined behavior and circular trust assumptions. Operational guidance: - The light CL dependency graph must be acyclic @@ -179,7 +182,7 @@ To cleanly separate the responsibility, the logic for selecting the finalized ta In normal mode: - Derives `safeL2` as safe attributes through the local L1->L2 derivation pipeline. - Determines `finalizedL2` by monitoring the L1 finalized head. -- Derivation Cursor as `currentL1`. +- Maintains derivation cursor as `currentL1` In light CL mode: - Uses external CL output (`safeL2` and `finalizedL2` provided as `L2BlockInfo`, `currentL1` as `L1BlockInfo`). @@ -200,7 +203,7 @@ The EngineActor: - Light CL mode: external `L2BlockInfo`. During `ConsolidateTask`, In light CL mode: -- Attribute validation is skipped because the input is `L2BlockInfo`. +- Attribute validity is assumed, rather than checked, for the provided `L2BlockInfo`. - If the unsafe chain disagrees with the target, reorg is performed using fork choice. `FinalizeTask` is reused unchanged. From 08a00b35aae0a9b785330c2defd43d680ff072e4 Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Sun, 11 Jan 2026 19:22:30 +0900 Subject: [PATCH 5/6] cleanup --- protocol/kona-node-light-cl.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md index 84e214c5..75e07a6c 100644 --- a/protocol/kona-node-light-cl.md +++ b/protocol/kona-node-light-cl.md @@ -4,9 +4,6 @@ | ------------------ |---------------------------------------| | Author | _@pcw109550_ | | Created at | _2026-01-06_ | -| Initial Reviewers | _@theochap_ | -| Need Approval From | | -| Status | _IN_REVIEW_ | ## Summary From 731d37538915d61102c74a754833c617af7eee1c Mon Sep 17 00:00:00 2001 From: Park Changwan Date: Sun, 11 Jan 2026 19:25:37 +0900 Subject: [PATCH 6/6] cleanup --- protocol/kona-node-light-cl.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/protocol/kona-node-light-cl.md b/protocol/kona-node-light-cl.md index 75e07a6c..189965e8 100644 --- a/protocol/kona-node-light-cl.md +++ b/protocol/kona-node-light-cl.md @@ -41,13 +41,6 @@ Non-goals include re-deriving or re-verifying derivation correctness locally, or ## Light CL Semantics -### `DerivationState` Contract - -At the core of Light CL is the `DerivationState`(`{safeL2, finalizedL2, currentL1}`), a data structure that replaces the output of the local derivation pipeline. It is defined as: -- [`safeL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#safe-l2-head): `L2BlockInfo` -- [`finalizedL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#finalized-l2-head): `L2BlockInfo` -- [`currentL1`](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/protocol/derivation.md?plain=1#L552): `L1BlockInfo` - ### Responsibilities Dropped When Light CL is enabled, kona-node does not: @@ -66,10 +59,17 @@ In light CL, kona-node continues to: - Produce unsafe blocks when operating as a sequencer - Track canonical L1 +### `DerivationState` Contract + +At the core of Light CL is the `DerivationState`(`{safeL2, finalizedL2, currentL1}`), a data structure that replaces the output of the local derivation pipeline. It is defined as: +- [`safeL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#safe-l2-head): `L2BlockInfo` +- [`finalizedL2`](https://github.com/ethereum-optimism/specs/blob/349724453ffa22dd0a5c624d17a27b84602c8192/specs/glossary.md#finalized-l2-head): `L2BlockInfo` +- [`currentL1`](https://github.com/ethereum-optimism/specs/blob/b2397eb45b77f882ccffe74bc03f87cddd3f4e26/specs/protocol/derivation.md?plain=1#L552): `L1BlockInfo` + ### Authority and Trust Model - Canonical L1 is the ultimate source of truth. -- External CL data ([`DerivationState`]()) is assumed to be correctly derived, subject to L1 consistency checks. +- External CL data ([`DerivationState`](#derivationstate-contract)) is assumed to be correctly derived, subject to L1 consistency checks. ### Bidirectional Messaging and Unidirectional Authority