diff options
Diffstat (limited to 'src/state')
| -rw-r--r-- | src/state/host.rs | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/state/host.rs b/src/state/host.rs index d23e07d..3210ee2 100644 --- a/src/state/host.rs +++ b/src/state/host.rs @@ -95,7 +95,8 @@ impl AppState { /// without them (forked where none is), written by a fresh actor of this node's, as /// the old one's later changes are among those dropped; this node's own writes among /// them go to the quarantine. Every peer syncs anew. Nothing while a rejoin runs, or - /// if the document doesn't hold `root`. + /// if the document doesn't hold `root`; nor if `root` is an epoch's root, or nothing + /// would be kept, which no rule can mean (logged as an error). pub(crate) async fn drop_taken(&self, root: ChangeHash) { let own = self.remake.own_actors(); let state = self.clone(); @@ -105,7 +106,9 @@ impl AppState { return None; } let changes = replica.doc.get_changes(&[]); - if !changes.iter().any(|change| change.hash() == root) { + let dropped = changes.iter().find(|change| change.hash() == root)?; + if dropped.deps().is_empty() { + error!(change = %root, "Asked to drop the epoch's root; kept it"); return None; } // In causal order: a change after those it builds on. @@ -119,6 +122,10 @@ impl AppState { .iter() .filter(|change| !tainted.contains(&change.hash())) .collect(); + if kept.is_empty() { + error!(change = %root, "Dropping a change would leave nothing; kept it"); + return None; + } let built_on: std::collections::HashSet<ChangeHash> = kept .iter() .flat_map(|change| change.deps().iter().copied()) |
