From b3526df29412400cfaa8c3a8d8692e37fc44d19b Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 13:49:26 +0000 Subject: state: a document swap keeps the signatures of the changes it keeps Review 2.2: swap_document forgot every signature. After dropping changes taken unjudged (or a rejoin into the same epoch), the node could vouch for none of the changes it kept: under signatures required, those building on an actor waited for that actor's next signature, and for an actor that stopped writing, forever. Signatures::kept_for keeps the signatures of the changes the new document holds, checks each actor's latest again, and keeps those waiting for their changes. This node's replayed changes are signed at once, as before. --- src/state/host.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/state/host.rs') diff --git a/src/state/host.rs b/src/state/host.rs index 3210ee2..38be831 100644 --- a/src/state/host.rs +++ b/src/state/host.rs @@ -24,9 +24,10 @@ impl AppState { /// document. (Lock order doc -> peer, as in sync generation.) fn swap_document(&self, replica: &mut Replica, epoch: Epoch, doc: Document) -> Document { let old = std::mem::replace(&mut replica.doc, doc); - // The old document's signatures are of its changes; this node's replayed into - // the new one, signed at once. - replica.signatures = Default::default(); + // The old document's signatures, of the changes the new one holds too (it may + // be the old one without some, or another of its epoch); this node's replayed + // into it, signed at once. + replica.signatures = replica.signatures.kept_for(&replica.doc); if let Some(key) = &self.node_key { let replica = &mut *replica; replica.signatures.sign_own_latest(&replica.doc, key); -- cgit v1.3.1