1use super::{Extrinsic, Header};
2use codec::{Decode, Encode, MaxEncodedLen};
3use jam_types::{
4 max_export_segments, max_imports, opaque, segment_len, segment_slice_len, slot_period_sec,
5 Segment, WorkPackage, PROVEN_PER_SEGMENT, VALS_PER_CORE,
6};
7use std::time::Duration;
8
9pub fn slot_duration() -> Duration {
11 Duration::from_secs(slot_period_sec())
12}
13
14pub fn max_import_proof_size() -> usize {
15 (PROVEN_PER_SEGMENT.next_power_of_two().ilog2() +
17 (max_imports() as usize)
18 .div_ceil(PROVEN_PER_SEGMENT)
19 .next_power_of_two()
20 .ilog2()) as usize *
21 32 + 1
22}
23
24pub fn max_bundle_size() -> usize {
26 WorkPackage::max_encoded_len() + max_import_proof_size() * max_imports() as usize
33}
34
35pub const SANE_MAX_PACKAGE_SIZE: usize = 200 * 1024;
38
39pub const GUARANTEE_MIN_SIGNATURES: usize = (VALS_PER_CORE * 2).div_ceil(3);
43
44opaque! { pub struct Entropy(pub [u8; 32]); }
46
47#[derive(Clone, Encode, Decode, Debug)]
48pub struct Block {
49 pub header: Header,
50 pub extrinsic: Extrinsic,
51}
52
53pub type TrancheIndex = u8;
55
56pub fn max_segment_slice_vec_bytes() -> u32 {
58 segment_slice_len() as u32 * max_export_segments()
59}
60
61pub fn max_segment_vec_bytes() -> u32 {
63 segment_len() as u32 * max_export_segments()
64}
65
66#[derive(Clone, Debug, Default, Eq, PartialEq)]
69pub struct SegmentSliceVec(Vec<u8>);
70
71impl SegmentSliceVec {
72 pub fn raw(&self) -> &[u8] {
74 &self.0
75 }
76
77 pub fn into_inner(self) -> Vec<u8> {
79 self.0
80 }
81
82 pub fn from_bytes(data: Vec<u8>) -> Option<Self> {
84 if data.len() > segment_slice_len() * max_export_segments() as usize {
85 return None
86 }
87 if !data.len().is_multiple_of(segment_slice_len()) {
88 return None
89 }
90 Some(Self(data))
91 }
92
93 pub fn with_capacity(capacity: usize) -> Self {
95 Self(Vec::with_capacity(capacity * segment_slice_len()))
96 }
97
98 pub fn len(&self) -> usize {
100 self.0.len() / segment_slice_len()
101 }
102
103 pub fn is_empty(&self) -> bool {
105 self.0.is_empty()
106 }
107
108 pub fn push(&mut self, slice: &[u8]) -> Result<(), &'static str> {
111 if slice.len() != segment_slice_len() {
112 return Err("Slice length does not match segment slice length")
113 }
114 if slice.len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
115 return Err("Exceeded maximum segment slice vector size")
116 }
117 self.0.extend_from_slice(slice);
118 Ok(())
119 }
120
121 pub fn push_default(&mut self) -> Result<&mut [u8], &'static str> {
124 if segment_slice_len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
125 return Err("Exceeded maximum segment slice vector size")
126 }
127 let len = self.0.len();
128 self.0.resize(len + segment_slice_len(), 0u8);
129 Ok(&mut self.0[len..])
130 }
131}
132
133impl std::ops::Index<usize> for SegmentSliceVec {
134 type Output = [u8];
135 fn index(&self, index: usize) -> &Self::Output {
136 &self.0[index * segment_slice_len()..(index + 1) * segment_slice_len()]
137 }
138}
139
140pub type SegmentVec = Vec<Segment>;