Adopt versioning standard + migrate to versioned protocol planes (0.2.0)
Establishes VERSIONING.md: SemVer 0.x (MINOR = breaking wire change) for the release version, and per-plane protocol versions enforced on the wire so incompatible peers fail fast and legibly instead of via silent decode/signature errors. ⚠️ BREAKING WIRE CHANGE — all peers must run >= 0.2.0 to interoperate (ALPNs and gossip subscription topics changed). A pre-0.2.0 peer (e.g. an un-resynced dopedart) can no longer connect, by design, and now fails at the handshake. - New src/protocol.rs: single source of truth for AUDIO/FRIENDS/GOSSIP_PROTO, the derived ALPNs (peerspeak/audio/1, peerspeak/friends/1), GOSSIP_SIG_DOMAIN, and versioned_topic(). Unit tests assert ALPN/domain strings match their integer versions (no silent drift) + that topic namespacing is deterministic. - Unified ALPNs: audio was b"peerspeak-audio" (unversioned, and duplicated in iroh_impl.rs + core/mod.rs) -> peerspeak/audio/1 from protocol.rs; friends re-exports protocol::FRIENDS_ALPN (was peerspeak/friends/0 -> /1). - Gossip: subscribe to versioned_topic(ticket.topic_id) so different gossip versions never share a swarm; the raw topic_id stays the room identity and what signatures bind. GOSSIP_SIG_DOMAIN centralized into protocol.rs. - Cargo.toml 0.1.0 -> 0.2.0. 316 lib tests / clippy --all-targets clean. VERSIONING.md documents the bump rules, the "I changed X -> what do I bump" table, and a release checklist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ use serde::{Serialize, Deserialize};
|
||||
|
||||
/// Domain-separation tag mixed into every signed gossip payload so a signature
|
||||
/// can never be lifted out of this protocol/version into another context.
|
||||
const GOSSIP_SIG_DOMAIN: &str = "peerspeak-gossip-v1";
|
||||
use crate::protocol::GOSSIP_SIG_DOMAIN;
|
||||
|
||||
/// How far a payload's sender-stamped timestamp may differ from local time
|
||||
/// before it's rejected as stale (replayed) or implausibly future. Bounds the
|
||||
@@ -248,7 +248,11 @@ impl RoomState for IrohGossipState {
|
||||
crate::redact_for_log(ticket_str)
|
||||
));
|
||||
let ticket = ticket_str.parse::<PeerSpeakTicket>()?;
|
||||
let topic_id = TopicId::from_bytes(ticket.topic_id);
|
||||
// Version-namespace the subscribed topic (VERSIONING.md): peers on a
|
||||
// different gossip protocol version derive a different topic from the same
|
||||
// ticket and never share a swarm. The raw ticket.topic_id stays the room
|
||||
// identity (and what signatures bind, below).
|
||||
let topic_id = TopicId::from_bytes(crate::protocol::versioned_topic(ticket.topic_id));
|
||||
|
||||
crate::log_msg(&format!(
|
||||
"Parsed ticket. host_id={}, host_addrs={}, topic={}",
|
||||
|
||||
Reference in New Issue
Block a user