1use crate::{BytesCursor, Immutable, ImmutableWrap, max_merkle_proof_len};
2
3use super::{
4 Extrinsic, Header,
5 extrinsic::{AssurancesXt, DisputesXt, GuaranteesXt, TicketsXt},
6};
7use codec::{Compact, Decode, Encode, MaxEncodedLen};
8use jam_types::{
9 HeaderHash, MAX_PREIMAGE_LEN, MAX_SEGMENT_SLICE_LEN, SEGMENT_LEN, Slot, VALS_PER_CORE,
10 WorkPackage, WorkPackageHash, max_export_segments, max_exports, max_imports, opaque,
11 segment_len, slot_period_sec,
12};
13use std::{sync::Arc, time::Duration};
14
15pub fn slot_duration() -> Duration {
17 Duration::from_secs(slot_period_sec())
18}
19
20fn max_import_proof_hashes_size() -> u32 {
24 32 * max_merkle_proof_len(max_exports())
25}
26
27pub fn max_import_footprint_in_bundle() -> u32 {
30 SEGMENT_LEN as u32 + max_import_proof_hashes_size()
31}
32
33pub fn max_import_proof_size() -> usize {
35 max_import_proof_hashes_size() as usize + 1
36}
37
38pub fn availability_data_expiration() -> Slot {
40 28 * 24 * 60 * 60 / slot_period_sec() as Slot
41}
42
43pub fn max_bundle_size() -> usize {
45 WorkPackage::max_encoded_len() + max_imports() as usize
53}
54
55pub fn max_block_size() -> usize {
60 Header::max_encoded_len() +
61 TicketsXt::max_encoded_len() +
62 AssurancesXt::max_encoded_len() +
63 GuaranteesXt::max_encoded_len() +
64 DisputesXt::max_encoded_len() +
65 MAX_PREIMAGE_LEN +
66 Compact::<u32>::max_encoded_len() }
68
69pub const SANE_MAX_PACKAGE_SIZE: usize = 200 * 1024;
72
73pub const GUARANTEE_MIN_SIGNATURES: usize = (VALS_PER_CORE * 2).div_ceil(3);
77
78opaque! { pub struct Entropy(pub [u8; 32]); }
80
81pub type ImmutableHeader = Immutable<Header, HeaderHash>;
82
83#[derive(Clone, Debug, Encode, Decode)]
84pub struct Block {
85 pub header: Arc<ImmutableHeader>,
86 pub extrinsic: Arc<Extrinsic>,
87}
88
89pub type TrancheIndex = u8;
91
92pub fn max_segment_vec_bytes() -> u32 {
94 segment_len() as u32 * max_export_segments()
95}
96
97#[derive(Clone, Debug, Eq, PartialEq)]
118pub struct SegmentSliceVec {
119 data: Vec<u8>,
120 slice_len: usize,
121}
122
123impl SegmentSliceVec {
124 pub fn raw(&self) -> &[u8] {
126 &self.data
127 }
128
129 pub fn into_inner(self) -> Vec<u8> {
131 self.data
132 }
133
134 pub fn slice_len(&self) -> usize {
136 self.slice_len
137 }
138
139 pub fn from_bytes(data: Vec<u8>, slice_len: usize) -> Option<Self> {
142 if slice_len == 0 || slice_len > MAX_SEGMENT_SLICE_LEN {
143 return None
144 }
145 if !data.len().is_multiple_of(slice_len) {
146 return None
147 }
148 if data.len() / slice_len > max_export_segments() as usize {
149 return None
150 }
151 Some(Self { data, slice_len })
152 }
153
154 pub fn with_capacity(capacity: usize, slice_len: usize) -> Self {
156 assert!(slice_len > 0 && slice_len <= MAX_SEGMENT_SLICE_LEN);
157 Self { data: Vec::with_capacity(capacity * slice_len), slice_len }
158 }
159
160 pub fn len(&self) -> usize {
162 self.data.len() / self.slice_len
163 }
164
165 pub fn is_empty(&self) -> bool {
167 self.data.is_empty()
168 }
169
170 pub fn push(&mut self, slice: &[u8]) -> Result<(), &'static str> {
173 if slice.len() != self.slice_len {
174 return Err("Slice length does not match segment slice length")
175 }
176 if self.len() == max_export_segments() as usize {
177 return Err("Exceeded maximum segment slice vector size")
178 }
179 self.data.extend_from_slice(slice);
180 Ok(())
181 }
182
183 pub fn push_default(&mut self) -> Result<&mut [u8], &'static str> {
186 if self.len() == max_export_segments() as usize {
187 return Err("Exceeded maximum segment slice vector size")
188 }
189 let len = self.data.len();
190 self.data.resize(len + self.slice_len, 0u8);
191 Ok(&mut self.data[len..])
192 }
193}
194
195impl std::ops::Index<usize> for SegmentSliceVec {
196 type Output = [u8];
197 fn index(&self, index: usize) -> &Self::Output {
198 &self.data[index * self.slice_len..(index + 1) * self.slice_len]
199 }
200}
201
202pub type ImmutableWorkPackage =
203 Immutable<jam_types::WrappedWorkPackage<ImmutableWrap>, WorkPackageHash>;
204
205impl From<&jam_types::WorkPackage> for ImmutableWorkPackage {
206 fn from(package: &jam_types::WorkPackage) -> Self {
207 BytesCursor::from(package.encode())
211 .decode_all()
212 .expect("Should be able to decode result of T::encode()")
213 }
214}
215
216impl From<jam_types::WorkPackage> for ImmutableWorkPackage {
217 fn from(package: jam_types::WorkPackage) -> Self {
218 (&package).into()
219 }
220}