aboutsummaryrefslogtreecommitdiffstats
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/host.rs17
-rw-r--r--src/state/mod.rs5
2 files changed, 19 insertions, 3 deletions
diff --git a/src/state/host.rs b/src/state/host.rs
index e401509..fb2e2e9 100644
--- a/src/state/host.rs
+++ b/src/state/host.rs
@@ -24,8 +24,13 @@ 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.
+ // The old document's signatures are of its changes; this node's replayed into
+ // the new one, signed at once.
replica.signatures = Default::default();
+ if let Some(key) = &self.node_key {
+ let replica = &mut *replica;
+ replica.signatures.sign_own_latest(&replica.doc, key);
+ }
replica.epoch = epoch;
replica.epoch_seq += 1;
// Publishes the epoch with the heads (`Replica::stamps`), under the same lock,
@@ -340,6 +345,11 @@ impl Host for AppState {
// take the document's lock first (`mutate_doc`).
let (old, resumed) = state.take_stale(old);
let out = f(&mut replica.doc, &old);
+ // What it replayed, vouched for at once.
+ if let Some(key) = &state.node_key {
+ let replica = &mut *replica;
+ replica.signatures.sign_own_latest(&replica.doc, key);
+ }
replica.writable = true;
replica.refresh_heads();
if resumed {
@@ -403,15 +413,18 @@ impl Host for AppState {
tokio::task::spawn_blocking(move || {
let result = {
let mut replica = state.doc.blocking_write();
- let result = if crate::access::policy::of(&replica.doc).enforced() {
+ let policy = crate::access::policy::of(&replica.doc);
+ let result = if policy.enforced() {
// Judged first (`access::screen`).
let (epoch, epoch_seq) = (replica.epoch, replica.epoch_seq);
+ let replica = &mut *replica;
crate::access::screen::apply_bytes(
&mut replica.doc,
epoch,
epoch_seq,
change.raw_bytes(),
&state.screening,
+ policy.required().then_some(&mut replica.signatures),
&mut crate::document::PatchLog::inactive(),
)
.map(|_| ())
diff --git a/src/state/mod.rs b/src/state/mod.rs
index 049c9e6..294b446 100644
--- a/src/state/mod.rs
+++ b/src/state/mod.rs
@@ -542,7 +542,10 @@ impl AppState {
if after != before
&& let [hash] = after[..]
{
- if state.sign_every == SignEvery::Change || sign.wanted(&replica.doc) {
+ if state.sign_every == SignEvery::Change
+ || sign.wanted(&replica.doc)
+ || crate::access::policy::of(&replica.doc).required()
+ {
let replica = &mut *replica;
replica.signatures.sign(&replica.doc, hash, key);
} else {