#![cfg(feature = "internal-testing")]
use bincode::{DefaultOptions, Deserializer, Serializer};
use serde::{Deserialize, Serialize};
use rbsr::RangeAggregate;
use rsos::{Aggregate, Fingerprint};
#[test]
fn wire_format_is_unchanged_by_the_aggregate_collapse() {
const GOLDEN: &[u8] = &[
1, 7, 1, 42, 253, 239, 205, 171, 137, 103, 69, 35, 1, 253, 16, 50, 84, 118, 152, 186, 220,
254, 1, 2, 251, 44, 1,
];
let segment = RangeAggregate::for_testing(
Some(7u32),
Some(42u32),
Aggregate::new(
300,
Fingerprint([0x0123456789abcdef, 0xfedcba9876543210, 1, 2]),
),
);
let mut buf = Vec::new();
segment
.serialize(&mut Serializer::new(&mut buf, DefaultOptions::new()))
.unwrap();
assert_eq!(
buf, GOLDEN,
"RangeAggregate's wire encoding changed — this is a protocol break, not a refactor"
);
let mut deserializer = Deserializer::from_slice(GOLDEN, DefaultOptions::new());
let decoded = RangeAggregate::<u32>::deserialize(&mut deserializer).unwrap();
assert_eq!(decoded, segment);
}
#[test]
fn envelope_pins_the_wire_version_byte() {
use gossip::auth::{Authenticator, ClusterKey, KEY_LEN, TAG_LEN};
use gossip::replay::{Seq, Stamp, REPLAY_HEADER_LEN};
let payload = b"payload";
let disabled = Authenticator::new(None, false).seal(Seq::new(1), Stamp::new(1), payload);
let mut expected_disabled = vec![gossip::auth::WIRE_VERSION];
expected_disabled.extend_from_slice(payload);
assert_eq!(
disabled, expected_disabled,
"unauthenticated envelope's wire-version placement changed — this is a protocol break"
);
let sealed = Authenticator::new(Some(ClusterKey::new([0x42; KEY_LEN])), false).seal(
Seq::new(0x0102030405060708),
Stamp::new(0x1112131415161718),
payload,
);
assert_eq!(
sealed.len(),
TAG_LEN + REPLAY_HEADER_LEN + 1 + payload.len()
);
let (tag, protected) = sealed.split_at(TAG_LEN);
assert_ne!(tag, [0u8; TAG_LEN], "sanity: a real tag was written");
assert_eq!(
&protected[..8],
&0x0102030405060708u64.to_le_bytes(),
"seq must be the first 8 bytes of the protected region, little-endian"
);
assert_eq!(
&protected[8..16],
&0x1112131415161718u64.to_le_bytes(),
"stamp must be the next 8 bytes of the protected region, little-endian"
);
assert_eq!(
protected[16],
gossip::auth::WIRE_VERSION,
"the wire-version byte must sit immediately after the replay header"
);
assert_eq!(
&protected[17..],
payload,
"the payload must immediately follow the wire-version byte"
);
}