Revert strict gossip ingest ordering: it broke convergence across compaction
All checks were successful
CI / check (push) Successful in 5m12s

This commit is contained in:
Jean Chevronnet 2026-07-19 21:56:05 +00:00
parent 4330ff169b
commit 6a22bee2e1
No known key found for this signature in database
3 changed files with 23 additions and 49 deletions

View file

@ -894,20 +894,16 @@ impl EventLog {
return Ok(None);
}
}
// Apply strictly in per-origin sequence. The FIRST entry ever seen from an
// origin sets the baseline — a peer syncing from a COMPACTED node starts
// mid-stream (its seqs restart at next_seq(), not 0), so we can't demand 0.
// After that, only the next contiguous seq is accepted; a non-contiguous one
// (an older duplicate, or a future entry a relay delivered ahead of the direct
// path in a 3+-node mesh) is dropped rather than applied, so it can't advance
// the version vector past a gap — the digest then re-requests the gap in order
// instead of losing it forever.
let expected = match self.versions.get(&entry.origin) {
None => entry.seq,
Some(&s) => s + 1,
};
if entry.seq != expected {
return Ok(None);
// Accept any entry newer than what we hold for this origin. A forward jump is
// legitimate here: a peer syncing from a COMPACTED node receives seqs that
// start well above 0 (the intermediate ones were folded into the snapshot),
// and the fold is an idempotent upsert. NOTE: this cannot detect an out-of-
// order relay in a 3+-node mesh (an entry delivered ahead of its predecessors
// advances the version past the gap). Fixing that safely needs a snapshot-epoch
// marker so a compaction jump is distinguishable from a live gap — deferred;
// see docs/federation.md. Not reachable today (no gossip peers).
if self.versions.get(&entry.origin).is_some_and(|&s| entry.seq <= s) {
return Ok(None); // already have it
}
self.persist(&entry)?;
self.lamport = self.lamport.max(entry.lamport).saturating_add(1); // Lamport receive rule