aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 15:36:04 +0000
committertv <tv@krebsco.de>2026-11-09 18:19:24 +0100
commitd16da7283ceca16f223f3fb6b0429c7b2ae1aec0 (patch)
tree0548a37628a067eb7dcbb493d8cd6fc43afc58c6
parentc1e750c5f795d4dd659be99f873ab7f98d5a2e83 (diff)
screen: that a policy was held kept across a swap of the document
Review 4, F12: `Screening::of` started screening over when the document was swapped (a drop, a switch, a rejoin), the root pin alone carried on, so whether the document had held a policy (`policed`, 1211) was forgotten there too, not only across a restart as documented: after a drop with the policy removed meanwhile, late changes written under it went in unjudged again. It is carried on now, as the root pin is; what belongs to the old document (changes waiting, refusals, drops held) still starts over. access.md says so.
-rw-r--r--docs/access.md4
-rw-r--r--src/access/screen.rs8
2 files changed, 8 insertions, 4 deletions
diff --git a/docs/access.md b/docs/access.md
index 3d4aeaf..402f1ab 100644
--- a/docs/access.md
+++ b/docs/access.md
@@ -346,8 +346,8 @@ the signatures of what was written under a policy requiring them. While neither
its document nor what it receives holds a policy, it judges only that a root is the
epoch's, and nothing costs more than applying the changes. A policy removed, or
replaced by one the node doesn't know, still judges what was written under it and
-comes late, as long as the node runs (after a restart, a document without a policy
-is judged as one that never had one).
+comes late, as long as the node runs, its document swapped meanwhile or not (after a
+restart, a document without a policy is judged as one that never had one).
An epoch's root is pinned. A remake's is its epoch's ID, the hash of its snapshot. The
first epoch's is its genesis change, which its genesis node logs (`The swarm's root`)
diff --git a/src/access/screen.rs b/src/access/screen.rs
index b1318ea..3ea03e0 100644
--- a/src/access/screen.rs
+++ b/src/access/screen.rs
@@ -147,8 +147,9 @@ impl Screening {
/// Whether `doc` holds a policy, known or not, or did since this node took it up:
/// then what it receives is judged (`apply`), each change by the policy at its
/// dependencies, though the policy is gone or unknown now; changes written under it
- /// may still come. Not across a restart: a node that starts with no policy in its
- /// document judges as one that never had one.
+ /// may still come. Kept across a swap of the document (a drop, a switch, a rejoin,
+ /// `of`); not across a restart: a node that starts with no policy in its document
+ /// judges as one that never had one.
pub(crate) fn policed(&mut self, doc: &Document) -> bool {
self.policed |= !matches!(super::policy::of(doc), super::policy::Policy::Open);
self.policed
@@ -156,9 +157,12 @@ impl Screening {
pub(crate) fn of(&mut self, epoch_seq: u32) -> &mut Self {
if self.epoch_seq != epoch_seq {
+ // The root pin and whether a policy was held go on; what belongs to the old
+ // document (changes waiting, refusals, drops held) doesn't.
*self = Screening {
epoch_seq,
root_pin: std::mem::take(&mut self.root_pin),
+ policed: self.policed,
..Screening::default()
};
}