# OP Stack on `ecp-forge` This runbook covers the repo-owned OP Stack testnet surface introduced by [ECP-0093](/Users/conradev/Projects/every.channel/evolution/proposals/ECP-0093-ecp-forge-op-stack-sepolia-observation-testnet.md). ## Scope - `ecp-forge` runs the every.channel OP Stack services with pinned official container images. - The chain is Sepolia-anchored and private by default on the RPC side. - Application-level consensus lives in the observation rail: - [EveryChannelWitnessRegistry.sol](/Users/conradev/Projects/every.channel/contracts/EveryChannelWitnessRegistry.sol) - [EveryChannelObservationLedger.sol](/Users/conradev/Projects/every.channel/contracts/EveryChannelObservationLedger.sol) ## Required inputs - `secrets/op-stack-sepolia-private-key.age` - Sepolia operator key for `op-deployer`, `op-node`, `op-batcher`, and `op-proposer`. - `secrets/op-stack-challenger-prestate.bin.gz.age` - Cannon absolute prestate artifact for `op-challenger`. If the private key secret is absent, `services.every-channel.op-stack.enable = false` on `ecp-forge`. If the prestate artifact is absent, `op-challenger` and `op-dispute-mon` stay disabled even when the core rollup services are enabled. ## Local validation Contracts: ```sh nix shell .#foundry .#solc -c forge test -vv ``` Real archive data through Anvil: ```sh nix shell .#foundry .#solc nixpkgs#jq nixpkgs#openssh nixpkgs#curl -c ./scripts/op-stack/anvil-reality-smoke.sh ``` The smoke script: - deploys the witness registry and observation ledger to Anvil, - reads a real archive JSONL entry from `root@git.every.channel`, - derives `stream_hash`, `epoch_hash`, `locator_hash`, and `observation_hash`, - finalizes the observation with two Anvil witnesses. Default remote source: - `/var/lib/every-channel/manifests/la-cbs/video0.m4s.jsonl` Output artifact: - `test-results/anvil-reality-smoke.json` ## Deploy ```sh ./scripts/deploy-ecp-forge.sh ``` The host bootstrap service is: - `every-channel-op-stack-bootstrap.service` It writes runtime state under: - `/var/lib/every-channel/op-stack` Key generated artifacts: - `/var/lib/every-channel/op-stack/deployment.json` - `/var/lib/every-channel/op-stack/sequencer/genesis.json` - `/var/lib/every-channel/op-stack/sequencer/rollup.json` ## Verify Core services: ```sh ssh -o BatchMode=yes -o IdentityAgent=none -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 root@git.every.channel \ 'systemctl is-active every-channel-op-stack-bootstrap podman-every-channel-op-geth podman-every-channel-op-node podman-every-channel-op-batcher podman-every-channel-op-proposer' ``` Full stack including challenger/dispute monitor: ```sh ssh -o BatchMode=yes -o IdentityAgent=none -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 root@git.every.channel \ 'systemctl is-active podman-every-channel-op-challenger podman-every-channel-op-dispute-mon' ``` Bootstrap outputs: ```sh ssh -o BatchMode=yes -o IdentityAgent=none -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 root@git.every.channel \ 'jq . /var/lib/every-channel/op-stack/deployment.json' ``` ## Contract deployment on the rollup Once the rollup RPC is live, deploy the observation rail to the L2 RPC: ```sh EVERY_CHANNEL_RPC_URL=http://127.0.0.1:8545 \ EVERY_CHANNEL_PRIVATE_KEY_FILE=/path/to/private-key \ ./scripts/op-stack/deploy-observation-ledger.sh ``` ## Notes - `op-geth` and `op-node` RPC surfaces bind to `127.0.0.1` on `ecp-forge`. - The public firewall opening is only for the `op-node` P2P port. - The bootstrap uses `op-deployer/v0.6.0-rc.3` by default and official OP Labs container images.