summaryrefslogtreecommitdiffstats
path: root/src/swarm/sync.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-23 06:43:33 +0200
committertv <tv@krebsco.de>2026-10-23 06:43:33 +0200
commit7af7b78f1434bc7ffc0333f2430dbd1934ec0570 (patch)
tree4ce73f5cd6874d2dd0a9670264e532ee49d80454 /src/swarm/sync.rs
parent121174a20618d88174784c5b2f1d905100f06223 (diff)
open sync only from one side
If both sides open, the openings cross, and an empty node's answer to the other opening (empty heads) makes the other side send the whole document a second time. Now after a sync reset, only the side with the smaller public key opens the sync; the other answers it, or opens itself if nothing arrives.
Diffstat (limited to 'src/swarm/sync.rs')
-rw-r--r--src/swarm/sync.rs24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs
index e294201..15b4ced 100644
--- a/src/swarm/sync.rs
+++ b/src/swarm/sync.rs
@@ -58,10 +58,28 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str, retry_delivery: bool
return Ok(());
}
- match &peer_state.membership {
- PeerMembership::Unknown => return Ok(()),
- PeerMembership::Member { swarm_id } => swarm_id.clone(),
+ let PeerMembership::Member { swarm_id } = &peer_state.membership else {
+ return Ok(());
+ };
+
+ if !retry_delivery {
+ let we_open = state.local_id() < peer;
+ if let Some(wait) = peer_state.opening_wait(we_open, Instant::now()) {
+ trace!(
+ wait_ms = wait.as_millis(),
+ "Leaving the opening sync message to the peer"
+ );
+ let tx = state.sync_events.clone();
+ let peer = peer.to_owned();
+ tokio::spawn(async move {
+ tokio::time::sleep(wait).await;
+ let _ = tx.send(SyncEvent::PeerNeedsSync(peer));
+ });
+ return Ok(());
+ }
}
+
+ swarm_id.clone()
};
let swarm_id = state