146 lines
6.1 KiB
Markdown
146 lines
6.1 KiB
Markdown
# ECP-0093: `ecp-forge` OP Stack Sepolia testnet and observation consensus rail
|
|
|
|
Status: Draft
|
|
|
|
## Problem / context
|
|
|
|
`every.channel` now has additive Ethereum-compatible commitments and signatures, but it does not yet
|
|
have:
|
|
|
|
- a concrete chain-operator path for bringing up a real OP Stack testnet on `ecp-forge`,
|
|
- a repo-owned bootstrap workflow that matches the current official OP Stack deployment guidance,
|
|
- an application-level consensus surface for "reality-derived" blocks where witnesses attest to the
|
|
same observed broadcast epoch, or
|
|
- a reproducible smoke path that pushes real every.channel archive data through the rail.
|
|
|
|
The current `EveryChannelRail` contract is useful as a compact pointer store, but it does not
|
|
capture the consensus shape requested by the founder: nodes independently discover an observation
|
|
from reality, then witnesses sign off on that shared observation hash.
|
|
|
|
## Decision
|
|
|
|
Adopt a two-part rollout:
|
|
|
|
1. Stand up an OP Stack Sepolia-anchored testnet on `ecp-forge` using the official OP Stack stack:
|
|
`op-deployer`, `op-geth`, `op-node`, `op-batcher`, `op-proposer`, `op-challenger`, and
|
|
optional `op-dispute-mon`.
|
|
2. Introduce an application-level observation consensus rail for every.channel:
|
|
- an `ObservationHeader` is derived from real stream epoch data,
|
|
- witnesses attest to the derived observation hash,
|
|
- the observation is finalized when quorum is reached,
|
|
- full media bytes remain off-chain.
|
|
|
|
This keeps Ethereum as the ordering/finality substrate while making the application-level "block"
|
|
come from reality, not from arbitrary contract writes.
|
|
|
|
## Details
|
|
|
|
### `ecp-forge` OP Stack deployment
|
|
|
|
- Use the official OP Stack deployment topology described in the current Optimism chain-operator
|
|
tutorial:
|
|
- Sepolia L1 contracts via `op-deployer`,
|
|
- `op-geth` + `op-node` sequencer,
|
|
- `op-batcher`,
|
|
- `op-proposer`,
|
|
- `op-challenger`,
|
|
- optional `op-dispute-mon`.
|
|
- Host these components on `ecp-forge` via repo-owned NixOS services and pinned official container
|
|
images.
|
|
- Keep L2 RPC surfaces private by default; expose P2P only as required for testnet participation.
|
|
- Default L1 RPC / beacon endpoints may use public Sepolia providers, but deployment and operation
|
|
require a repo-managed Sepolia private key secret with sufficient ETH.
|
|
- `op-challenger` and `op-dispute-mon` require a repo-managed Cannon absolute prestate artifact.
|
|
If the prestate is absent, the core rollup may still run, but the dispute path is intentionally
|
|
gated off instead of starting with incomplete configuration.
|
|
|
|
### Observation consensus
|
|
|
|
Introduce a new application-level surface alongside `EveryChannelRail`:
|
|
|
|
- `ObservationHeader`
|
|
- `streamHash`
|
|
- `epochHash`
|
|
- `parentObservationHash`
|
|
- `dataRoot`
|
|
- `locatorHash`
|
|
- `observedUnixMs`
|
|
- `sequence`
|
|
- `ObservationHash`
|
|
- `keccak256(abi.encode(ObservationHeader))`
|
|
- `ObservationSlot`
|
|
- `keccak256(abi.encode(streamHash, epochHash))`
|
|
|
|
Witnesses attest to an `ObservationHash`, not directly to arbitrary payloads. This lets the chain
|
|
finalize the winning observation for a `(stream, epoch)` slot without storing the full manifest,
|
|
chunk list, PSIP data, or media bytes.
|
|
|
|
### Witness model
|
|
|
|
For the first testnet tranche:
|
|
|
|
- witness membership is registry-backed,
|
|
- quorum is fixed and explicit,
|
|
- no staking or slashing is required,
|
|
- sending an attestation transaction from a witness address is sufficient "sign off".
|
|
|
|
Off-chain EIP-712 witness signatures may be added later for relayed submission, but they are not a
|
|
prerequisite for the first live testnet.
|
|
|
|
### Real-data validation
|
|
|
|
Use real every.channel archive data already present on `ecp-forge` as the smoke source:
|
|
|
|
- derive observation headers from actual archive JSONL entries,
|
|
- submit them to a local Anvil deployment of the observation ledger,
|
|
- prove quorum/finalization against production-shaped data before attempting Sepolia rollout.
|
|
|
|
## Components
|
|
|
|
- `contracts/EveryChannelRail.sol`
|
|
- compact manifest / transport pointer store (existing rail)
|
|
- `contracts/EveryChannelWitnessRegistry.sol`
|
|
- witness membership for observation consensus
|
|
- `contracts/EveryChannelObservationLedger.sol`
|
|
- candidate observation storage, attestation tracking, and finalization
|
|
- `scripts/op-stack/download-op-deployer.sh`
|
|
- pinned `op-deployer` fetch helper
|
|
- `scripts/op-stack/setup-rollup.sh`
|
|
- repo-owned OP Stack bootstrap/config generation
|
|
- `scripts/op-stack/anvil-reality-smoke.sh`
|
|
- local smoke against Anvil using real `ecp-forge` archive data
|
|
- `nix/modules/ec-op-stack.nix`
|
|
- NixOS service/module surface for `ecp-forge`
|
|
|
|
## Alternatives considered
|
|
|
|
- Use Base Sepolia directly as the only test environment. Rejected because it validates contract
|
|
compatibility, but not operation of an every.channel-owned chain.
|
|
- Wait for a future custom consensus implementation before any chain bring-up. Rejected because it
|
|
delays operator learning and hides infrastructure problems until late.
|
|
- Put media bytes or full manifests on chain. Rejected because it is operationally wasteful and not
|
|
required for observation finalization.
|
|
|
|
## Rollout / teardown plan
|
|
|
|
1. Add the observation-ledger contracts and Foundry tests.
|
|
2. Add Anvil + real-archive smoke scripts.
|
|
3. Add an `ec-op-stack` Nix module and `ecp-forge` integration points.
|
|
4. Wire secrets for a Sepolia deployment key on `ecp-forge`.
|
|
5. Bring up the OP Stack services on `ecp-forge`.
|
|
6. Deploy observation-ledger contracts onto the new chain.
|
|
7. Submit real archive-derived observations and verify finalization.
|
|
|
|
Teardown:
|
|
|
|
- disable `services.every-channel.op-stack`,
|
|
- stop and remove the OP Stack containers/state directories,
|
|
- preserve the local Anvil smoke path and the additive Ethereum rail code.
|
|
|
|
## Open questions
|
|
|
|
- Should `ecp-forge` be the only sequencer for the first tranche, or should a second verifier-only
|
|
peer be provisioned immediately?
|
|
- When we move beyond a registry-backed witness set, do we want bonds, reputation, or both?
|
|
- Should finalized observation slots bridge back into the existing manifest/transport pointer
|
|
contract automatically, or remain a separate ledger surface for the first rollout?
|