use crate::{BytesCursor, Immutable, ImmutableWrap, max_merkle_proof_len};
use super::{
Extrinsic, Header,
extrinsic::{AssurancesXt, DisputesXt, GuaranteesXt, TicketsXt},
};
use codec::{Compact, Decode, Encode, MaxEncodedLen};
use jam_types::{
HeaderHash, MAX_PREIMAGE_LEN, MAX_SEGMENT_SLICE_LEN, SEGMENT_LEN, Slot, VALS_PER_CORE,
WorkPackage, WorkPackageHash, max_export_segments, max_exports, max_imports, opaque,
segment_len, slot_period_sec,
};
use std::{sync::Arc, time::Duration};
pub fn slot_duration() -> Duration {
Duration::from_secs(slot_period_sec())
}
fn max_import_proof_hashes_size() -> u32 {
32 * max_merkle_proof_len(max_exports())
}
pub fn max_import_footprint_in_bundle() -> u32 {
SEGMENT_LEN as u32 + max_import_proof_hashes_size()
}
pub fn max_import_proof_size() -> usize {
max_import_proof_hashes_size() as usize + 1
}
pub fn availability_data_expiration() -> Slot {
28 * 24 * 60 * 60 / slot_period_sec() as Slot
}
pub fn max_bundle_size() -> usize {
WorkPackage::max_encoded_len() + max_imports() as usize
}
pub fn max_block_size() -> usize {
Header::max_encoded_len() +
TicketsXt::max_encoded_len() +
AssurancesXt::max_encoded_len() +
GuaranteesXt::max_encoded_len() +
DisputesXt::max_encoded_len() +
MAX_PREIMAGE_LEN +
Compact::<u32>::max_encoded_len() }
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]); }
pub type ImmutableHeader = Immutable<Header, HeaderHash>;
#[derive(Clone, Debug, Encode, Decode)]
pub struct Block {
pub header: Arc<ImmutableHeader>,
pub extrinsic: Arc<Extrinsic>,
}
pub type TrancheIndex = u8;
pub fn max_segment_vec_bytes() -> u32 {
segment_len() as u32 * max_export_segments()
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SegmentSliceVec {
data: Vec<u8>,
slice_len: usize,
}
impl SegmentSliceVec {
pub fn raw(&self) -> &[u8] {
&self.data
}
pub fn into_inner(self) -> Vec<u8> {
self.data
}
pub fn slice_len(&self) -> usize {
self.slice_len
}
pub fn from_bytes(data: Vec<u8>, slice_len: usize) -> Option<Self> {
if slice_len == 0 || slice_len > MAX_SEGMENT_SLICE_LEN {
return None
}
if !data.len().is_multiple_of(slice_len) {
return None
}
if data.len() / slice_len > max_export_segments() as usize {
return None
}
Some(Self { data, slice_len })
}
pub fn with_capacity(capacity: usize, slice_len: usize) -> Self {
assert!(slice_len > 0 && slice_len <= MAX_SEGMENT_SLICE_LEN);
Self { data: Vec::with_capacity(capacity * slice_len), slice_len }
}
pub fn len(&self) -> usize {
self.data.len() / self.slice_len
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn push(&mut self, slice: &[u8]) -> Result<(), &'static str> {
if slice.len() != self.slice_len {
return Err("Slice length does not match segment slice length")
}
if self.len() == max_export_segments() as usize {
return Err("Exceeded maximum segment slice vector size")
}
self.data.extend_from_slice(slice);
Ok(())
}
pub fn push_default(&mut self) -> Result<&mut [u8], &'static str> {
if self.len() == max_export_segments() as usize {
return Err("Exceeded maximum segment slice vector size")
}
let len = self.data.len();
self.data.resize(len + self.slice_len, 0u8);
Ok(&mut self.data[len..])
}
}
impl std::ops::Index<usize> for SegmentSliceVec {
type Output = [u8];
fn index(&self, index: usize) -> &Self::Output {
&self.data[index * self.slice_len..(index + 1) * self.slice_len]
}
}
pub type ImmutableWorkPackage =
Immutable<jam_types::WrappedWorkPackage<ImmutableWrap>, WorkPackageHash>;
impl From<&jam_types::WorkPackage> for ImmutableWorkPackage {
fn from(package: &jam_types::WorkPackage) -> Self {
BytesCursor::from(package.encode())
.decode_all()
.expect("Should be able to decode result of T::encode()")
}
}
impl From<jam_types::WorkPackage> for ImmutableWorkPackage {
fn from(package: jam_types::WorkPackage) -> Self {
(&package).into()
}
}