From a9fb4e6890bfaef1e25cdceb4eea9c997e3c7cdf Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 5 Nov 2026 03:49:13 +0100 Subject: no swarm ID in sync --- docs/peers.md | 3 ++- src/simtest/bench.rs | 2 +- src/swarm/stats.rs | 4 ++-- src/swarm/sync.rs | 29 +++++++---------------------- src/transport/mod.rs | 1 - src/transport/wire.rs | 3 +-- 6 files changed, 13 insertions(+), 29 deletions(-) diff --git a/docs/peers.md b/docs/peers.md index 0f7635e..e86e530 100644 --- a/docs/peers.md +++ b/docs/peers.md @@ -78,7 +78,8 @@ sequenceDiagram ``` One round trip makes both sides members of each other: the HELLO proves the sender's -key, the reply the swarm ID and the responder's key. A new handshake resets the sync +key, the reply the swarm ID and the responder's key. Sync messages don't repeat the +swarm ID: the handshake bound the peer to it. A new handshake resets the sync session on both sides; HELLOs carry the handshake's number, so a resent HELLO (its reply was lost) or a late copy is answered without resetting again. A node that doesn't know its swarm yet (it is joining itself) doesn't answer a HELLO; the sender retries. diff --git a/src/simtest/bench.rs b/src/simtest/bench.rs index 0300825..5b713f3 100644 --- a/src/simtest/bench.rs +++ b/src/simtest/bench.rs @@ -725,7 +725,7 @@ fn report( let framed = r1.framed - r0.framed; let _ = writeln!( out, - " sync envelopes: {:.0} bytes each beside the Automerge message, {:.0} of them the swarm ID and the epoch", + " sync envelopes: {:.0} bytes each beside the Automerge message, {:.0} of them the epoch", each(r1.framing_bytes - r0.framing_bytes, framed), each(r1.framing_id_bytes - r0.framing_id_bytes, framed), ); diff --git a/src/swarm/stats.rs b/src/swarm/stats.rs index 371fe42..ed91db0 100644 --- a/src/swarm/stats.rs +++ b/src/swarm/stats.rs @@ -129,7 +129,7 @@ pub(crate) struct Relay { pub(crate) delivered: u64, pub(crate) delivered_bytes: u64, /// Sync messages sent (not offers), the bytes the envelope added to their - /// Automerge messages, and of those the swarm ID's and the epoch's. + /// Automerge messages, and of those the epoch's. pub(crate) framed: u64, pub(crate) framing_bytes: u64, pub(crate) framing_id_bytes: u64, @@ -255,7 +255,7 @@ impl NodeStats { } /// A sync message went out whose envelope added `bytes` to its Automerge message, - /// `ids` of them the swarm ID and the epoch. + /// `ids` of them the epoch. pub(crate) fn sync_framing(&self, bytes: usize, ids: usize) { let mut inner = self.lock(); inner.relay.framed += 1; diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 8660742..28f3ca0 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -239,14 +239,13 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str) -> Result<()> { return (session, Ok(None)); }; // What the envelope adds to an Automerge message (`swarm::stats`), and of - // that, the swarm ID and the epoch (msgpack: 36 bytes the epoch). + // that, the epoch (msgpack: 36 bytes). let inner = match &body { transport::SyncBody::Message(payload) => Some(payload.0.len()), transport::SyncBody::Delta(_) => None, }; - let ids = rmp_serde::encode::to_vec(&swarm_id).map_or(0, |id| id.len()) + 36; + let ids = 36; let envelope = transport::SyncEnvelope { - swarm_id, epoch, epoch_seq, body, @@ -390,13 +389,11 @@ pub(crate) async fn handle_sync( debug!(peer = %peer, "Dropping sync message from a peer that isn't a member yet"); true } - Standing::Member { swarm_id } if swarm_id != &envelope.swarm_id => { - bail!( - "Sync swarm mismatch for peer {peer}: validated_swarm={swarm_id}, envelope_swarm={}", - envelope.swarm_id - ); - } - Standing::Member { .. } => false, + // Its swarm was proven by the handshake (the envelope doesn't say it again). + Standing::Member { swarm_id } => match state.swarm_id().await { + Some(ours) if &ours == swarm_id => false, + _ => bail!("Sync from {peer}, a member of swarm {swarm_id}, which isn't ours"), + }, } }; @@ -409,18 +406,6 @@ pub(crate) async fn handle_sync( return Ok(()); } - let expected_swarm = state - .swarm_id() - .await - .ok_or_else(|| anyhow!("Missing expected swarm ID after peer membership"))?; - if envelope.swarm_id != expected_swarm { - bail!( - "Incompatible swarm from {peer}: expected {}, received {}", - expected_swarm, - envelope.swarm_id - ); - } - let epoch_label = envelope.epoch; let from_ready = envelope.ready; let writer = envelope.writer; diff --git a/src/transport/mod.rs b/src/transport/mod.rs index 04e0506..3fd4490 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -656,7 +656,6 @@ impl std::fmt::Debug for HelloReply { #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct SyncEnvelope { - pub(crate) swarm_id: String, /// Epoch of the document the message was generated from. #[serde(with = "crate::transport::wire::codec::epoch")] pub(crate) epoch: Epoch, diff --git a/src/transport/wire.rs b/src/transport/wire.rs index 475c7f2..3f7736d 100644 --- a/src/transport/wire.rs +++ b/src/transport/wire.rs @@ -14,7 +14,7 @@ use super::{EncodedMessage, MessageKind, ParsedMessage}; /// The wire format's version, the first byte of every payload. Bump it with every change /// to a message type or a codec (`golden_bytes` fails then). -pub(crate) const VERSION: u8 = 28; +pub(crate) const VERSION: u8 = 29; /// What the second byte of a payload says. fn tag(kind: MessageKind) -> u8 { @@ -401,7 +401,6 @@ pub(crate) fn samples() -> Vec { sender_run_id: [6; 16], }), ParsedMessage::Sync(SyncEnvelope { - swarm_id: "swarm".into(), epoch, epoch_seq: 1, body: SyncBody::Delta(DeltaSpec { -- cgit v1.3.1