Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions docs/ai/acceptance-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,25 @@ RUST_JIT_BUILD=1 cd op-acceptance-tests && mise exec -- just acceptance-test bas

This runs only packages listed in `gates/base.txt`.

### Kona Reproducible Prestate
### Kona Prestate

Some tests (e.g. superfaultproofs, interop fault proofs) require a reproducible kona prestate. This is **not** handled by `build-deps` or `RUST_JIT_BUILD`:
Some tests (e.g. superfaultproofs, interop fault proofs) require a kona prestate. This is **not** handled by `build-deps` or `RUST_JIT_BUILD`. There are two ways to build it:

**Reproducible build** (preferred when Docker is available):

```bash
mise exec -- just reproducible-prestate-kona
```

**Requires Docker.** If Docker is not available in your environment, ask the user to run this command for you.
This produces a prestate whose hash matches CI/release builds. It works on any host with Docker installed.

**Native build** (fallback when Docker is not available):

```bash
cd rust && mise exec -- just build-kona-prestates
```

Only works on **Linux** with the **MIPS cross-compile toolchain** installed. The produced hash will not match release builds, so this is only suitable for local test runs where the hash doesn't need to match a deployed release. If neither Docker nor the MIPS toolchain is available, ask the user to build the prestate for you.

## What `build-deps` Does

Expand Down
1 change: 1 addition & 0 deletions docs/public-docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2324,6 +2324,7 @@
"pages": [
"/op-stack/interop/interop",
"/op-stack/interop/explainer",
"/op-stack/interop/supernode",
"/op-stack/interop/reorg",
"/op-stack/interop/superchain-eth-bridge"
]
Expand Down
1 change: 1 addition & 0 deletions docs/public-docs/op-stack/interop/explainer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,5 @@ The Superchain interop cluster is being rolled out iteratively. To see which cha

* Learn [how messages get from one chain to another chain](/app-developers/guides/interoperability/message-passing).
* Learn how [interop handles reorgs and avoids double-spends](/op-stack/interop/reorg).
* Read about [op-supernode](/op-stack/interop/supernode), the component that derives every chain in the dependency set together and enforces cross-chain safety.
* Read the [cross-chain security measures](/op-stack/security/interop-security) for safe interoperability.
5 changes: 3 additions & 2 deletions docs/public-docs/op-stack/interop/reorg.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ L1 reorgs typically happen at the unsafe head — only the most recent L1 blocks
When an L1 reorg does affect L2, one of two things happens:

* **The replacement L1 block carries the same batch data as the original.** Derivation is deterministic, so the L2 chain it produces is identical, and the reorg is a no-op from the L2 perspective.
* **The replacement L1 block does not carry that batch data.** The sequencer notices and reposts the affected batch in a later L1 block. As long as the batch lands again before the [sequencer window](https://specs.optimism.io/glossary.html#sequencing-window) elapses (3600 L1 blocks ≈ 12 hours on standard chains like OP Mainnet and Base), derivation reproduces the same L2 chain. If the window does elapse without the batch reappearing, the affected L2 blocks are replaced with deposit-only blocks (see [Invalid block](#invalid-block) below).
* **The replacement L1 block does not carry that batch data.** The sequencer notices and reposts the affected batch in a later L1 block. As long as the batch lands again before the [sequencer window](https://specs.optimism.io/glossary.html#sequencing-window) elapses (3600 L1 blocks ≈ 12 hours on standard chains like OP Mainnet and Unichain), derivation reproduces the same L2 chain. If the window does elapse without the batch reappearing, the affected L2 blocks are replaced with deposit-only blocks (see [Invalid block](#invalid-block) below).

The takeaway is that L1 reorgs do not by themselves break interop guarantees: either the data comes back and L2 stays identical, or the chain falls back to deposit-only blocks for that span — the same behavior as if the sequencer had simply gone offline.

Expand Down Expand Up @@ -160,5 +160,6 @@ At worst, some unsafe blocks need to be recalculated (if one fork is chosen over
## Next steps

* Read the [interop explainer](./explainer) for the rest of the architecture.
* Read about [op-supernode](./supernode), the component that derives every chain in the dependency set together and enforces the safety levels described above.
* Read the [cross-chain security measures](/op-stack/security/interop-security) for safe interoperability.
* View more [interop tutorials](/app-developers/tutorials/interoperability/).
* View more [interop guides and tutorials](/app-developers/guides/interoperability/get-started).
160 changes: 160 additions & 0 deletions docs/public-docs/op-stack/interop/supernode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
title: OP Supernode
description: Learn how op-supernode runs every chain in an interop dependency set inside one process.
audit-source:
- op-supernode/cmd/main.go
- op-supernode/supernode/supernode.go
- op-supernode/supernode/chain_container/chain_container.go
- op-supernode/supernode/activity/interop/interop.go
- op-supernode/README.md
- op-supernode/safety-labels.md
---

<Info>
OP Stack interop is in active development.
op-supernode is the runtime that operators of interop chains will run, and the architecture and interfaces described here may continue to evolve as the rollout progresses.
</Info>

# OP Supernode

*op-supernode* is a component that runs every chain in an interop dependency set together as virtual nodes inside one binary.
Where a pre-interop deployment runs one op-node per chain, op-supernode hosts every chain side by side, shares the L1 and beacon-chain plumbing across them, and adds the cross-chain message verification work that interop needs.

## Why op-supernode exists

OP Stack interop changes what a single node has to do.
Before interop, a node only had to derive its own chain.
With interop, a node has to derive *every chain in its dependency set*, because any of those chains can emit an initiating message that the local chain depends on.
The local chain cannot advance past a block whose dependencies it cannot prove, so the derivation of every other chain in the set is on the critical path.

Without consolidation, every operator runs a full op-node and execution client for every chain in the dependency set.
That duplicates the L1 client, the beacon-chain client, the derivation pipeline, the storage layout, and the operational glue around each one.
For a fully-connected dependency set — the configuration the [Superchain interop cluster](/op-stack/interop/explainer#superchain-interop-cluster) targets — the duplication scales with the size of the cluster.

op-supernode collapses that duplication.
It runs each chain as an in-memory *virtual node* inside one process, with a single L1 client and a single beacon client serving all of them, and adds the cross-chain message verification work above the per-chain layer.

## How op-supernode works

The supernode is composed of *chain containers* and *activities*.
Each chain container hosts one virtual node for one chain.
Activities are modular components that operate above the chain layer, with access to every chain.

<img src="/public/img/op-stack/interop/supernode-architecture.png" alt="An op-supernode hosts two chain containers (Chain A and Chain B), each containing a Virtual Node and Engine Controller. The Engine Controllers drive external Execution Clients. A shared Interop Verification Activity and L1 Client sit alongside the chain containers." width="600" />

### Chain containers

A *chain container* is the supernode's wrapper around one chain.
Inside a chain container is a *virtual node*: a consensus-layer (CL) implementation hosted in-process rather than as a separate operating-system process.
Today the only virtual node implementation is op-node itself, hosted as a library; the chain container manages its lifecycle (start, stop, pause, resume) and exposes a stable interface to the rest of the supernode.

Chain containers also drive the execution engine for the chain through an engine controller.
They expose the operations the supernode needs to verify cross-chain messages — deriving the local-safe block at a timestamp, fetching receipts, answering output-root queries — without reaching into the internals of any one chain.

### Shared resources

Running every chain inside one process makes shared resources possible.

* A single **L1 RPC client** and a single **L1 beacon client** serve every chain. Cache hits on L1 blocks and blob lookups carry across chains.
* The **JSON-RPC surface** is namespaced per chain. `11155420/` reaches OP Sepolia's RPC; `1301/` reaches Unichain Sepolia's. Tools that expect an op-node-shaped endpoint reach a chain by addressing it through that prefix.
* **Metrics** are namespaced per chain via the same scheme.
* **Data directories** are namespaced so SafeDB and P2P state for one chain cannot collide with another's.

Some flags are intentionally owned at the supernode level rather than per chain.
`--l1` and `--l1.beacon` configure the shared L1 plumbing, and any per-chain override of them is silently replaced with the top-level value.

### Activities

An *activity* is a modular component that operates above the chain layer rather than inside any one chain.
Each activity can register an RPC namespace on the supernode root, expose Prometheus metrics, and run a goroutine for as long as the supernode is up.

The supernode ships with a small set of activities:

* **Heartbeat** — emits a liveness signal and exposes `heartbeat_check` over JSON-RPC.
* **SuperRoot** — produces a *super root*: a commitment over verified L2 blocks across the dependency set at a given timestamp. Exposed as `superroot_atTimestamp`. The fault proof system needs this commitment to produce an interop-aware proof.
* **Supernode** — exposes `supernode_syncStatus`, an aggregate per-chain sync status across the dependency set.
* **Interop** — does the actual cross-chain message verification (see the next section).

## Cross-chain message safety

The interop activity is the part of op-supernode that decides when a chain's blocks have satisfied their cross-chain dependencies and can be promoted past unsafe.
It runs above the chain containers and reaches into them through a narrow interface.

For every block produced on every chain, the interop activity answers one question: have all the initiating messages this block executes been reproduced from L1, and at the same safety level the destination block is trying to reach?
The activity decides per round between *wait*, *advance*, *invalidate*, and *rewind*.
The decision is recorded in a write-ahead log so the supernode can pick up after a restart in the same state it was in before.

When the answer is *advance*, the supernode signals the chain's CL to promote the block.
The signal flows through an *authority* interface that the chain container holds and the virtual node defers to: the supernode advances safety on a chain only via the chain's own CL.
The CL stays the single source of truth for safety on its chain, and the execution layer (EL) never has to learn about interop.

When the answer is *invalidate* or *rewind*, the supernode tells the chain to back out the affected blocks.
A block on chain B that referenced a chain-A log can be invalidated because the chain-A log never made it to L1, or because the L1 record contradicts what was gossiped over P2P.
See [Interop reorg awareness](/op-stack/interop/reorg) for how that plays out at the chain level.

The user-facing safety levels do not change.
Block safety levels (*unsafe*, *safe*, *finalized*) are still defined as they are without interop, and the EL's view of those labels matches.
The supernode's role is to make sure the labels mean what they say once cross-chain dependencies are part of the picture.

## op-supernode and Light CL

op-supernode pairs with the *Light CL* mode of op-node and kona-node.
A Light CL turns off local derivation and mirrors safe and finalized state from a trusted external source over the `optimism_syncStatus` RPC.
It still advances the unsafe chain over P2P; only the safe and finalized views are delegated.

Together, supernode and Light CL form a topology:

* One trusted op-supernode (or a small high-availability pool of them) runs derivation for every chain in the dependency set, plus the interop activity that promotes blocks to safe.
* The rest of the operator's fleet runs op-node or kona-node in Light CL mode, points at the supernode's `optimism_syncStatus`, and inherits its safe and finalized view.
* Node operators run the same setup, minus the sequencer Light CLs (only the chain operator produces blocks).

This split is what makes interop tractable for operators who already run dozens or hundreds of nodes per chain.
The expensive multi-chain derivation work happens once, on the supernode; the rest of the fleet stays cheap.

```mermaid
graph LR
classDef supernode fill:#FFE
classDef transparent fill:none, stroke:none

SnA[Supernode-A]
SnB[Supernode-B]
SnC[Supernode-C]

Px0["Proxy CL<br/>Chain-0"]
Px1["Proxy CL<br/>Chain-1"]

subgraph c0["Chain-0 Light CL fleet"]
direction TB
C0Seq["Sequencer<br/>0..N"]
C0Rep["Replica<br/>0..N"]
end

subgraph c1["Chain-1 Light CL fleet"]
direction TB
C1Seq["Sequencer<br/>0..N"]
C1Rep["Replica<br/>0..N"]
end

SnA --> Px0
SnA --> Px1
SnB --> Px0
SnB --> Px1
SnC --> Px0
SnC --> Px1

Px0 --> C0Seq
Px0 --> C0Rep
Px1 --> C1Seq
Px1 --> C1Rep

class SnA,SnB,SnC supernode
class c0,c1 transparent
```

## Where to go next

* Read the [interop explainer](/op-stack/interop/explainer) for how cross-chain messaging works at the protocol level.
* Read [interop reorg awareness](/op-stack/interop/reorg) for how the safety model handles equivocation and L1 reorgs.
* Read the [cross-chain security measures](/op-stack/security/interop-security) for how an operator can configure the safety level it requires for inbound messages.
* Read the [specialized op-node topology notice](/notices/specialized-node-topology) for the operator-facing pattern of running light op-nodes with `--l2.follow.source`, the fleet-side of the supernode-plus-light-CL topology.
* For implementation detail, see the [op-supernode source](https://github.com/ethereum-optimism/optimism/tree/develop/op-supernode) in the monorepo.
37 changes: 31 additions & 6 deletions docs/public-docs/op-stack/reference/glossary.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ reality the block time is variable as some time slots might be skipped. Pre-merg

### Delegation

Refers to the process of assigning the voting power of your tokens to a designated community member, known as a delegate.
Delegates are individuals who have volunteered to actively participate in the governance of the Optimism Token House.
By delegating your voting power, you enable these delegates to vote on governance matters on your behalf, while you retain full ownership of your tokens and the freedom to use them as you wish.
Refers to the process of assigning the voting power of your tokens to a designated community member, known as a delegate.
Delegates are individuals who have volunteered to actively participate in the governance of the Optimism Token House.
By delegating your voting power, you enable these delegates to vote on governance matters on your behalf, while you retain full ownership of your tokens and the freedom to use them as you wish.
You can also change your chosen delegate at any time, allowing for flexibility in how your voting power is represented in the governance process.

### EOA or externally owned account
Expand All @@ -53,8 +53,8 @@ at the request of the L1 consensus layer. On L2, the executed blocks are freshly

### Optimism collective

The Optimism Collective is a band of people, projects, and companies working together to build a better economy for everyone,
united by a mutually beneficial pact to adhere to the axiom of impact=profit — the principle that positive impact to the collective should be rewarded with profit to the individual.
The Optimism Collective is a band of people, projects, and companies working together to build a better economy for everyone,
united by a mutually beneficial pact to adhere to the axiom of impact=profit — the principle that positive impact to the collective should be rewarded with profit to the individual.
New model of digital democratic governance optimized to drive rapid and sustained growth of a decentralized ecosystem.


Expand Down Expand Up @@ -269,7 +269,7 @@ It also submits [output roots](#l2-output-root) to L1.

Range of L1 blocks from which a [sequencing epoch](#sequencing-epoch) can be derived.
A sequencing window whose first L1 block has number `N` contains [batcher transactions](#batcher-transaction) for epoch
`N`. The window contains blocks `(N, N + SWS)` where `SWS` is the sequencer window size.
`N`. The window contains blocks `(N, N + SWS)` where `SWS` is the sequencer window size.
The current default `SWS` is 3600 epochs.
Additionally, the first block in the window defines the [depositing transactions](#depositing-transaction) which determine the
[deposits](#deposit) to be included in the first L2 block of the epoch.
Expand All @@ -284,6 +284,31 @@ sequencing window. Epochs can have variable size, subject to some constraints.

The network of OP Stack chains connected by native interoperability. Not yet live. Chains that are part of the OP Stack ecosystem share security and a common development stack (the OP Stack). The interop cluster specifically refers to the subset of chains connected by the OP Stack interoperability layer.

### Dependency set

The set of chains that a given chain accepts initiating messages from. A chain's local block cannot become safe until every initiating message it depends on has also been derived from L1. The *transitive* dependency set extends this to the dependencies of those chains, and so on. The [OP Stack interop cluster](#op-stack-interop-cluster) is configured as a fully-connected dependency set: every chain in the set has every other chain in its dependency set.

### Supernode

A component that runs the consensus layer of every chain in a [dependency set](#dependency-set) together as in-memory [virtual nodes](#virtual-node) inside one binary. The supernode shares the L1 client, L1 beacon client, JSON-RPC surface, and metrics across chains, and verifies that every cross-chain message a chain depends on has been reproduced from L1 before promoting blocks to "safe". It connects to an execution client for each chain using the engine API. Often referred to as `op-supernode` after the binary name. See the [supernode explainer](/op-stack/interop/supernode) for the architecture.

### Chain container

The [supernode](#supernode)'s wrapper around a single chain. A chain container hosts one [virtual node](#virtual-node), drives that chain's execution engine via an engine controller, and exposes a stable interface the rest of the supernode uses to derive blocks, fetch receipts, and answer output-root queries.

### Virtual node

A consensus-layer node hosted in-process inside a [supernode](#supernode), rather than as a separate operating-system process. Today the only virtual node implementation is op-node itself, hosted as a library.

### Super root

A commitment over verified L2 blocks across a [dependency set](#dependency-set) at a given timestamp. Produced by the supernode's `superroot_atTimestamp` RPC and consumed by the fault proof system as the input it needs to generate an interop-aware proof.

### Light CL

A mode of operation for the consensus layer (op-node or kona-node) that turns off local L1-to-L2 derivation and mirrors safe and finalized state from a trusted external source over the `optimism_syncStatus` RPC. A light CL still advances the unsafe chain over P2P. Pairs with a [supernode](#supernode) acting as the safe source for a fleet of light CLs.
Learn more at the [Light Node Topology Notice Page](0xE69104DD872222E1Bd7C1adD47588F8C62ed64C0).

### Shared L1 Bridge

The L1 bridge contracts which govern all OP Chains in the OP Stack ecosystem. This bridge can be upgraded by the Optimism Collective.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading