diff options
| author | tv <tv@krebsco.de> | 2026-11-05 01:23:40 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-05 01:23:40 +0100 |
| commit | 889e23ee1eb8a209efe7c1eae86aa39091560149 (patch) | |
| tree | 8da04d6d62f9a1647f90b6ea459eba62b91f5a12 /src/document/sync.rs | |
| parent | 0d16147e95211b0829fddaefb0d014fe0c48dbc8 (diff) | |
covered neighbours have it
Diffstat (limited to 'src/document/sync.rs')
| -rw-r--r-- | src/document/sync.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/document/sync.rs b/src/document/sync.rs index 1f61f70..befb8e5 100644 --- a/src/document/sync.rs +++ b/src/document/sync.rs @@ -476,6 +476,13 @@ impl SyncSession { known.len() } + /// The peer has `changes`, or will without us (another parent in their writer's + /// tree brings them, `swarm::tree::forward`): counted as sent, they don't go to it, + /// unless it asks for them (`resend_if_needed`). + pub(crate) fn known_to_peer(&mut self, changes: &[crate::document::ChangeHash]) { + self.state.sent_hashes.extend(changes.iter().copied()); + } + /// What the sync state knows of the peer (`PeerView`). fn peer_view(&self) -> PeerView { PeerView { @@ -1238,6 +1245,35 @@ mod tests { assert_eq!(b.known_beyond(&theirs, &theirs.get_heads()), 0); } + /// Changes the peer gets from elsewhere (another parent in their writer's tree) + /// don't go to it, but do if it asks. + #[test] + fn changes_known_to_the_peer_go_only_when_asked() { + use crate::document::testing::change; + use automerge::{ROOT, transaction::Transactable}; + let (mut ours, mut theirs) = (Document::new(), Document::new()); + change(&mut ours, |doc| doc.put(ROOT, "early", 1).unwrap()); + let (mut a, mut b) = in_step(&mut ours, &mut theirs); + let (now, bytes) = (Instant::now(), SyncBytes::default()); + + change(&mut ours, |doc| doc.put(ROOT, "elsewhere", 2).unwrap()); + a.known_to_peer(&ours.get_heads()); + let message = a.generate(&ours, now, bytes).expect("our heads moved"); + a.send_succeeded(a.id()); + let (carried, _) = decode(&message).unwrap().sizes(); + assert_eq!(carried, 0, "not sent: the peer gets it from elsewhere"); + + // It didn't: it asks, and gets it. + b.receive(&mut theirs, decode(&message).unwrap()).unwrap(); + let asking = b.generate(&theirs, now, bytes).expect("it asks"); + b.send_succeeded(b.id()); + a.receive(&mut ours, decode(&asking).unwrap()).unwrap(); + a.resend_if_needed(&ours, "b"); + let answer = a.generate(&ours, now, bytes).expect("answered"); + b.receive(&mut theirs, decode(&answer).unwrap()).unwrap(); + assert_eq!(theirs.get_heads(), ours.get_heads()); + } + /// Our transport refused a message taken as delivered: the peer's heads are as /// before, so the next message carries the change again. #[test] |
