use {
crate::shred::{CodingShredHeader, DataShredHeader, Error, ShredCommonHeader},
solana_sdk::{clock::Slot, signature::Signature},
};
pub(super) trait Shred: Sized {
const SIZE_OF_PAYLOAD: usize;
const SIZE_OF_HEADERS: usize;
fn from_payload(shred: Vec<u8>) -> Result<Self, Error>;
fn common_header(&self) -> &ShredCommonHeader;
fn sanitize(&self) -> Result<(), Error>;
fn set_signature(&mut self, signature: Signature);
fn payload(&self) -> &Vec<u8>;
fn into_payload(self) -> Vec<u8>;
fn erasure_shard_index(&self) -> Result<usize, Error>;
fn erasure_shard(self) -> Result<Vec<u8>, Error>;
fn erasure_shard_as_slice(&self) -> Result<&[u8], Error>;
fn signed_message(&self) -> &[u8];
fn set_index(&mut self, index: u32);
fn set_slot(&mut self, slot: Slot);
}
pub(super) trait ShredData: Shred {
fn data_header(&self) -> &DataShredHeader;
fn parent(&self) -> Result<Slot, Error> {
let slot = self.common_header().slot;
let parent_offset = self.data_header().parent_offset;
if parent_offset == 0 && slot != 0 {
return Err(Error::InvalidParentOffset {
slot,
parent_offset,
});
}
slot.checked_sub(Slot::from(parent_offset))
.ok_or(Error::InvalidParentOffset {
slot,
parent_offset,
})
}
fn data(&self) -> Result<&[u8], Error>;
}
pub(super) trait ShredCode: Shred {
fn coding_header(&self) -> &CodingShredHeader;
fn first_coding_index(&self) -> Option<u32> {
let position = u32::from(self.coding_header().position);
self.common_header().index.checked_sub(position)
}
}