Cleanup shreds to remove FirstShred data structure (#5789)

* Cleanup shreds to remove FirstShred data structure

* Also reduce size used by parent slot information in shred header

* clippy

* fixes

* fix chacha test
This commit is contained in:
Pankaj Garg 2019-09-04 21:06:47 -07:00 committed by GitHub
parent 7062fe4b47
commit f78b865cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 122 additions and 193 deletions

View File

@ -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<Shred> {
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");

View File

@ -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");

View File

@ -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();

View File

@ -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);

View File

@ -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<u8>,
}
#[derive(Serialize, Clone, Deserialize, PartialEq, Debug)]
pub struct FirstDataShred {
pub header: FirstDataShredHeader,
pub payload: Vec<u8>,
}
#[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<u64>,
parent_slot: u64,
parent_offset: u16,
fec_rate: f32,
signer: Arc<Keypair>,
pub shreds: Vec<Vec<u8>>,
@ -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<u64>,
parent: u64,
fec_rate: f32,
signer: &Arc<Keypair>,
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<Vec<u8>>, bool, usize) {
let (index, mut first_shred_in_slot) = Self::get_shred_index(shred, num_data);
) -> (Vec<Vec<u8>>, 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<Vec<u8>> = (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<u8> {
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<Vec<u8>> = 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<Vec<u8>, 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<Vec<u8>>,
first_shred: bool,
) -> Vec<u8> {
fn reassemble_payload(num_data: usize, data_shred_bufs: Vec<Vec<u8>>) -> Vec<u8> {
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);

View File

@ -279,7 +279,7 @@ mod test {
fn local_entries_to_shred(entries: Vec<Entry>, keypair: &Arc<Keypair>) -> Vec<Shred> {
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();