2 Federation
Jean edited this page 2026-07-21 14:49:20 +00:00

Federation

Optional. A single node is the usual setup, and most networks never need this. If you run several echo nodes on different servers, they share one account and channel database with no central store, by replicating the event log. Turn it on with [gossip] and [[peer]].

Gossip

Each log entry carries an origin, a per-origin sequence number, and a Lamport clock. Peers connect, exchange version vectors, and send each other the entries the other is missing. A freshly committed entry is also pushed straight away, so a registration propagates in milliseconds. Ingest is idempotent, so re-delivery and reconnection after a split both converge on the same state. The peer link can run over mutually-authenticated TLS.

Global and local scope

Not everything replicates. Every event has a scope, and the match on it is exhaustive, so a new event has to pick a side.

  • Global: account identity. Registration, certificates, passwords, grouped nicks, and the network-wide operator lists. Gossiped to every node.
  • Local: channel state. It stays on the node that owns the channel and never leaves.

The reason is authority. Account identity is meant to be one thing across the whole network. Channel authority is live and local: a node must not be handed ownership of a channel registered on a network it was never part of. A node refuses to ingest any non-global entry a peer sends it, which is the guarantee behind that rule.

Conflict resolution

If two nodes register the same account name before gossip converges, the log still folds to the same owner on every node. Each account records the node that first registered it; the earliest registration wins, with ties broken deterministically. The merge is commutative and idempotent, so delivery order does not matter. When a peer's registration wins a name a local session was using, that node logs the session out, tells the user, and releases any channels the losing account founded, since they cannot transfer to the name's new owner.

Compaction

The log is compacted to one entry per account as it grows, so it does not grow without bound. Local channel state is kept for the owning node's own replay and excluded from what peers pull.

Signing

By default trust is flat: any peer that holds the shared secret can assert any origin. For a network where nodes do not fully trust each other, per-origin Ed25519 signing ([gossip.signing]) lets a node verify that an entry claiming a given origin was really signed by that origin's key. Generate a node's key with echo --gen-gossip-key and list each origin's public key under trust.