ReceiptChains, re-implemented from WAI jwp-receipts §3 step 3 as amended: - NEW 7: admit verifies each group's key, signature and label first (ReceiptVerifier::verify_group, any key); a forged group is Unverified and never held, admitted or anchored, joined or re-anchored. - NEW 1: each anchor leaves a gap; a group inside it linking to either end is history, so an ascending FETCH after a re-anchor and a joiner's ascending fill are admitted (the review's two sequences, as tests). - NEW 2: held groups indexed by link and by parent; offered again only when a group they link to is admitted; each signature verified once; a history count per chain and a total across chains beside the live count; Chain.links capped at CHAIN_HELD_LINKS (65 536, as WAI's reference). Tests count held groups, verifications and re-offers, not time. - OPEN 1: for_moq refuses a count above MAX_HELD_GROUPS; HoldBound::from_json refuses a statement without counts; admit_on and ObjectReceipt::check_moqt refuse a receipt off its track, group or object (MoqtMismatch) unheld. tests/staged_moq_trace.rs drops its pending queue: each subscriber's chains are for_moq under its stated bound; the joiner subscribes at its join and anchors; the lossy subscriber's lost receipt is recovered by re-anchoring, its layers refused; when each receipt is verified or refused, and each status's evidence, are the trace's. Co-Authored-By: Claude Opus 5.5 <[email protected]>
98 lines
4.1 KiB
Rust
98 lines
4.1 KiB
Rust
//! **joule-moq** — MoQT (Media over QUIC Transport) wire protocol + JWP receipt
|
|
//! extension for the CommunicationOS broadcast surface.
|
|
//!
|
|
//! MoQT is the IETF-track pub/sub transport for live and broadcast media over
|
|
//! QUIC. Tracks fan out through relays to subscribers; objects within a track
|
|
//! are independently addressable, cacheable, and replayable. This crate
|
|
//! delivers the wire protocol *plus* a first-class JWP receipt extension so
|
|
//! every object carries verifiable provenance, joule cost, and (optionally)
|
|
//! MLS-wrapped end-to-end ciphertext.
|
|
//!
|
|
//! ## What this crate ships
|
|
//!
|
|
//! - Wire codec for the MoQT control + data planes ([`wire`], [`messages`])
|
|
//! - Track / Group / Object identifiers and metadata ([`track`])
|
|
//! - Session state machine for publisher / subscriber / relay roles ([`session`])
|
|
//! - Endpoint trait surface ([`endpoint`])
|
|
//! - **JWP receipt extension** — batched per-group signing with Merkle inclusion
|
|
//! proofs per object, identity-bound publication, joule attribution ([`receipt`])
|
|
//! - In-memory mock for testing without QUIC ([`mock`]), whose relay also forwards
|
|
//! staged tracks on a caller-driven clock: per-hop delivery timeouts, capping by
|
|
//! subscription, and the receipts of dropped objects forwarded all the same
|
|
//! - Staged tracks, one per layer of a WAI stage set ([`staged`]), and receipt chains
|
|
//! kept per publisher key and track ([`ReceiptChains`])
|
|
//!
|
|
//! ## What this crate intentionally does not ship (yet)
|
|
//!
|
|
//! - A production QUIC implementation (gated behind the `quic` feature; v0.1
|
|
//! exposes the trait surface only).
|
|
//! - Browser-native subscriber (will be a separate WASM crate).
|
|
//! - The relay binary (`joule-moq-relay`) and publisher SDK (`joule-moq-publisher`)
|
|
//! live in their own crates and depend on this one.
|
|
//!
|
|
//! ## Standards alignment
|
|
//!
|
|
//! Targets `draft-ietf-moq-transport` (working group draft, evolving). Wire
|
|
//! constants and message types are versioned per the draft revision implemented
|
|
//! by [`MOQT_DRAFT_VERSION`]. The JWP receipt extension is a non-normative
|
|
//! addition we plan to submit as `draft-charlot-moq-jwp-extensions`.
|
|
//!
|
|
//! ## Receipt-first design
|
|
//!
|
|
//! Every endpoint role in this crate produces or consumes JWP-signed receipts
|
|
//! by construction. There is no "raw" object path that bypasses receipt
|
|
//! generation.
|
|
|
|
pub mod endpoint;
|
|
pub mod error;
|
|
pub mod messages;
|
|
pub mod mock;
|
|
pub mod receipt;
|
|
pub mod session;
|
|
pub mod staged;
|
|
pub mod track;
|
|
pub mod wai_dispatch;
|
|
pub mod wire;
|
|
|
|
#[cfg(feature = "quic")]
|
|
pub mod transport_quic;
|
|
|
|
pub use endpoint::{
|
|
MoqEndpoint, Publisher, Relay, Subscriber, SubscriptionHandle,
|
|
};
|
|
pub use error::{MoqError, MoqResult};
|
|
pub use messages::{
|
|
AnnounceMessage, ControlMessage, ObjectHeader, SetupMessage,
|
|
SubscribeMessage, SubscribeOk,
|
|
};
|
|
pub use receipt::{
|
|
compose_group_class, Admission, Anchoring, BoundRefused, ChainEvent, ChainRefusal, GroupReceipt, HoldBound, ObjectReceipt,
|
|
ReceiptChains, ReceiptVerifier, ReceiptBuilder, ReceiptsTrack, MerkleProof, VerifiedGroup, CHAIN_HELD_LINKS, CHAIN_OPEN_GAPS,
|
|
MAX_HELD_GROUPS,
|
|
};
|
|
pub use session::{MoqSession, SessionRole, SessionState};
|
|
pub use track::{
|
|
GroupId, ObjectId, ObjectStatus, Track, TrackAlias, TrackName,
|
|
TrackNamespace,
|
|
};
|
|
pub use wai_dispatch::{
|
|
is_known_capability, is_mandatory_floor, is_neural, payload_has_wai_envelope,
|
|
KNOWN_CAPABILITIES, WAI1_MAGIC, WAI2_MAGIC,
|
|
};
|
|
pub use wire::{decode_varint, encode_varint, WireCodec};
|
|
|
|
/// MoQT draft revision targeted by this crate.
|
|
///
|
|
/// The IETF MoQ working group is iterating; bumping this constant signals
|
|
/// a wire-incompatible version of the protocol.
|
|
pub const MOQT_DRAFT_VERSION: u32 = 0xff00_0008; // matches draft-08-style version
|
|
|
|
/// JWP receipt extension version.
|
|
///
|
|
/// Independent of the MoQT draft version. Bumped when the receipt header
|
|
/// schema changes. 2: the labelled object leaf and the labelled group payload
|
|
/// (optional members; a receipt without them keeps its bytes).
|
|
pub const JWP_MOQ_EXTENSION_VERSION: u8 = 2;
|
|
|
|
/// Crate version, exposed for receipt-emitting tooling.
|
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|