aboutsummaryrefslogtreecommitdiffstats
path: root/src/document/file.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-07 22:35:21 +0100
committertv <tv@krebsco.de>2026-11-07 22:35:21 +0100
commit2ff408c024a0ef5db2a770e8a091783f1b6d9cfc (patch)
tree5350c2290c673049af04ff1c55043087a86f3b14 /src/document/file.rs
parent63b34dfa41e1595145507a88901e332bf4bd3b14 (diff)
signatures: with sync messages
Sync messages carry, for each actor's writes, the latest signature the sender checked; the receiver checks it once it holds the change. Auth plan M5.
Diffstat (limited to 'src/document/file.rs')
-rw-r--r--src/document/file.rs28
1 files changed, 7 insertions, 21 deletions
diff --git a/src/document/file.rs b/src/document/file.rs
index 33f7934..2d588ee 100644
--- a/src/document/file.rs
+++ b/src/document/file.rs
@@ -6,8 +6,8 @@
//! each a little-endian `u32` length and that many bytes, the first of them its kind
//! (`Record`): first a full save of the document, then increments (the changes after
//! the heads written before), and the signatures of its changes
-//! (`document::signatures`), those the file holds none of yet, each a change hash
-//! (32 bytes) and its signature (64). A record cut short by a crash is dropped when
+//! (`document::signatures`), those the file holds none of yet, as
+//! `signatures::pack` packs them. A record cut short by a crash is dropped when
//! reading. A file of `continuum-document/1` has records of the document alone,
//! without their kind: a full save, then increments.
//!
@@ -46,9 +46,6 @@ enum Record {
Signatures = 2,
}
-/// A signature as a record holds it: the change's hash, then the signature.
-const SIGNATURE_BYTES: usize = 32 + 64;
-
#[derive(Debug, Default, Serialize, Deserialize)]
struct Header {
/// Hex actor IDs.
@@ -146,16 +143,10 @@ fn parse(bytes: &[u8]) -> Result<(Loaded, usize)> {
(Record::Increment, Some(doc)) => {
doc.load_incremental(record).context("an increment")?;
}
- (Record::Signatures, Some(_)) => {
- if record.len() % SIGNATURE_BYTES != 0 {
- bail!("signatures of {} bytes", record.len());
- }
- for entry in record.chunks_exact(SIGNATURE_BYTES) {
- let (hash, signature) = entry.split_at(32);
- let hash = ChangeHash(hash.try_into().expect("32 bytes"));
- signatures.push((hash, signature.try_into().expect("64 bytes")));
- }
- }
+ (Record::Signatures, Some(_)) => signatures.extend(
+ super::signatures::unpack(record)
+ .ok_or_else(|| anyhow!("signatures of {} bytes", record.len()))?,
+ ),
(_, None) => bail!("a record before the full save"),
}
records = after;
@@ -184,12 +175,7 @@ fn signatures_record(signatures: &[(ChangeHash, [u8; 64])]) -> Vec<u8> {
if signatures.is_empty() {
return Vec::new();
}
- let mut bytes = Vec::with_capacity(signatures.len() * SIGNATURE_BYTES);
- for (hash, signature) in signatures {
- bytes.extend_from_slice(&hash.0);
- bytes.extend_from_slice(signature);
- }
- record(Record::Signatures, &bytes)
+ record(Record::Signatures, &super::signatures::pack(signatures))
}
/// A whole file: header, one full save, and the signatures.