diff options
| author | tv <tv@krebsco.de> | 2026-10-26 19:29:59 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-26 19:29:59 +0100 |
| commit | 4bbadf6fdc4733b4c3c5eeb575508b2f9334ebdb (patch) | |
| tree | e79ad53ac99932c94b5bc581b382c919cfc9bb17 /src/transport/wire.rs | |
| parent | 9a165fd06a1b52bb943a84f26adf8dec72056143 (diff) | |
keepalive sends head samples alongside digest
When there are more than 32 heads that can be send in a single keepalive
message, the digest is accompanied by 32 heads, a different window each
time, so after a few keepalives every head has been listed.
Diffstat (limited to 'src/transport/wire.rs')
| -rw-r--r-- | src/transport/wire.rs | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/src/transport/wire.rs b/src/transport/wire.rs index 11d36cf..3c80b11 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 = 1; +pub(crate) const VERSION: u8 = 2; /// What the second byte of a payload says. fn tag(kind: MessageKind) -> u8 { @@ -200,7 +200,10 @@ pub(crate) mod codec { heads.iter().map(|head| Bytes::new(&head.0)).collect(), Bytes::new(&[]), ), - HeadsSummary::Digest(digest) => (Vec::new(), Bytes::new(digest)), + HeadsSummary::Digest { digest, sample } => ( + sample.iter().map(|head| Bytes::new(&head.0)).collect(), + Bytes::new(digest), + ), }; (listed, digest).serialize(s) } @@ -209,21 +212,24 @@ pub(crate) mod codec { d: D, ) -> Result<HeadsSummary, D::Error> { let (listed, digest): (Vec<ByteBuf>, ByteBuf) = Deserialize::deserialize(d)?; - if !digest.is_empty() { - return Ok(HeadsSummary::Digest(fixed(&digest, "a heads digest")?)); - } if listed.len() > MAX_LISTED_HEADS { return Err(D::Error::custom(format!( "more than {MAX_LISTED_HEADS} heads listed" ))); } - listed + let listed = listed .iter() .map(|head| -> Result<ChangeHash, D::Error> { Ok(ChangeHash(fixed(head, "a head")?)) }) - .collect::<Result<Vec<_>, _>>() - .map(HeadsSummary::Heads) + .collect::<Result<Vec<_>, _>>()?; + if digest.is_empty() { + return Ok(HeadsSummary::Heads(listed)); + } + Ok(HeadsSummary::Digest { + digest: fixed(&digest, "a heads digest")?, + sample: listed, + }) } } @@ -317,7 +323,10 @@ mod tests { #[test] fn keepalives_keep_their_kind_and_heads() { let keepalive = Keepalive { - heads: HeadsSummary::Digest([8; 32]), + heads: HeadsSummary::Digest { + digest: [8; 32], + sample: vec![ChangeHash([9; 32])], + }, epoch: Epoch::GENESIS, epoch_seq: 0, ready: true, @@ -328,6 +337,7 @@ mod tests { panic!("not a PONG"); }; assert_eq!(decoded.heads, keepalive.heads); + assert_eq!(decoded.heads.listed(), [ChangeHash([9; 32])]); } #[test] @@ -401,7 +411,7 @@ mod tests { }); assert_eq!( hex(&encode(&hello).unwrap()), - format!("010097a5737761726d{epoch_hex}01c403010203c3{}07", run("04")) + format!("020097a5737761726d{epoch_hex}01c403010203c3{}07", run("04")) ); let reply = ParsedMessage::HelloReply(HelloReply { @@ -418,7 +428,7 @@ mod tests { assert_eq!( hex(&encode(&reply).unwrap()), format!( - "010199a5737761726d91a170{epoch_hex}01c400c2{}05{}", + "020199a5737761726d91a170{epoch_hex}01c400c2{}05{}", run("04"), run("06") ) @@ -433,7 +443,7 @@ mod tests { }); assert_eq!( hex(&encode(&ping).unwrap()), - format!("0103959290c400{epoch_hex}01c3c2") + format!("0203959290c400{epoch_hex}01c3c2") ); } } |
