From 40ee439f36e2afb3c978d0214dd6b8319dfa9642 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 21:51:14 +0000 Subject: remake: a strict remake of a strict swarm isn't followed Review 3, R3: 1186 kept honest nodes from proposing or voting for a strict remake of a swarm strict already, but a majority of members, each with keys of its own, could still commit one, and switch and catchup followed it without asking what kind of remake made the epoch: the registry, policy and bans of a strict swarm changing by a member majority, the honest minority following. A node now refuses to switch to such an epoch (its document's policy strict, the remake's kind strict), and catchup refuses to rejoin one whose chain of epochs holds a strict remake after the swarm was strict (as the old document is, or once a remake since made it so). access.md says so. --- src/remake/catchup.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/remake/catchup.rs') diff --git a/src/remake/catchup.rs b/src/remake/catchup.rs index 4df5c90..6ef8121 100644 --- a/src/remake/catchup.rs +++ b/src/remake/catchup.rs @@ -528,6 +528,22 @@ fn prepare( .filter(|next| next.previous == previous); let gap = target.generation - previous.generation; + // 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. + 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) + && epoch.kind == "strict" + { + if strict { + return Prepared::Failed(format!( + "epoch generation {generation} was made by a strict remake of a swarm strict already: not followed" + )); + } + strict = true; + } + } // Writes made in our epoch go through every remake since, in order. let translator = (previous.generation + 1..=target.generation).try_fold( Translator::default(), -- cgit v1.3.1