From de560ee34ba0297194cae6ac9a1966e3ef614945 Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 23 Oct 2026 22:25:41 +0200 Subject: bump number of heads in keepalive messages Instead of arbitrarily limiting the number to 16, allow filling keepalive messages as long as they don't cause mycelium to chunk it. --- src/transport/mycelium.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/transport/mycelium.rs') diff --git a/src/transport/mycelium.rs b/src/transport/mycelium.rs index 9d1fb90..2683f82 100644 --- a/src/transport/mycelium.rs +++ b/src/transport/mycelium.rs @@ -973,3 +973,45 @@ pub enum TransportError { status: reqwest::StatusCode, }, } + +#[cfg(test)] +mod tests { + use super::*; + + /// Mycelium splits messages into chunks of this size. + const MYCELIUM_CHUNK: usize = 1300; + + #[test] + fn largest_keepalive_fits_in_one_chunk() { + let keepalive = Keepalive { + heads: HeadsSummary::Heads( + (0..MAX_LISTED_HEADS as u8) + .map(|n| ChangeHash([n; 32])) + .collect(), + ), + epoch: Epoch { + generation: u64::MAX, + id: [0xff; 32], + }, + ready: true, + syncs_with_you: true, + }; + let payload = keepalive_to_bytes(&keepalive).unwrap(); + // Mycelium's message data: a length byte, the topic, then our payload. + let size = 1 + TOPIC_PONG.len().max(TOPIC_PING.len()) + payload.len(); + assert!( + size + 50 <= MYCELIUM_CHUNK, + "keepalive with {MAX_LISTED_HEADS} heads takes {size} bytes" + ); + assert_eq!(bytes_to_keepalive(&payload).unwrap().heads, keepalive.heads); + } + + #[test] + fn listed_heads_equal_their_digest() { + let heads: Vec<_> = (0..3u8).map(|n| ChangeHash([n; 32])).collect(); + let listed = HeadsSummary::of(heads.clone()); + let digest = HeadsSummary::Digest(listed.digest()); + assert_eq!(listed, digest); + assert_ne!(listed, HeadsSummary::of(heads[..2].to_vec())); + } +} -- cgit v1.3.1