From eae437ce2734b8d65bf40aa207c134a3c641138f Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 22:44:23 +0000 Subject: sync: signatures go with changes only A sync message took the signatures its peer wasn't sent yet whenever it had a body, an Automerge message saying only what we have included. A signature belongs with the changes it vouches for: they go along the trees, and a peer that got them elsewhere got the signatures with them. Signatures now go in a message that carries changes (pushed, offered as a delta, or in an Automerge message carrying some: SyncSession:: carrying), and in no other. --- src/document/sync.rs | 7 +++++++ src/swarm/sync.rs | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/document/sync.rs b/src/document/sync.rs index 394b10a..440718c 100644 --- a/src/document/sync.rs +++ b/src/document/sync.rs @@ -983,6 +983,13 @@ impl SyncSession { self.state.their_heads.is_none() && we_ready && peer_ready == Some(false) } + /// Whether the message just generated (`generate`) carries changes. + pub(crate) fn carrying(&self) -> bool { + self.sending + .as_ref() + .is_some_and(|sending| !sending.sent.is_empty()) + } + /// Which session this is: a message generated from it reports its send's outcome /// with this (`send_succeeded`, `send_failed`). pub(crate) fn id(&self) -> u64 { diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 0c49fa3..b7bf8ed 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -287,8 +287,18 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str) -> Result<()> { _ => {} } } - // With what it carries, the signatures the peer wasn't sent yet. - let signatures = if body.is_some() { + // With changes, the signatures the peer wasn't sent yet: they go where + // changes go, along the trees, so a peer that got these changes + // elsewhere got the signatures with them, and a message carrying + // none takes none. + let carries = match &body { + Some( + transport::SyncBody::Changes { .. } | transport::SyncBody::Delta(_), + ) => true, + Some(_) => peer_state.sync.carrying(), + None => false, + }; + let signatures = if carries { let (signatures, sent) = replica.signatures.newer_than(peer_state.signatures_sent); peer_state.signatures_sent = sent; -- cgit v1.3.1