aboutsummaryrefslogtreecommitdiffstats
path: root/src/document/signatures.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/document/signatures.rs')
-rw-r--r--src/document/signatures.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/document/signatures.rs b/src/document/signatures.rs
index 47e5917..63b19a5 100644
--- a/src/document/signatures.rs
+++ b/src/document/signatures.rs
@@ -340,6 +340,54 @@ impl Signatures {
(signatures, next)
}
+ /// Received signatures waiting for their changes (`offer`) checked against
+ /// `changes`, not in the document yet, each made by its committer (`committers`, as
+ /// `access::screen` finds them): one valid vouches for its actor's changes up to it,
+ /// these among them.
+ pub(crate) fn vouch_batch(&mut self, changes: &[super::Change], committers: &[Option<String>]) {
+ for (change, committer) in changes.iter().zip(committers) {
+ let hash = change.hash();
+ let Some(signature) = self.pending.remove(&hash) else {
+ continue;
+ };
+ let valid = committer
+ .as_deref()
+ .and_then(crate::identity::public_of)
+ .is_some_and(|key| crate::identity::verify(&key, &message(&hash), &signature));
+ if !valid {
+ continue;
+ }
+ self.insert(hash, signature);
+ let actor = change.actor_id();
+ if self
+ .latest
+ .get(actor)
+ .is_none_or(|latest| latest.seq < change.seq())
+ {
+ self.stamp += 1;
+ self.latest.insert(
+ actor.clone(),
+ Latest {
+ seq: change.seq(),
+ hash,
+ stamp: self.stamp,
+ },
+ );
+ }
+ }
+ }
+
+ /// Signs this node's latest change in `doc` with `key` if no signature of it is kept:
+ /// after a switch or a rejoin, the changes it replayed there (`remake::delta`), made
+ /// without one, vouched for at once.
+ pub(crate) fn sign_own_latest(&mut self, doc: &Document, key: &crate::identity::NodeKey) {
+ if let Some(change) = doc.get_last_local_change()
+ && !self.by_change.contains_key(&change.hash())
+ {
+ self.sign(doc, change.hash(), key);
+ }
+ }
+
/// Whether a signature vouches for `actor`'s change `seq`.
pub(crate) fn verified(&self, actor: &super::ActorId, seq: u64) -> bool {
self.latest