# ECP-0104: `ecp-forge` dual Ethereum full nodes on dedicated NVMe ZFS ## Why `every.channel` now has OP Stack and Ethereum contract rails on `ecp-forge`, but it still depends on public L1 RPC and beacon providers for Ethereum itself. The forge host has enough raw capacity in `tank`, but `tank` is a large HDD `raidz3` pool that is well suited for archive bytes, not for the random-read/write pattern of concurrent Ethereum execution and consensus sync. The same host also has a free 7 TB NVMe device, which is the right media class for a self-hosted node. ## Decision 1. Create a dedicated single-device ZFS pool for Ethereum on the free NVMe in `ecp-forge`. 2. Run two full-sync Ethereum node pairs on that pool: - Ethereum mainnet - Ethereum Sepolia 3. Use Reth for execution and Lighthouse for consensus. 4. Keep raw execution and beacon RPC local-only on `ecp-forge` for the first tranche. 5. Publish sync and finality status on `https://eth.every.channel`. 6. Because this tranche is explicitly full-sync from genesis, run Lighthouse with `--allow-insecure-genesis-sync` instead of checkpoint bootstrap. ## Consequences - `every.channel` gets repo-owned L1 execution and consensus rails for both mainnet and Sepolia. - Ethereum state no longer competes with `tank` archive I/O. - The first public surface is intentionally conservative: health and sync visibility, not unauthenticated public JSON-RPC. - The dedicated Ethereum pool is single-device NVMe, so it optimizes for node performance rather than storage redundancy. - Consensus sync starts from genesis without checkpoint assistance, which is slower but matches the requested full-sync posture. ## Rejected Alternatives - Put Ethereum state on `tank`: rejected because the HDD `raidz3` pool is the wrong latency profile for concurrent execution and consensus sync. - Keep using only public upstream Ethereum providers: rejected because the OP Stack and settlement rails should not depend on third-party RPC availability. - Expose raw JSON-RPC on `eth.every.channel` immediately: rejected for the first tranche because it creates an unauthenticated public abuse surface before auth and rate policy exists. - Use checkpoint sync for Lighthouse: rejected for this tranche because the requested posture is full sync from genesis on both networks.