aboutsummaryrefslogtreecommitdiffstats
path: root/src/document/sync.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-07 22:35:22 +0100
committertv <tv@krebsco.de>2026-11-07 22:35:22 +0100
commit7323e8ed8598cda9784493aa3334d947120b53d8 (patch)
tree1e772cdf74974f918cf07d2e4b9d8e8593bed9dd /src/document/sync.rs
parentd322e7d4aa41d94232113cb7680cec1d65a11b0c (diff)
swarm: changes taken unjudged, dropped (REFUSALS)
A node refusing changes a peer brought tells it which broke a rule; the peer judges them itself, and if its rules refuse them too, drops them with all built on them (its document forked without them, a fresh actor), quarantining its own writes among them. Wire version 42. Auth plan M6 (rejoin on taint).
Diffstat (limited to 'src/document/sync.rs')
-rw-r--r--src/document/sync.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/document/sync.rs b/src/document/sync.rs
index 823d4a3..b172dd1 100644
--- a/src/document/sync.rs
+++ b/src/document/sync.rs
@@ -212,6 +212,9 @@ pub(crate) struct SyncSession {
/// The wait before answering a peer that offers again only changes we refused
/// (`refused_again`).
refused_backoff: Backoff,
+ /// When we last told the peer which of the changes it brought we refused
+ /// (`refusals_due`).
+ refusals_told: Option<Instant>,
/// The answer we expect to our last sync message(s), if any.
pub(crate) reply: Option<SyncReplyWait>,
@@ -264,6 +267,7 @@ impl SyncSession {
assumed_lately: std::collections::VecDeque::new(),
said_heads: None,
refused_backoff: Backoff::new(REFUSED_WAIT, REFUSED_WAIT_MAX),
+ refusals_told: None,
reply: None,
reply_backoff,
}
@@ -993,6 +997,18 @@ impl SyncSession {
delay
}
+ /// Whether to tell the peer which of the changes it brought we refused, now
+ /// (`swarm::refusals`): at most every `refusals::TELL_EVERY`.
+ pub(crate) fn refusals_due(&mut self, now: Instant) -> bool {
+ let due = self.refusals_told.is_none_or(|told| {
+ now.saturating_duration_since(told) >= crate::swarm::refusals::TELL_EVERY
+ });
+ if due {
+ self.refusals_told = Some(now);
+ }
+ due
+ }
+
/// The peer brought changes we took (or none refused before): answered at once again.
pub(crate) fn refusals_settled(&mut self) {
self.refused_backoff.reset();