aboutsummaryrefslogtreecommitdiffstats
path: root/src/remake/catchup.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 03:05:08 +0000
committertv <tv@krebsco.de>2026-11-09 04:05:27 +0100
commit3c1403409877b0006594324a0daa5e9dd55ec3f4 (patch)
tree7fdd96893a01185259f369d84e3f5231a9de4995 /src/remake/catchup.rs
parentc2e566599aed088973b5a5be2bb04ee69cee5c7a (diff)
remake: leave out earlier epochs' metadata past the replay window
Every snapshot carried the metadata of all earlier epochs (`_continuum/epochs`) forward, so it grew by an entry, a clock per actor among it, with every remake. Only a rejoining node reads an earlier entry: a node on epoch P reads P+1's (its clock, when it was proposed, its replay window) and every one up to the swarm's epoch (kind, translation, whether it was strict). It replays only while P+1's replay window covers it; beyond, its writes are quarantined whatever the entries say. So a snapshot now leaves out the generations older than the oldest whose replay window still covers a node on the epoch before it (`snapshot::left_out`), judged by the remake's `proposedAt`: the same on every node, and earlier than any rejoining node's clock, so nothing a node can still replay through goes. Metadata that doesn't read stays, with all after it. A strict remake's metadata stays for good: by it a rejoining node, however far behind, tells a strict remake of a swarm strict already (`catchup::prepare`, which reads the generations it finds). There is at most one, short of such a remake. No new key and no change to the rejoin: a node beyond the window that finds some entries and not others quarantines with "cannot translate" rather than "outside the replay window".
Diffstat (limited to 'src/remake/catchup.rs')
-rw-r--r--src/remake/catchup.rs6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/remake/catchup.rs b/src/remake/catchup.rs
index 6ef8121..a3443ba 100644
--- a/src/remake/catchup.rs
+++ b/src/remake/catchup.rs
@@ -522,7 +522,9 @@ fn prepare(
};
// The epoch that followed ours records (per actor) which of our changes it took.
- // Snapshots carry earlier epochs' metadata forward, so this works across any gap.
+ // Snapshots carry earlier epochs' metadata forward while a node can replay through
+ // it (`snapshot::left_out`), so this works across any gap within the window; beyond
+ // it, the metadata missing quarantines as the window would.
let next = snapshot::read_epoch_metadata(copy, previous.generation + 1)
.ok()
.filter(|next| next.previous == previous);
@@ -531,6 +533,8 @@ fn prepare(
// A strict remake of a swarm strict already isn't followed: there its registry,
// policy and bans change by its users' signatures, not by a majority of members
// (`vote::strict_taken`). Strict as our document is, or once a remake since made it so.
+ // A strict remake's metadata is carried forward for good (`snapshot::left_out`), so
+ // this sees every one since our epoch, however far behind.
let mut strict = crate::access::policy::of(old).strict();
for generation in previous.generation + 1..=target.generation {
if let Ok(epoch) = snapshot::read_epoch_metadata(copy, generation)