diff --git a/gossip/src/crds_gossip_pull.rs b/gossip/src/crds_gossip_pull.rs index c0aea32e06dfac..f650d91497fbb5 100644 --- a/gossip/src/crds_gossip_pull.rs +++ b/gossip/src/crds_gossip_pull.rs @@ -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 @@ -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::::from(filters) { let request_bytes = 4 + request_bytes + bincode::serialized_size(&filter).unwrap(); let request = Protocol::PullRequest(filter, caller.clone()); diff --git a/gossip/src/crds_value.rs b/gossip/src/crds_value.rs index 1a5b464e763b17..fb3061d1499f85 100644 --- a/gossip/src/crds_value.rs +++ b/gossip/src/crds_value.rs @@ -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 diff --git a/gossip/src/protocol.rs b/gossip/src/protocol.rs index 053a199c053d12..c169bee4fb15b9 100644 --- a/gossip/src/protocol.rs +++ b/gossip/src/protocol.rs @@ -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 { match self { Protocol::PullRequest(_, ref caller) => { @@ -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() ); } @@ -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); } } @@ -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}" ); } @@ -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::(); + .map(CrdsValue::bincode_serialized_size) + .sum::(); 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()); } @@ -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], @@ -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] @@ -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] diff --git a/gossip/tests/crds_gossip.rs b/gossip/tests/crds_gossip.rs index 22a93e22dee496..eb2c7517f1eac4 100644 --- a/gossip/tests/crds_gossip.rs +++ b/gossip/tests/crds_gossip.rs @@ -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::(); num_msgs += 1; let origins: HashSet<_> = network .get(&to) @@ -558,7 +562,7 @@ fn network_run_pull( .iter() .map(|f| f.filter.bits.len() as usize / 8) .sum::(); - 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)) @@ -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::(); msgs += rsp.len(); if let Some(node) = network.get(&from) { let mut stats = ProcessPullStats::default();