diff --git a/core/src/blocktree.rs b/core/src/blocktree.rs index 70814654ae..5fdef264d2 100644 --- a/core/src/blocktree.rs +++ b/core/src/blocktree.rs @@ -895,14 +895,9 @@ impl Blocktree { }, |v| v, ); - let mut shredder = Shredder::new( - current_slot, - Some(parent_slot), - 0.0, - keypair, - start_index as u32, - ) - .expect("Failed to create entry shredder"); + let mut shredder = + Shredder::new(current_slot, parent_slot, 0.0, keypair, start_index as u32) + .expect("Failed to create entry shredder"); let mut all_shreds = vec![]; // Find all the entries for start_slot for entry in entries { @@ -917,14 +912,9 @@ impl Blocktree { .map(|s| bincode::deserialize(s).unwrap()) .collect(); all_shreds.extend(shreds); - shredder = Shredder::new( - current_slot, - Some(parent_slot), - 0.0, - &Arc::new(Keypair::new()), - 0, - ) - .expect("Failed to create entry shredder"); + shredder = + Shredder::new(current_slot, parent_slot, 0.0, &Arc::new(Keypair::new()), 0) + .expect("Failed to create entry shredder"); } if entry.borrow().is_tick() { @@ -1654,7 +1644,7 @@ pub fn create_new_ledger(ledger_path: &Path, genesis_block: &GenesisBlock) -> Re let blocktree = Blocktree::open(ledger_path)?; let entries = crate::entry::create_ticks(ticks_per_slot, genesis_block.hash()); - let mut shredder = Shredder::new(0, Some(0), 0.0, &Arc::new(Keypair::new()), 0) + let mut shredder = Shredder::new(0, 0, 0.0, &Arc::new(Keypair::new()), 0) .expect("Failed to create entry shredder"); let last_hash = entries.last().unwrap().hash; bincode::serialize_into(&mut shredder, &entries) @@ -1728,14 +1718,8 @@ pub fn entries_to_test_shreds( parent_slot: u64, is_full_slot: bool, ) -> Vec { - let mut shredder = Shredder::new( - slot, - Some(parent_slot), - 0.0, - &Arc::new(Keypair::new()), - 0 as u32, - ) - .expect("Failed to create entry shredder"); + let mut shredder = Shredder::new(slot, parent_slot, 0.0, &Arc::new(Keypair::new()), 0 as u32) + .expect("Failed to create entry shredder"); bincode::serialize_into(&mut shredder, &entries) .expect("Expect to write all entries to shreds"); diff --git a/core/src/broadcast_stage/broadcast_utils.rs b/core/src/broadcast_stage/broadcast_utils.rs index 7d0a174e6a..8229d941fa 100644 --- a/core/src/broadcast_stage/broadcast_utils.rs +++ b/core/src/broadcast_stage/broadcast_utils.rs @@ -88,14 +88,9 @@ pub(super) fn entries_to_shreds( .for_each(|(i, entries_tuple)| { let (entries, _): (Vec<_>, Vec<_>) = entries_tuple.into_iter().unzip(); //entries - let mut shredder = Shredder::new( - slot, - Some(parent_slot), - 1.0, - keypair, - latest_shred_index as u32, - ) - .expect("Expected to create a new shredder"); + let mut shredder = + Shredder::new(slot, parent_slot, 1.0, keypair, latest_shred_index as u32) + .expect("Expected to create a new shredder"); bincode::serialize_into(&mut shredder, &entries) .expect("Expect to write all entries to shreds"); diff --git a/core/src/chacha.rs b/core/src/chacha.rs index 0cf4356e6e..91534c72ee 100644 --- a/core/src/chacha.rs +++ b/core/src/chacha.rs @@ -153,7 +153,7 @@ mod tests { hasher.hash(&buf[..size]); // golden needs to be updated if blob stuff changes.... - let golden: Hash = "EdYYuAuDPVY7DLNeCtPWAKipicx2KjsxqD2PZ7oxVmHE" + let golden: Hash = "HVUt3uy4it4NgbGgYiG9C3gnvxDCzkgqwzzSCM9N4sSt" .parse() .unwrap(); diff --git a/core/src/cluster_info.rs b/core/src/cluster_info.rs index c91925bbe9..4c27c74aeb 100644 --- a/core/src/cluster_info.rs +++ b/core/src/cluster_info.rs @@ -1767,7 +1767,7 @@ mod tests { use crate::crds_value::CrdsValueLabel; use crate::repair_service::RepairType; use crate::result::Error; - use crate::shred::{FirstDataShred, Shred}; + use crate::shred::{DataShred, Shred}; use crate::test_tx::test_tx; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -1927,7 +1927,7 @@ mod tests { 0, ); assert!(rv.is_empty()); - let mut shred = Shred::FirstInSlot(FirstDataShred::default()); + let mut shred = Shred::FirstInSlot(DataShred::default()); shred.set_slot(2); shred.set_index(1); diff --git a/core/src/shred.rs b/core/src/shred.rs index 474c7446b9..3f48cc4be9 100644 --- a/core/src/shred.rs +++ b/core/src/shred.rs @@ -14,7 +14,7 @@ use std::{cmp, io}; #[derive(Serialize, Clone, Deserialize, PartialEq, Debug)] pub enum Shred { - FirstInSlot(FirstDataShred), + FirstInSlot(DataShred), FirstInFECSet(DataShred), Data(DataShred), LastInFECSet(DataShred), @@ -25,8 +25,8 @@ pub enum Shred { impl Shred { pub fn slot(&self) -> u64 { match self { - Shred::FirstInSlot(s) => s.header.data_header.common_header.slot, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => s.header.common_header.slot, @@ -36,30 +36,36 @@ impl Shred { pub fn parent(&self) -> u64 { match self { - Shred::FirstInSlot(s) => s.header.data_header.parent, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) - | Shred::LastInSlot(s) => s.header.parent, + | Shred::LastInSlot(s) => { + s.header.common_header.slot - u64::from(s.header.parent_offset) + } Shred::Coding(_) => std::u64::MAX, } } pub fn set_slot(&mut self, slot: u64) { + let parent = self.parent(); match self { - Shred::FirstInSlot(s) => s.header.data_header.common_header.slot = slot, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) - | Shred::LastInSlot(s) => s.header.common_header.slot = slot, + | Shred::LastInSlot(s) => { + s.header.common_header.slot = slot; + s.header.parent_offset = (slot - parent) as u16; + } Shred::Coding(s) => s.header.common_header.slot = slot, }; } pub fn index(&self) -> u32 { match self { - Shred::FirstInSlot(s) => s.header.data_header.common_header.index, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => s.header.common_header.index, @@ -69,8 +75,8 @@ impl Shred { pub fn set_index(&mut self, index: u32) { match self { - Shred::FirstInSlot(s) => s.header.data_header.common_header.index = index, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => s.header.common_header.index = index, @@ -80,8 +86,8 @@ impl Shred { pub fn signature(&self) -> Signature { match self { - Shred::FirstInSlot(s) => s.header.data_header.common_header.signature, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => s.header.common_header.signature, @@ -93,8 +99,8 @@ impl Shred { let mut seed = [0; 32]; let seed_len = seed.len(); let sig = match self { - Shred::FirstInSlot(s) => &s.header.data_header.common_header.signature, - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => &s.header.common_header.signature, @@ -142,17 +148,10 @@ pub struct ShredCommonHeader { pub struct DataShredHeader { _reserved: CodingShredHeader, pub common_header: ShredCommonHeader, - pub parent: u64, + pub parent_offset: u16, pub last_in_slot: u8, } -/// The first data shred also has parent slot value in it -#[derive(Serialize, Clone, Deserialize, Default, PartialEq, Debug)] -pub struct FirstDataShredHeader { - pub data_header: DataShredHeader, - pub parent: u64, -} - /// The coding shred header has FEC information #[derive(Serialize, Clone, Deserialize, Default, PartialEq, Debug)] pub struct CodingShredHeader { @@ -163,12 +162,6 @@ pub struct CodingShredHeader { pub payload: Vec, } -#[derive(Serialize, Clone, Deserialize, PartialEq, Debug)] -pub struct FirstDataShred { - pub header: FirstDataShredHeader, - pub payload: Vec, -} - #[derive(Serialize, Clone, Deserialize, PartialEq, Debug)] pub struct DataShred { pub header: DataShredHeader, @@ -180,18 +173,6 @@ pub struct CodingShred { pub header: CodingShredHeader, } -/// Default shred is sized correctly to meet MTU/Packet size requirements -impl Default for FirstDataShred { - fn default() -> Self { - let size = PACKET_DATA_SIZE - - serialized_size(&Shred::FirstInSlot(Self::empty_shred())).unwrap() as usize; - FirstDataShred { - header: FirstDataShredHeader::default(), - payload: vec![0; size], - } - } -} - /// Default shred is sized correctly to meet MTU/Packet size requirements impl Default for DataShred { fn default() -> Self { @@ -231,30 +212,6 @@ pub trait ShredCommon { fn empty_shred() -> Self; } -impl ShredCommon for FirstDataShred { - fn write_at(&mut self, offset: usize, buf: &[u8]) -> (usize, usize) { - let mut capacity = self.payload.len().saturating_sub(offset); - let slice_len = cmp::min(capacity, buf.len()); - capacity -= slice_len; - if slice_len > 0 { - self.payload[offset..offset + slice_len].copy_from_slice(&buf[..slice_len]); - } - (slice_len, capacity) - } - - fn overhead() -> usize { - (bincode::serialized_size(&Shred::FirstInSlot(Self::empty_shred())).unwrap() - - bincode::serialized_size(&vec![0u8; 0]).unwrap()) as usize - } - - fn empty_shred() -> Self { - FirstDataShred { - header: FirstDataShredHeader::default(), - payload: vec![], - } - } -} - impl ShredCommon for DataShred { fn write_at(&mut self, offset: usize, buf: &[u8]) -> (usize, usize) { let mut capacity = self.payload.len().saturating_sub(offset); @@ -305,8 +262,7 @@ impl ShredCommon for CodingShred { pub struct Shredder { slot: u64, pub index: u32, - pub parent: Option, - parent_slot: u64, + parent_offset: u16, fec_rate: f32, signer: Arc, pub shreds: Vec>, @@ -320,32 +276,20 @@ impl Write for Shredder { .active_shred .take() .or_else(|| { - Some( - self.parent - .take() - .map(|parent| { - self.parent_slot = parent; - // If parent slot is available - if self.index == 0 { - // If index is 0, it's the first shred in slot - Shred::FirstInSlot(self.new_first_shred(parent)) - } else { - // Or, it is the first shred in FEC set - Shred::FirstInFECSet(self.new_data_shred()) - } - }) - .unwrap_or_else(|| - // If parent slot is not provided, and since there's no existing shred, - // assume it's first shred in FEC block - Shred::FirstInFECSet(self.new_data_shred())), - ) + Some(if self.index == 0 { + // If index is 0, it's the first shred in slot + Shred::FirstInSlot(self.new_data_shred()) + } else { + // Else, it is the first shred in FEC set + Shred::FirstInFECSet(self.new_data_shred()) + }) }) .unwrap(); let written = self.active_offset; let (slice_len, capacity) = match current_shred.borrow_mut() { - Shred::FirstInSlot(s) => s.write_at(written, buf), - Shred::FirstInFECSet(s) + Shred::FirstInSlot(s) + | Shred::FirstInFECSet(s) | Shred::Data(s) | Shred::LastInFECSet(s) | Shred::LastInSlot(s) => s.write_at(written, buf), @@ -389,7 +333,7 @@ pub struct DeshredResult { impl Shredder { pub fn new( slot: u64, - parent: Option, + parent: u64, fec_rate: f32, signer: &Arc, index: u32, @@ -402,12 +346,19 @@ impl Shredder { fec_rate ), ))) + } else if slot < parent || slot - parent > u64::from(std::u16::MAX) { + Err(Error::IO(IOError::new( + ErrorKind::Other, + format!( + "Current slot {:?} must be > Parent slot {:?}, but the difference must not be > {:?}", + slot, parent, std::u16::MAX + ), + ))) } else { Ok(Shredder { slot, index, - parent, - parent_slot: 0, + parent_offset: (slot - parent) as u16, fec_rate, signer: signer.clone(), ..Shredder::default() @@ -440,20 +391,10 @@ impl Shredder { let mut data_shred = DataShred::default(); data_shred.header.common_header.slot = self.slot; data_shred.header.common_header.index = self.index; - data_shred.header.parent = self.parent_slot; + data_shred.header.parent_offset = self.parent_offset; data_shred } - /// Create a new data shred that's also first in the slot - fn new_first_shred(&self, parent: u64) -> FirstDataShred { - let mut first_shred = FirstDataShred::default(); - first_shred.header.parent = parent; - first_shred.header.data_header.parent = parent; - first_shred.header.data_header.common_header.slot = self.slot; - first_shred.header.data_header.common_header.index = self.index; - first_shred - } - pub fn new_coding_shred( slot: u64, index: u32, @@ -568,26 +509,24 @@ impl Shredder { first_index: usize, expected_index: usize, present: &mut [bool], - ) -> (Vec>, bool, usize) { - let (index, mut first_shred_in_slot) = Self::get_shred_index(shred, num_data); + ) -> (Vec>, usize) { + let index = Self::get_shred_index(shred, num_data); // The index of current shred must be within the range of shreds that are being // recovered if !(first_index..first_index + num_data + num_coding).contains(&index) { - return (vec![], false, index); + return (vec![], index); } let mut missing_blocks: Vec> = (expected_index..index) .map(|missing| { present[missing.saturating_sub(first_index)] = false; - // If index 0 shred is missing, then first shred in slot will also be recovered - first_shred_in_slot |= missing == 0; Shredder::new_empty_missing_shred(num_data, num_coding, slot, first_index, missing) }) .collect(); let shred_buf = bincode::serialize(shred).unwrap(); missing_blocks.push(shred_buf); - (missing_blocks, first_shred_in_slot, index) + (missing_blocks, index) } fn new_empty_missing_shred( @@ -598,9 +537,9 @@ impl Shredder { missing: usize, ) -> Vec { let missing_shred = if missing == 0 { - let mut data_shred = FirstDataShred::default(); - data_shred.header.data_header.common_header.slot = slot; - data_shred.header.data_header.common_header.index = 0; + let mut data_shred = DataShred::default(); + data_shred.header.common_header.slot = slot; + data_shred.header.common_header.index = missing as u32; Shred::FirstInSlot(data_shred) } else if missing < first_index + num_data { let mut data_shred = DataShred::default(); @@ -642,7 +581,7 @@ impl Shredder { let mut shred_bufs: Vec> = shreds .iter() .flat_map(|shred| { - let (blocks, _first_shred, last_index) = Self::fill_in_missing_shreds( + let (blocks, last_index) = Self::fill_in_missing_shreds( shred, num_data, num_coding, @@ -736,9 +675,8 @@ impl Shredder { /// (lower to higher index, and data shreds before coding shreds) pub fn deshred(shreds: &[Shred]) -> Result, reed_solomon_erasure::Error> { let num_data = shreds.len(); - let (data_shred_bufs, first_shred) = { - let (first_index, first_shred_in_slot) = - Shredder::get_shred_index(shreds.first().unwrap(), num_data); + let data_shred_bufs = { + let first_index = Shredder::get_shred_index(shreds.first().unwrap(), num_data); let last_index = match shreds.last().unwrap() { Shred::LastInFECSet(s) | Shred::LastInSlot(s) => { @@ -755,43 +693,26 @@ impl Shredder { .iter() .map(|shred| bincode::serialize(shred).unwrap()) .collect(); - (shred_bufs, first_shred_in_slot) + shred_bufs }; - Ok(Self::reassemble_payload( - num_data, - data_shred_bufs, - first_shred, - )) + Ok(Self::reassemble_payload(num_data, data_shred_bufs)) } - fn get_shred_index(shred: &Shred, num_data: usize) -> (usize, bool) { - let (first_index, first_shred_in_slot) = match shred { - Shred::FirstInSlot(s) => (s.header.data_header.common_header.index as usize, true), - Shred::FirstInFECSet(s) - | Shred::Data(s) - | Shred::LastInFECSet(s) - | Shred::LastInSlot(s) => (s.header.common_header.index as usize, false), - Shred::Coding(s) => (s.header.common_header.index as usize + num_data, false), - }; - (first_index, first_shred_in_slot) + fn get_shred_index(shred: &Shred, num_data: usize) -> usize { + if let Shred::Coding(_) = shred { + shred.index() as usize + num_data + } else { + shred.index() as usize + } } - fn reassemble_payload( - num_data: usize, - data_shred_bufs: Vec>, - first_shred: bool, - ) -> Vec { + fn reassemble_payload(num_data: usize, data_shred_bufs: Vec>) -> Vec { data_shred_bufs[..num_data] .iter() - .enumerate() - .flat_map(|(i, data)| { - let offset = if i == 0 && first_shred { - bincode::serialized_size(&Shred::FirstInSlot(FirstDataShred::empty_shred())) - .unwrap() - } else { - bincode::serialized_size(&Shred::Data(DataShred::empty_shred())).unwrap() - }; + .flat_map(|data| { + let offset = + bincode::serialized_size(&Shred::Data(DataShred::empty_shred())).unwrap(); data[offset as usize..].iter() }) .cloned() @@ -807,14 +728,22 @@ mod tests { fn test_data_shredder() { let keypair = Arc::new(Keypair::new()); let slot = 0x123456789abcdef0; + + // Test that parent cannot be > current slot + assert_matches!(Shredder::new(slot, slot + 1, 1.001, &keypair, 0), Err(_)); + // Test that slot - parent cannot be > u16 MAX + assert_matches!( + Shredder::new(slot, slot - 1 - 0xffff, 1.001, &keypair, 0), + Err(_) + ); + let mut shredder = - Shredder::new(slot, Some(5), 0.0, &keypair, 0).expect("Failed in creating shredder"); + Shredder::new(slot, slot - 5, 0.0, &keypair, 0).expect("Failed in creating shredder"); assert!(shredder.shreds.is_empty()); assert_eq!(shredder.active_shred, None); assert_eq!(shredder.active_offset, 0); - assert!(FirstDataShred::overhead() < PACKET_DATA_SIZE); assert!(DataShred::overhead() < PACKET_DATA_SIZE); assert!(CodingShred::overhead() < PACKET_DATA_SIZE); @@ -854,6 +783,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::FirstInSlot(_)); assert_eq!(deserialized_shred.index(), 0); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); let seed0 = deserialized_shred.seed(); // Test that same seed is generated for a given shred @@ -880,6 +810,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::LastInFECSet(_)); assert_eq!(deserialized_shred.index(), 1); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); // Test that same seed is NOT generated for two different shreds assert_ne!(seed0, deserialized_shred.seed()); @@ -902,6 +833,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::FirstInFECSet(_)); assert_eq!(deserialized_shred.index(), 2); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); // Test8: Write more data to generate an intermediate data shred @@ -919,6 +851,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::Data(_)); assert_eq!(deserialized_shred.index(), 3); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); // Test9: Write some data to shredder @@ -939,6 +872,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::LastInSlot(_)); assert_eq!(deserialized_shred.index(), 4); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); } @@ -948,7 +882,7 @@ mod tests { let slot = 0x123456789abcdef0; let mut shredder = - Shredder::new(slot, Some(5), 0.0, &keypair, 0).expect("Failed in creating shredder"); + Shredder::new(slot, slot - 5, 0.0, &keypair, 0).expect("Failed in creating shredder"); assert!(shredder.shreds.is_empty()); assert_eq!(shredder.active_shred, None); @@ -972,6 +906,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::FirstInSlot(_)); assert_eq!(deserialized_shred.index(), 0); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); let shred = shredder.shreds.remove(0); @@ -980,10 +915,10 @@ mod tests { assert_matches!(deserialized_shred, Shred::LastInFECSet(_)); assert_eq!(deserialized_shred.index(), 1); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); - // Try shredder when no parent is provided - let mut shredder = Shredder::new(0x123456789abcdef0, None, 0.0, &keypair, 2) + let mut shredder = Shredder::new(0x123456789abcdef0, slot - 5, 0.0, &keypair, 2) .expect("Failed in creating shredder"); assert!(shredder.shreds.is_empty()); @@ -1007,6 +942,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::LastInFECSet(_)); assert_eq!(deserialized_shred.index(), 2); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); } @@ -1016,9 +952,9 @@ mod tests { let slot = 0x123456789abcdef0; // Test that FEC rate cannot be > 1.0 - assert_matches!(Shredder::new(slot, Some(5), 1.001, &keypair, 0), Err(_)); + assert_matches!(Shredder::new(slot, slot - 5, 1.001, &keypair, 0), Err(_)); - let mut shredder = Shredder::new(0x123456789abcdef0, Some(5), 1.0, &keypair, 0) + let mut shredder = Shredder::new(0x123456789abcdef0, slot - 5, 1.0, &keypair, 0) .expect("Failed in creating shredder"); assert!(shredder.shreds.is_empty()); @@ -1044,6 +980,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::FirstInSlot(_)); assert_eq!(deserialized_shred.index(), 0); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); let shred = shredder.shreds.remove(0); @@ -1052,6 +989,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::Data(_)); assert_eq!(deserialized_shred.index(), 1); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); let shred = shredder.shreds.remove(0); @@ -1060,6 +998,7 @@ mod tests { assert_matches!(deserialized_shred, Shred::LastInFECSet(_)); assert_eq!(deserialized_shred.index(), 2); assert_eq!(deserialized_shred.slot(), slot); + assert_eq!(deserialized_shred.parent(), slot - 5); assert!(deserialized_shred.verify(&keypair.pubkey())); let shred = shredder.shreds.remove(0); @@ -1092,7 +1031,7 @@ mod tests { let keypair = Arc::new(Keypair::new()); let slot = 0x123456789abcdef0; let mut shredder = - Shredder::new(slot, Some(5), 1.0, &keypair, 0).expect("Failed in creating shredder"); + Shredder::new(slot, slot - 5, 1.0, &keypair, 0).expect("Failed in creating shredder"); assert!(shredder.shreds.is_empty()); assert_eq!(shredder.active_shred, None); @@ -1183,6 +1122,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 1); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(1, recovered_shred); @@ -1190,6 +1130,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 3); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(3, recovered_shred); @@ -1252,6 +1193,7 @@ mod tests { assert_matches!(recovered_shred, Shred::FirstInSlot(_)); assert_eq!(recovered_shred.index(), 0); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(0, recovered_shred); @@ -1259,6 +1201,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 2); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(2, recovered_shred); @@ -1266,6 +1209,7 @@ mod tests { assert_matches!(recovered_shred, Shred::LastInFECSet(_)); assert_eq!(recovered_shred.index(), 4); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(4, recovered_shred); @@ -1293,7 +1237,7 @@ mod tests { // Test4: Try recovery/reassembly full slot with 3 missing data shreds + 2 coding shreds. Hint: should work let mut shredder = - Shredder::new(slot, Some(5), 1.0, &keypair, 0).expect("Failed in creating shredder"); + Shredder::new(slot, slot - 5, 1.0, &keypair, 0).expect("Failed in creating shredder"); let mut offset = shredder.write(&data).unwrap(); let approx_shred_payload_size = offset; @@ -1343,6 +1287,7 @@ mod tests { assert_matches!(recovered_shred, Shred::FirstInSlot(_)); assert_eq!(recovered_shred.index(), 0); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(0, recovered_shred); @@ -1350,6 +1295,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 2); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(2, recovered_shred); @@ -1357,6 +1303,7 @@ mod tests { assert_matches!(recovered_shred, Shred::LastInSlot(_)); assert_eq!(recovered_shred.index(), 4); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(4, recovered_shred); @@ -1404,7 +1351,7 @@ mod tests { // Test6: Try recovery/reassembly with non zero index full slot with 3 missing data shreds + 2 coding shreds. Hint: should work let mut shredder = - Shredder::new(slot, Some(5), 1.0, &keypair, 25).expect("Failed in creating shredder"); + Shredder::new(slot, slot - 5, 1.0, &keypair, 25).expect("Failed in creating shredder"); let mut offset = shredder.write(&data).unwrap(); let approx_shred_payload_size = offset; @@ -1454,6 +1401,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 25); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(0, recovered_shred); @@ -1461,6 +1409,7 @@ mod tests { assert_matches!(recovered_shred, Shred::Data(_)); assert_eq!(recovered_shred.index(), 27); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(2, recovered_shred); @@ -1468,6 +1417,7 @@ mod tests { assert_matches!(recovered_shred, Shred::LastInSlot(_)); assert_eq!(recovered_shred.index(), 29); assert_eq!(recovered_shred.slot(), slot); + assert_eq!(recovered_shred.parent(), slot - 5); assert!(recovered_shred.verify(&keypair.pubkey())); shreds.insert(4, recovered_shred); diff --git a/core/src/window_service.rs b/core/src/window_service.rs index c32f94749d..4851b1a34a 100644 --- a/core/src/window_service.rs +++ b/core/src/window_service.rs @@ -279,7 +279,7 @@ mod test { fn local_entries_to_shred(entries: Vec, keypair: &Arc) -> Vec { let mut shredder = - Shredder::new(0, Some(0), 0.0, keypair, 0).expect("Failed to create entry shredder"); + Shredder::new(0, 0, 0.0, keypair, 0).expect("Failed to create entry shredder"); bincode::serialize_into(&mut shredder, &entries) .expect("Expect to write all entries to shreds"); shredder.finalize_slot();