aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/rules.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/access/rules.rs')
-rw-r--r--src/access/rules.rs10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs
index f285328..2aed4b8 100644
--- a/src/access/rules.rs
+++ b/src/access/rules.rs
@@ -33,7 +33,7 @@ use crate::document::at::At;
use crate::document::inspect::{Action, Op, Path};
use crate::document::meta;
use crate::document::replica::Epoch;
-use crate::document::{ChangeHash, Document, store};
+use crate::document::{ChangeHash, Document, ReadDoc, store};
/// A change to judge, as its bytes say.
#[derive(Debug, Clone)]
@@ -75,8 +75,10 @@ impl std::fmt::Display for Refusal {
/// Judges `change`, about to be applied to `doc` (of `epoch`).
pub(crate) fn judge(doc: &Document, epoch: Epoch, change: &Change<'_>) -> Result<(), Refusal> {
if change.deps.is_empty() {
+ // The first epoch's: the first change a document holds, as it comes to an empty
+ // one, or as it is in one (judged again, `swarm::refusals`).
let root = if epoch.generation == 0 {
- doc.get_heads().is_empty()
+ doc.get_heads().is_empty() || doc.get_change_by_hash(&change.hash).is_some()
} else {
change.hash.0 == epoch.id
};
@@ -720,6 +722,10 @@ mod tests {
};
assert!(root(&Document::new(), Epoch::GENESIS, [1; 32]).is_ok());
assert!(refused(root(&swarm(false), Epoch::GENESIS, [1; 32])));
+ // The first epoch's, judged again in a document that holds it: its root.
+ let held = swarm(false);
+ let first = held.get_changes(&[])[0].hash();
+ assert!(root(&held, Epoch::GENESIS, first.0).is_ok());
let epoch = Epoch {
generation: 3,
id: [5; 32],