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

6.7 KiB
Raw Blame History

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?