every.channel/evolution/proposals/ECP-0093-ecp-forge-op-stack-sepolia-observation-testnet.md

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?