summaryrefslogtreecommitdiffstats
path: root/src/transport/wire.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/wire.rs')
-rw-r--r--src/transport/wire.rs54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/transport/wire.rs b/src/transport/wire.rs
index ceeaf87..5577f42 100644
--- a/src/transport/wire.rs
+++ b/src/transport/wire.rs
@@ -14,7 +14,7 @@ use super::{MessageKind, ParsedMessage};
/// The wire format's version, the first byte of every payload. Bump it with every change
/// to a message type or a codec (`golden_bytes` fails then).
-pub(crate) const VERSION: u8 = 4;
+pub(crate) const VERSION: u8 = 5;
/// What the second byte of a payload says.
fn tag(kind: MessageKind) -> u8 {
@@ -25,6 +25,8 @@ fn tag(kind: MessageKind) -> u8 {
MessageKind::Ping => 3,
MessageKind::Pong => 4,
MessageKind::Blob => 5,
+ MessageKind::Who => 6,
+ MessageKind::Me => 7,
}
}
@@ -57,6 +59,9 @@ pub(crate) fn encode(message: &ParsedMessage) -> Result<Vec<u8>, WireError> {
rmp_serde::encode::write(&mut payload, keepalive)?
}
ParsedMessage::Blob(blob) => rmp_serde::encode::write(&mut payload, blob)?,
+ ParsedMessage::Who(proof) | ParsedMessage::Me(proof) => {
+ rmp_serde::encode::write(&mut payload, proof)?
+ }
}
Ok(payload)
}
@@ -81,6 +86,10 @@ pub(crate) fn decode(payload: &[u8]) -> Result<ParsedMessage, WireError> {
ParsedMessage::Pong(rmp_serde::from_slice(body)?)
} else if is(MessageKind::Blob) {
ParsedMessage::Blob(rmp_serde::from_slice(body)?)
+ } else if is(MessageKind::Who) {
+ ParsedMessage::Who(rmp_serde::from_slice(body)?)
+ } else if is(MessageKind::Me) {
+ ParsedMessage::Me(rmp_serde::from_slice(body)?)
} else {
return Err(WireError::UnknownKind(kind));
})
@@ -125,6 +134,19 @@ pub(crate) mod codec {
}
}
+ /// A 64-byte signature.
+ pub(crate) mod bytes64 {
+ use super::*;
+
+ pub(crate) fn serialize<S: Serializer>(value: &[u8; 64], s: S) -> Result<S::Ok, S::Error> {
+ Bytes::new(value).serialize(s)
+ }
+
+ pub(crate) fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 64], D::Error> {
+ fixed(&ByteBuf::deserialize(d)?, "a signature")
+ }
+ }
+
/// 32-byte hashes.
pub(crate) mod hashes32 {
use super::*;
@@ -299,8 +321,8 @@ mod tests {
use super::*;
use crate::document::replica::Epoch;
use crate::transport::{
- BlobBody, BlobId, BlobMessage, HeadsSummary, HelloReply, HelloRequest, Keepalive,
- ListedPeer, MAX_LISTED_HEADS,
+ BlobBody, BlobId, BlobMessage, HeadsSummary, HelloReply, HelloRequest, IdentityProof,
+ Keepalive, ListedPeer, MAX_LISTED_HEADS,
};
use automerge::ChangeHash;
@@ -447,7 +469,7 @@ mod tests {
});
assert_eq!(
hex(&encode(&hello).unwrap()),
- format!("040097a5737761726d{epoch_hex}01c403010203c3{}07", run("04"))
+ format!("050097a5737761726d{epoch_hex}01c403010203c3{}07", run("04"))
);
let reply = ParsedMessage::HelloReply(HelloReply {
@@ -467,7 +489,7 @@ mod tests {
assert_eq!(
hex(&encode(&reply).unwrap()),
format!(
- "040199a5737761726d9192a17091a161{epoch_hex}01c400c2{}05{}",
+ "050199a5737761726d9192a17091a161{epoch_hex}01c400c2{}05{}",
run("04"),
run("06")
)
@@ -482,7 +504,27 @@ mod tests {
});
assert_eq!(
hex(&encode(&ping).unwrap()),
- format!("0403959290c400{epoch_hex}01c3c2")
+ format!("0503959290c400{epoch_hex}01c3c2")
);
+
+ let who = ParsedMessage::Who(IdentityProof {
+ key: [8; 32],
+ signature: [9; 64],
+ });
+ assert_eq!(
+ hex(&encode(&who).unwrap()),
+ format!("050692c420{}c440{}", "08".repeat(32), "09".repeat(64))
+ );
+ let ParsedMessage::Me(proof) = decode(
+ &encode(&ParsedMessage::Me(IdentityProof {
+ key: [8; 32],
+ signature: [9; 64],
+ }))
+ .unwrap(),
+ )
+ .unwrap() else {
+ panic!("not a ME");
+ };
+ assert_eq!((proof.key, proof.signature), ([8; 32], [9; 64]));
}
}