use {
crate::shred::{
payload::Payload, CodingShredHeader, DataShredHeader, Error, ShredCommonHeader,
},
solana_clock::Slot,
solana_signature::Signature,
};
pub(super) trait Shred<'a>: Sized {
const SIZE_OF_PAYLOAD: usize;
const SIZE_OF_HEADERS: usize;
type SignedData: AsRef<[u8]>;
fn from_payload<T>(shred: T) -> Result<Self, Error>
where
Payload: From<T>;
fn common_header(&self) -> &ShredCommonHeader;
fn sanitize(&self) -> Result<(), Error>;
fn set_signature(&mut self, signature: Signature);
fn payload(&self) -> &Payload;
fn into_payload(self) -> Payload;
fn erasure_shard_index(&self) -> Result<usize, Error>;
fn erasure_shard(&self) -> Result<&[u8], Error>;
fn signed_data(&'a self) -> Result<Self::SignedData, Error>;
}
pub(super) trait ShredData: for<'a> Shred<'a> {
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: for<'a> Shred<'a> {
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)
}
}