feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled

Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
2026-08-13 18:34:25 +08:00
parent 61c3fa1df9
commit 9dfa06ffee
3785 changed files with 1085458 additions and 2 deletions
+274
View File
@@ -0,0 +1,274 @@
//! The mesh wire contract — FROZEN surface.
//!
//! Every byte that crosses the mesh is one of the frames in this module,
//! postcard-encoded behind a one-byte protocol version. This file is the
//! contract between all mesh lanes: transport (endpoint/peer), membership
//! (gossip/registry), the session directory, and the media fan-out all build
//! against these types. **Changes here require a post in the mesh thread
//! before the edit** — two lanes compiling against different frame layouts is
//! the failure mode this file exists to prevent.
//!
//! ## The fencing law (non-negotiable)
//!
//! Every session-bearing frame carries the fenced tuple
//! [`FencedHeader`] `{session_id, generation, owner_runtime_id}`. Receivers
//! MUST reject frames whose generation is stale for that session, at every
//! hop. Mesh membership is a hint; the fenced generation (Redis CAS lease)
//! is the arbiter. The mesh may say "don't dial" — it may never say "take
//! over."
//!
//! ## Framing
//!
//! - **Datagrams** (realtime-media): one [`MeshDatagram`] per QUIC datagram,
//! postcard-encoded, no length prefix (the datagram boundary is the frame
//! boundary). Senders MUST check the encoded size against the connection's
//! `max_datagram_size()` and fail loud, never truncate.
//! - **Bi-streams** (reliable-stream + gossip control): length-delimited
//! postcard. Each frame is a u32-LE length followed by that many bytes of
//! postcard-encoded [`MeshStreamFrame`]. Max frame size: [`MAX_STREAM_FRAME`].
//! The first frame on any stream MUST be `Hello`; a non-`Hello` first frame
//! is a protocol error and the stream is reset.
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// ALPN for the mesh QUIC endpoint. Version bumps get a new ALPN so old and
/// new pods never half-speak to each other during a rolling deploy.
pub const ALPN: &[u8] = b"buzz/mesh/1";
/// Wire protocol version, first byte of every encoded frame (datagram or
/// stream frame). Receivers MUST reject unknown versions loudly (count it,
/// log it) rather than guessing.
pub const WIRE_VERSION: u8 = 1;
/// Hard cap on a single length-delimited stream frame (16 MiB). Anything
/// larger is a protocol error, not a bigger buffer.
pub const MAX_STREAM_FRAME: u32 = 16 * 1024 * 1024;
/// A relay runtime's mesh identity: the ed25519 public key of the **mesh
/// endpoint keypair generated fresh at process start**. This is both the
/// iroh endpoint id and the boot-unique runtime id used in the ready
/// registry and ownership leases — one value, boot-unique by construction.
///
/// It is deliberately NOT the deployment's Nostr relay key: that key is
/// secp256k1, and the helm chart shares one `BUZZ_RELAY_PRIVATE_KEY` Secret
/// across all pods of a release — using it here would give every pod the
/// same runtime id and collapse the ownership plane (Wren's contract-review
/// blocker). Binding to the deployment identity is done out-of-band: the
/// ready-registry record carries a relay-key-signed attestation of the
/// runtime pubkey (membership lane), and peers accept mesh connections only
/// from endpoint ids present in attested registry/gossip records.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct RuntimeId(pub [u8; 32]);
impl RuntimeId {
pub fn to_hex(&self) -> String {
hex::encode(self.0)
}
}
impl std::fmt::Debug for RuntimeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RuntimeId({}…)", &self.to_hex()[..8])
}
}
impl std::fmt::Display for RuntimeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.to_hex())
}
}
/// The fenced tuple. Present on every session-bearing frame; checked at
/// every hop against the Redis lease.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct FencedHeader {
pub session_id: Uuid,
/// Monotonic lease generation from the Redis CAS. A receiver that has
/// observed generation G for a session rejects any frame with < G.
pub generation: u64,
/// The runtime the sender believes owns the session. Advisory for
/// routing/diagnostics; the generation is what fences.
pub owner_runtime_id: RuntimeId,
}
/// Tunnel profile, fixed at session establishment.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Profile {
/// Ordered, reliable, backpressured (goose/berd). Rides `open_bi()`.
ReliableStream,
/// Lossy-by-design realtime media (huddle Opus). Rides QUIC datagrams.
RealtimeMedia,
/// Huddle roster/join/leave control. State-bearing — a dropped roster
/// delta is an unrecoverable peer-index desync, so this rides a reliable
/// stream like `ReliableStream`, never datagrams. Separate variant so
/// routing intent and `/_mesh` counters stay legible.
HuddleControl,
}
/// One QUIC datagram: realtime media only.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct MeshDatagram {
pub fenced: FencedHeader,
/// Sender-scoped monotonic sequence for loss/reorder observability.
/// Receivers tolerate gaps and reordering; they never wait.
pub seq: u64,
/// Opaque at this layer: the profile owner defines the internal layout.
/// For realtime media it is `[peer_index: u8][client frame]` — the
/// peer_index is relay routing metadata (owner pod is sole allocator);
/// the client frame's encrypted content is NIP-44 between client
/// endpoints, so server-side plaintext of the media itself never exists.
pub payload: Vec<u8>,
}
/// One length-delimited frame on a mesh bi-stream.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum MeshStreamFrame {
/// MUST be the first frame on every stream, in both directions.
Hello(StreamHello),
/// Opaque tunnel bytes for a reliable-stream session.
Data {
fenced: FencedHeader,
payload: Vec<u8>,
},
/// Clean close: the sender will send no more `Data` for this session.
/// Distinct from a QUIC reset — receivers treat reset as abnormal.
Goodbye {
fenced: FencedHeader,
reason: GoodbyeReason,
},
/// Membership gossip on the control stream (one per peer connection).
/// Payload is the gossip lane's postcard-encoded digest/delta exchange —
/// opaque at this layer so gossip can evolve without a wire bump here.
Gossip { payload: Vec<u8> },
}
/// Stream role, declared in the Hello.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum StreamRole {
/// The per-connection control stream (gossip + liveness). Exactly one
/// per peer connection, opened by the dialer immediately after connect.
Control,
/// A reliable-stream tunnel session.
Session {
fenced: FencedHeader,
profile: Profile,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StreamHello {
pub sender: RuntimeId,
pub role: StreamRole,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum GoodbyeReason {
/// Client closed / session ended normally.
SessionEnded,
/// This runtime is draining (SIGTERM) — re-establish elsewhere.
Draining,
/// The sender observed a newer generation and is fencing itself out.
StaleGeneration,
}
/// Encode a frame: version byte + postcard.
pub fn encode<T: Serialize>(frame: &T) -> Result<Vec<u8>, crate::MeshError> {
let buf = vec![WIRE_VERSION];
postcard::to_extend(frame, buf).map_err(crate::MeshError::Encode)
}
/// Decode a frame: check version byte, then postcard.
pub fn decode<'a, T: Deserialize<'a>>(bytes: &'a [u8]) -> Result<T, crate::MeshError> {
match bytes.split_first() {
Some((&WIRE_VERSION, rest)) => postcard::from_bytes(rest).map_err(crate::MeshError::Decode),
Some((&v, _)) => Err(crate::MeshError::UnknownWireVersion(v)),
None => Err(crate::MeshError::EmptyFrame),
}
}
#[cfg(test)]
mod tests {
use super::*;
fn fenced() -> FencedHeader {
FencedHeader {
session_id: Uuid::from_u128(0xDEAD_BEEF),
generation: 42,
owner_runtime_id: RuntimeId([7u8; 32]),
}
}
#[test]
fn datagram_roundtrip() {
let d = MeshDatagram {
fenced: fenced(),
seq: 9001,
payload: vec![1, 2, 3],
};
let bytes = encode(&d).unwrap();
assert_eq!(bytes[0], WIRE_VERSION);
let back: MeshDatagram = decode(&bytes).unwrap();
assert_eq!(back, d);
}
#[test]
fn stream_frame_roundtrip() {
for f in [
MeshStreamFrame::Hello(StreamHello {
sender: RuntimeId([1u8; 32]),
role: StreamRole::Session {
fenced: fenced(),
profile: Profile::ReliableStream,
},
}),
MeshStreamFrame::Data {
fenced: fenced(),
payload: b"opaque".to_vec(),
},
MeshStreamFrame::Goodbye {
fenced: fenced(),
reason: GoodbyeReason::Draining,
},
MeshStreamFrame::Gossip {
payload: vec![0xAA; 16],
},
] {
let back: MeshStreamFrame = decode(&encode(&f).unwrap()).unwrap();
assert_eq!(back, f);
}
}
#[test]
fn unknown_version_rejected() {
let d = MeshDatagram {
fenced: fenced(),
seq: 1,
payload: vec![],
};
let mut bytes = encode(&d).unwrap();
bytes[0] = 99;
assert!(matches!(
decode::<MeshDatagram>(&bytes),
Err(crate::MeshError::UnknownWireVersion(99))
));
}
/// Opus @ 20ms worst case (~160B) + header must clear the conservative
/// QUIC datagram floor (~1200B path MTU minus QUIC overhead). This pins
/// the header overhead so it can't silently grow past the budget.
#[test]
fn datagram_header_overhead_within_budget() {
let payload = vec![0u8; 160];
let d = MeshDatagram {
fenced: fenced(),
seq: u64::MAX,
payload: payload.clone(),
};
let overhead = encode(&d).unwrap().len() - payload.len();
assert!(
overhead <= 64,
"datagram header overhead {overhead}B exceeds 64B budget"
);
}
}