aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/signatures.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm/signatures.rs')
-rw-r--r--src/swarm/signatures.rs41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/swarm/signatures.rs b/src/swarm/signatures.rs
index c172455..309ccc2 100644
--- a/src/swarm/signatures.rs
+++ b/src/swarm/signatures.rs
@@ -68,12 +68,47 @@ pub(crate) async fn received(state: &AppState, message: SignaturesMessage) {
return;
};
let doc = std::sync::Arc::clone(&state.doc);
- let _ = tokio::task::spawn_blocking(move || {
+ let screening = std::sync::Arc::clone(&state.screening);
+ // How many waiting changes went in, if any: published as received ones are.
+ let applied = tokio::task::spawn_blocking(move || {
let mut replica = doc.blocking_write();
- if replica.epoch == message.epoch {
+ if replica.epoch != message.epoch {
+ return 0;
+ }
+ {
+ let (epoch, epoch_seq) = (replica.epoch, replica.epoch_seq);
let replica = &mut *replica;
replica.signatures.offer(&replica.doc, signatures);
+ // With signatures required, changes waiting for them judged again
+ // (`access::screen`).
+ if crate::access::policy::of(&replica.doc).required() {
+ let applied = replica.logged_signed(|doc, known, log| {
+ let applied = crate::access::screen::apply_bytes(
+ doc,
+ epoch,
+ epoch_seq,
+ &[],
+ &screening,
+ Some(known),
+ log,
+ );
+ (applied, true)
+ });
+ replica.refresh_heads();
+ return match applied {
+ Ok(applied) => applied,
+ Err(error) => {
+ tracing::warn!(error = %format!("{error:#}"), "Couldn't judge the changes waiting for signatures");
+ 0
+ }
+ };
+ }
+ 0
}
})
- .await;
+ .await
+ .unwrap_or(0);
+ if applied > 0 {
+ state.publish_change();
+ }
}