Expand description
The sync session wire protocol (phase D, #406).
One symmetric protocol for device↔device and device↔server: both peers send Frame::Hello
naming the account and every account-log entry hash they already hold, then each streams the
entries the other lacks as Frame::Entries pages, ending with Frame::Done. The receiver
feeds every entry through the op-log ingest seam, which re-verifies signature, canonicity, and
chain continuity from scratch — the sender is never trusted, so a malformed or forged frame is
rejected exactly as a malformed local write would be.
Frames are canonical CBOR arrays tagged by a leading discriminant, encoded by hand with
minicbor::Encoder to match the op-log’s envelope style (no derive). The byte layout is a
frozen wire — a golden-vector test pins it.
Enums§
- Frame
- One protocol frame. The discriminant is the second array element (after the domain tag).
- Wire
Error - A frame that failed to decode. Kept distinct from an I/O error so the session can treat a protocol violation (drop the peer) differently from a transport hiccup.
Constants§
- MAX_
AUTH_ BINDING_ BYTES - The maximum bytes an
Frame::Authbinding carries. A node binding is a small fixed shape (~224 bytes: domain + three 32-byte keys + a timestamp + a 64-byte signature); this is a decode-time sanity bound on that field. The actual PRE-ALLOCATION bound for an unauthenticated peer is the auth phase’s frame-level cap, enforced from the length prefix before the body is allocated (auth::MAX_AUTH_FRAME_BYTESviacodec::read_frame_within) — not this, which is checked only after the frame is read. - MAX_
ENTRIES_ PER_ PAGE - The maximum entries a single
Frame::Entriespage carries — a hard cap so one frame can never force an unbounded allocation on the receiver (#406: bounded frames, no amplification). - MAX_
HELLO_ HASHES - The maximum entry hashes a single
Frame::Helloinventory carries. Bounds the hello frame so a peer cannot force an unbounded allocation before any authentication. A sender with more entries than this advertises a bounded subset — still correct (the peer’s extra sends are idempotently re-ingested), just less efficient; seesession::bounded_inventory. For the accounts D targets the cap is never reached. - SYNC_
ALPN - The ALPN this protocol speaks. Versioned: a breaking wire change bumps the suffix so an old peer
declines the handshake instead of misreading frames. Bumped to
/2for the #881 auth phase (theAuthframe exchanged before any inventory) — a/1peer, which would stream its inventory without authenticating, must not interoperate.