use super::{Extrinsic, Header};
use codec::{Decode, Encode, MaxEncodedLen};
use jam_types::{
max_export_segments, max_imports, opaque, segment_len, segment_slice_len, slot_period_sec,
Segment, WorkPackage, PROVEN_PER_SEGMENT, VALS_PER_CORE,
};
use std::time::Duration;
pub fn slot_duration() -> Duration {
Duration::from_secs(slot_period_sec())
}
pub fn max_import_proof_size() -> usize {
(PROVEN_PER_SEGMENT.next_power_of_two().ilog2() +
(max_imports() as usize)
.div_ceil(PROVEN_PER_SEGMENT)
.next_power_of_two()
.ilog2()) as usize *
32 + 1
}
pub fn max_bundle_size() -> usize {
WorkPackage::max_encoded_len() + max_import_proof_size() * max_imports() as usize
}
pub const SANE_MAX_PACKAGE_SIZE: usize = 200 * 1024;
pub const GUARANTEE_MIN_SIGNATURES: usize = (VALS_PER_CORE * 2).div_ceil(3);
opaque! { pub struct Entropy(pub [u8; 32]); }
#[derive(Clone, Encode, Decode, Debug)]
pub struct Block {
pub header: Header,
pub extrinsic: Extrinsic,
}
pub type TrancheIndex = u8;
pub fn max_segment_slice_vec_bytes() -> u32 {
segment_slice_len() as u32 * max_export_segments()
}
pub fn max_segment_vec_bytes() -> u32 {
segment_len() as u32 * max_export_segments()
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct SegmentSliceVec(Vec<u8>);
impl SegmentSliceVec {
pub fn raw(&self) -> &[u8] {
&self.0
}
pub fn into_inner(self) -> Vec<u8> {
self.0
}
pub fn from_bytes(data: Vec<u8>) -> Option<Self> {
if data.len() > segment_slice_len() * max_export_segments() as usize {
return None
}
if !data.len().is_multiple_of(segment_slice_len()) {
return None
}
Some(Self(data))
}
pub fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity * segment_slice_len()))
}
pub fn len(&self) -> usize {
self.0.len() / segment_slice_len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn push(&mut self, slice: &[u8]) -> Result<(), &'static str> {
if slice.len() != segment_slice_len() {
return Err("Slice length does not match segment slice length")
}
if slice.len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
return Err("Exceeded maximum segment slice vector size")
}
self.0.extend_from_slice(slice);
Ok(())
}
pub fn push_default(&mut self) -> Result<&mut [u8], &'static str> {
if segment_slice_len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
return Err("Exceeded maximum segment slice vector size")
}
let len = self.0.len();
self.0.resize(len + segment_slice_len(), 0u8);
Ok(&mut self.0[len..])
}
}
impl std::ops::Index<usize> for SegmentSliceVec {
type Output = [u8];
fn index(&self, index: usize) -> &Self::Output {
&self.0[index * segment_slice_len()..(index + 1) * segment_slice_len()]
}
}
pub type SegmentVec = Vec<Segment>;