every.channel/evolution/proposals/ECP-0092-ethereum-rails-and-private-settlement.md

158 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ECP-0092: Ethereum rails and private settlement for every.channel
Status: Draft
## Problem / context
`every.channel` already has useful anti-junk and manifest integrity primitives, but they stop at
repo-local formats: custom Merkle trees, JSON body hashes, and Ed25519 signatures. That is enough
for local validation, not for the broader direction now requested:
- stream identity, broadcast de-duplication, manifests, and transport announcements should all have
Ethereum-compatible representations,
- private-chain settlement should reuse existing Ethereum tooling instead of inventing a custom
ledger,
- iroh should remain the transport substrate,
- storage on chain must stay compact, and
- `ecp-forge` should become the high-bandwidth head node for sequencing, archival, and bootstrap.
This supersedes the specific ECP-0022 alternative that rejected “global consensus / blockchain for
manifests” as overkill. The new direction is not a public general-purpose chain. It is a private,
Ethereum-compatible settlement rail for every.channel commitments.
## Decision
Adopt a dual-plane architecture:
- `iroh` remains the transport, discovery, and media movement layer.
- Local protocol integrity remains first-class:
- `manifest_id` stays BLAKE3 over the manifest body,
- object membership proofs stay `merkle+blake3`,
- Ed25519 manifest signatures remain supported.
- Ethereum-compatible commitments become an additive settlement/mirroring layer for stream
identity, transport announcements, and manifests.
- Ethereum-native signatures are added alongside local signatures:
- manifests may carry secp256k1 EIP-712 signatures over `ManifestBody`,
- no existing local signature path is removed as part of this proposal.
- On-chain state remains compact:
- manifests store only stream/epoch ids plus commitment hashes,
- control announcements store only stream ids plus announcement commitments,
- full media bytes, manifests, PSIP tables, and chunk inventories remain off-chain.
- The chain is private and purpose-built for every.channel use cases:
- no arbitrary application compute in the near term,
- no fraud-proof system in the near term,
- permissionless submission as far as operationally possible,
- pseudonymous participation preferred over account-heavy identity.
## Details
### Canonical Ethereum representations
Introduce Solidity-compatible struct mirrors for the protocol surfaces we actually ship:
- `BroadcastId`
- `SourceId`
- `StreamKey`
- `StreamDescriptor`
- `StreamControlAnnouncement`
- `ChunkId`
- `ManifestVariant`
- `ManifestBody`
- `ManifestSignature`
- `Manifest`
These are encoded via Solidity ABI rules and hashed with `keccak256`. They mirror the shipped
protocol types; they do not replace the local wire format or local hashing rules.
### Manifest commitments
Publisher-generated manifests may carry a set of Ethereum commitments as first-class fields:
- `manifest-data-merkle-keccak256-v1`
- Keccak Merkle root over ordered chunk hashes, or over ordered variant roots for multi-variant
manifests.
- `manifest-body-abi-keccak256-v1`
- `keccak256(abi.encode(EthManifestBody))`
- `manifest-envelope-abi-keccak256-v1`
- `keccak256(abi.encode(EthManifest))`
`manifest_id` and `merkle_root` remain the local BLAKE3-backed protocol fields. Ethereum
commitments are explicit, separately named, and never inferred from those local field names alone.
### Signature rails
Manifest signatures become dual-rail:
- local signatures continue to sign the local BLAKE3 `manifest_id` with Ed25519,
- Ethereum-native signatures sign the typed `EthManifestBody` with secp256k1 EIP-712,
- both signature families may appear on the same manifest.
The Ethereum signature target is `ManifestBody`, not the full manifest envelope, so signatures do
not become self-referential when more signatures are appended.
### Stream and control commitments
Stream descriptors and control announcements may also carry Ethereum-compatible commitments:
- `stream-id-keccak256-v1`
- `stream-descriptor-abi-keccak256-v1`
- `control-announcement-abi-keccak256-v1`
This ties broadcast-scoped discovery identity to the same settlement vocabulary used by manifests
without forcing transport-time consumers to abandon the local vocabulary they already use.
### Solidity rail contract
Add a minimal contract that stores only the latest compact pointers:
- latest manifest pointer per `stream_id + epoch_id`
- latest transport announcement pointer per `stream_id`
- event emissions for historical indexing
The contract must stay event-heavy and storage-light. Full manifests stay in iroh / relay / archive
storage.
### `ecp-forge` role
`ecp-forge` becomes the maximal head node for this network:
- private-chain bootstrap and packaging,
- archival indexer for settlement events,
- high-bandwidth manifest and control announcer,
- optional sequencer / execution-client host for the private network.
This role is operational, not constitutional. Other nodes must still be able to validate, mirror,
and submit commitments without going through a closed control plane.
## Alternatives considered
- Keep custom BLAKE3-only manifests forever. Rejected because it strands every.channel outside the
tooling and audit surface of the Ethereum ecosystem.
- Replace BLAKE3 and Ed25519 immediately. Rejected because it weakens the local protocols existing
integrity path before the private rail is operational and discards useful cryptographic
properties for no near-term operational win.
- Build a custom blockchain. Rejected because existing Rust + Solidity stacks are already good
enough and reduce implementation risk.
- Use public Ethereum mainnet / arbitrary public L2s directly. Rejected for now because cost,
privacy, and operational control do not fit the current network shape.
## Rollout / teardown plan
1. Add `ec-eth` with canonical Solidity-compatible representations and Keccak commitments.
2. Preserve the local BLAKE3/Ed25519 rail as the default transport integrity path.
3. Add optional secp256k1 EIP-712 manifest-body signatures alongside Ed25519 signatures.
4. Add the minimal Solidity rail contract for compact settlement pointers.
5. Teach publishers/indexers to mirror manifests and announcements onto the private chain.
6. Stand up the private Ethereum-compatible network on `ecp-forge` and companion nodes.
Teardown:
- back out the Ethereum rail changes explicitly in code; the preserved local rail remains as the
fallback integrity path.
## Open questions
- Which execution stack should back the private network first: a slim Reth-based node, or a more
minimal Rust EVM deployment?
- When the private rail becomes live, do we require both signature families for publisher policy, or
is one valid rail-specific signature enough for a given transport or settlement action?