aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/signatures.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-08 21:46:41 +0000
committertv <tv@krebsco.de>2026-11-08 22:58:41 +0100
commit1fa5360a210b4b820441fdbc6f5dfbbb9eaf14f3 (patch)
treedc99ee243b33b2a9f729a38175e65b5e25253aca /src/swarm/signatures.rs
parent51da8017d4592b31e904f505cab18ae1854df08b (diff)
screen: signatures required as the policy a change came under says
Review 3, R1: what a node received was vouched for only while its own document's policy required signatures. A joiner's first sync, and every node's message bringing `required`, went in by the rules alone: a malicious first peer could plant changes under other members' actors at their next seqs, their real ones then failing as duplicates for good. The signatures a message carries are always offered now, and the screen always has them: a change waits for one where the policy at the heads it is judged at requires it (rules::Reads::required, read once per heads), whatever the receiving document holds. Changes written under a policy not requiring signatures wait for none, as on every other node; the check for forged changes runs always. Changes waiting for a signature are judged again whenever signatures come. The test of signatures required now takes the history into an empty document; a new one takes changes written under a policy not requiring them without any.
Diffstat (limited to 'src/swarm/signatures.rs')
-rw-r--r--src/swarm/signatures.rs51
1 files changed, 23 insertions, 28 deletions
diff --git a/src/swarm/signatures.rs b/src/swarm/signatures.rs
index 9ea404e..111b3da 100644
--- a/src/swarm/signatures.rs
+++ b/src/swarm/signatures.rs
@@ -75,35 +75,30 @@ pub(crate) async fn received(state: &AppState, message: SignaturesMessage) {
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(outcome) => outcome.applied,
- Err(error) => {
- tracing::warn!(error = %format!("{error:#}"), "Couldn't judge the changes waiting for signatures");
- 0
- }
- };
+ let (epoch, epoch_seq) = (replica.epoch, replica.epoch_seq);
+ let replica = &mut *replica;
+ replica.signatures.offer(&replica.doc, signatures);
+ // Changes waiting for them judged again (`access::screen`): those the policy they
+ // were written under requires signed.
+ 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();
+ match applied {
+ Ok(outcome) => outcome.applied,
+ Err(error) => {
+ tracing::warn!(error = %format!("{error:#}"), "Couldn't judge the changes waiting for signatures");
+ 0
}
- 0
}
})
.await