Skip to content

Commit

Permalink
adds {CrdsValue,Protocol}::bincode_serialized_size (#3609)
Browse files Browse the repository at this point in the history
Reworking gossip CrdsValue and Protocol bincode serialization.
  • Loading branch information
behzadnouri authored Nov 18, 2024
1 parent e3954be commit 7fbaa56
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 31 deletions.
7 changes: 2 additions & 5 deletions gossip/src/crds_gossip_pull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,7 @@ pub(crate) fn get_max_bloom_filter_bytes(caller: &CrdsValue) -> usize {
let size_of_filter = PACKET_DATA_SIZE
.checked_sub(
// 4 bytes for u32 enum variant identifier of Protocol.
4 + bincode::serialized_size(caller)
.map(usize::try_from)
.unwrap()
.unwrap(),
4 + caller.bincode_serialized_size(),
)
.unwrap();
MAX_BYTES_CACHE
Expand Down Expand Up @@ -1456,7 +1453,7 @@ pub(crate) mod tests {
let packet_data_size_range = (PACKET_DATA_SIZE - 5)..=PACKET_DATA_SIZE;
let max_bytes = get_max_bloom_filter_bytes(caller);
let filters = CrdsFilterSet::new(rng, num_items, max_bytes);
let request_bytes = bincode::serialized_size(caller).unwrap();
let request_bytes = caller.bincode_serialized_size() as u64;
for filter in Vec::<CrdsFilter>::from(filters) {
let request_bytes = 4 + request_bytes + bincode::serialized_size(&filter).unwrap();
let request = Protocol::PullRequest(filter, caller.clone());
Expand Down
10 changes: 6 additions & 4 deletions gossip/src/crds_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,12 @@ impl CrdsValue {
Some(epoch_slots)
}

/// Returns the size (in bytes) of a CrdsValue
#[cfg(test)]
pub(crate) fn size(&self) -> u64 {
bincode::serialized_size(&self).expect("unable to serialize contact info")
/// Returns the bincode serialized size (in bytes) of the CrdsValue.
pub fn bincode_serialized_size(&self) -> usize {
bincode::serialized_size(&self)
.map(usize::try_from)
.unwrap()
.unwrap()
}

/// Returns true if, regardless of prunes, this crds-value
Expand Down
44 changes: 25 additions & 19 deletions gossip/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ pub(crate) struct PruneData {
}

impl Protocol {
/// Returns the bincode serialized size (in bytes) of the Protocol.
#[cfg(test)]
fn bincode_serialized_size(&self) -> usize {
bincode::serialized_size(self)
.map(usize::try_from)
.unwrap()
.unwrap()
}

pub(crate) fn par_verify(self, stats: &GossipStats) -> Option<Self> {
match self {
Protocol::PullRequest(_, ref caller) => {
Expand Down Expand Up @@ -459,7 +468,7 @@ pub(crate) mod tests {
let header = Protocol::PushMessage(Pubkey::default(), Vec::default());
assert_eq!(
PUSH_MESSAGE_MAX_PAYLOAD_SIZE,
PACKET_DATA_SIZE - bincode::serialized_size(&header).unwrap() as usize
PACKET_DATA_SIZE - header.bincode_serialized_size()
);
}

Expand Down Expand Up @@ -499,9 +508,9 @@ pub(crate) mod tests {
let data = CrdsData::DuplicateShred(MAX_DUPLICATE_SHREDS - 1, chunk);
let value = CrdsValue::new(data, &keypair);
let pull_response = Protocol::PullResponse(keypair.pubkey(), vec![value.clone()]);
assert!(bincode::serialized_size(&pull_response).unwrap() < PACKET_DATA_SIZE as u64);
assert!(pull_response.bincode_serialized_size() < PACKET_DATA_SIZE);
let push_message = Protocol::PushMessage(keypair.pubkey(), vec![value.clone()]);
assert!(bincode::serialized_size(&push_message).unwrap() < PACKET_DATA_SIZE as u64);
assert!(push_message.bincode_serialized_size() < PACKET_DATA_SIZE);
}
}

Expand All @@ -511,9 +520,9 @@ pub(crate) mod tests {
for _ in 0..100 {
let crds_values = vec![CrdsValue::new_rand(&mut rng, None)];
let pull_response = Protocol::PullResponse(Pubkey::new_unique(), crds_values);
let size = bincode::serialized_size(&pull_response).unwrap();
let size = pull_response.bincode_serialized_size();
assert!(
PULL_RESPONSE_MIN_SERIALIZED_SIZE as u64 <= size,
PULL_RESPONSE_MIN_SERIALIZED_SIZE <= size,
"pull-response serialized size: {size}"
);
}
Expand Down Expand Up @@ -559,13 +568,13 @@ pub(crate) mod tests {
let header_size = PACKET_DATA_SIZE - PUSH_MESSAGE_MAX_PAYLOAD_SIZE;
for values in splits {
// Assert that sum of parts equals the whole.
let size: u64 = header_size as u64
let size = header_size
+ values
.iter()
.map(|v| bincode::serialized_size(v).unwrap())
.sum::<u64>();
.map(CrdsValue::bincode_serialized_size)
.sum::<usize>();
let message = Protocol::PushMessage(self_pubkey, values);
assert_eq!(bincode::serialized_size(&message).unwrap(), size);
assert_eq!(message.bincode_serialized_size(), size);
// Assert that the message fits into a packet.
assert!(Packet::from_data(Some(&socket), message).is_ok());
}
Expand All @@ -582,7 +591,7 @@ pub(crate) mod tests {
}));

let mut i = 0;
while value.size() < PUSH_MESSAGE_MAX_PAYLOAD_SIZE as u64 {
while value.bincode_serialized_size() < PUSH_MESSAGE_MAX_PAYLOAD_SIZE {
value = CrdsValue::new_unsigned(CrdsData::AccountsHashes(AccountsHashes {
from: Pubkey::default(),
hashes: vec![(0, Hash::default()); i],
Expand All @@ -596,18 +605,15 @@ pub(crate) mod tests {
}

fn test_split_messages(value: CrdsValue) {
const NUM_VALUES: u64 = 30;
let value_size = value.size();
let num_values_per_payload = (PUSH_MESSAGE_MAX_PAYLOAD_SIZE as u64 / value_size).max(1);
const NUM_VALUES: usize = 30;
let value_size = value.bincode_serialized_size();
let num_values_per_payload = (PUSH_MESSAGE_MAX_PAYLOAD_SIZE / value_size).max(1);

// Expected len is the ceiling of the division
let expected_len = (NUM_VALUES + num_values_per_payload - 1) / num_values_per_payload;
let msgs = vec![value; NUM_VALUES as usize];
let msgs = vec![value; NUM_VALUES];

assert!(
split_gossip_messages(PUSH_MESSAGE_MAX_PAYLOAD_SIZE, msgs).count() as u64
<= expected_len
);
assert!(split_gossip_messages(PUSH_MESSAGE_MAX_PAYLOAD_SIZE, msgs).count() <= expected_len);
}

#[test]
Expand Down Expand Up @@ -662,7 +668,7 @@ pub(crate) mod tests {
)
.unwrap();
let vote = CrdsValue::new(CrdsData::Vote(1, vote), &Keypair::new());
assert!(bincode::serialized_size(&vote).unwrap() <= PUSH_MESSAGE_MAX_PAYLOAD_SIZE as u64);
assert!(vote.bincode_serialized_size() <= PUSH_MESSAGE_MAX_PAYLOAD_SIZE);
}

#[test]
Expand Down
14 changes: 11 additions & 3 deletions gossip/tests/crds_gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,11 @@ fn network_run_push(
let mut num_msgs: usize = 0;
let mut pruned: HashSet<(Pubkey, Pubkey)> = HashSet::new();
for (to, msgs) in push_messages {
bytes += serialized_size(&msgs).unwrap() as usize;
// 8 bytes for encoding the length of the vector.
bytes += 8 + msgs
.iter()
.map(CrdsValue::bincode_serialized_size)
.sum::<usize>();
num_msgs += 1;
let origins: HashSet<_> = network
.get(&to)
Expand Down Expand Up @@ -558,7 +562,7 @@ fn network_run_pull(
.iter()
.map(|f| f.filter.bits.len() as usize / 8)
.sum::<usize>();
bytes += serialized_size(&caller_info).unwrap() as usize;
bytes += caller_info.bincode_serialized_size();
let filters: Vec<_> = filters
.into_iter()
.map(|f| (caller_info.clone(), f))
Expand All @@ -579,7 +583,11 @@ fn network_run_pull(
.collect()
})
.unwrap();
bytes += serialized_size(&rsp).unwrap() as usize;
// 8 bytes for encoding the length of the vector.
bytes += 8 + rsp
.iter()
.map(CrdsValue::bincode_serialized_size)
.sum::<usize>();
msgs += rsp.len();
if let Some(node) = network.get(&from) {
let mut stats = ProcessPullStats::default();
Expand Down

0 comments on commit 7fbaa56

Please sign in to comment.