1use super::{
2 extrinsic::{AssurancesXt, DisputesXt, GuaranteesXt, TicketsXt},
3 Extrinsic, Header,
4};
5use codec::{Compact, Decode, Encode, MaxEncodedLen};
6use jam_types::{
7 max_export_segments, max_imports, opaque, segment_len, segment_slice_len, slot_period_sec,
8 Slot, WorkPackage, MAX_PREIMAGE_LEN, PROVEN_PER_SEGMENT, VALS_PER_CORE,
9};
10use std::{sync::Arc, time::Duration};
11
12pub fn slot_duration() -> Duration {
14 Duration::from_secs(slot_period_sec())
15}
16
17pub fn max_import_proof_size() -> usize {
18 (PROVEN_PER_SEGMENT.next_power_of_two().ilog2() +
20 (max_imports() as usize)
21 .div_ceil(PROVEN_PER_SEGMENT)
22 .next_power_of_two()
23 .ilog2()) as usize *
24 32 + 1
25}
26
27pub fn availability_data_expiration() -> Slot {
29 28 * 24 * 60 * 60 / slot_period_sec() as Slot
30}
31
32pub fn max_bundle_size() -> usize {
34 WorkPackage::max_encoded_len() + max_import_proof_size() * max_imports() as usize
41}
42
43pub fn max_block_size() -> usize {
48 Header::max_encoded_len() +
49 TicketsXt::max_encoded_len() +
50 AssurancesXt::max_encoded_len() +
51 GuaranteesXt::max_encoded_len() +
52 DisputesXt::max_encoded_len() +
53 MAX_PREIMAGE_LEN +
54 Compact::<u32>::max_encoded_len() }
56
57pub const SANE_MAX_PACKAGE_SIZE: usize = 200 * 1024;
60
61pub const GUARANTEE_MIN_SIGNATURES: usize = (VALS_PER_CORE * 2).div_ceil(3);
65
66opaque! { pub struct Entropy(pub [u8; 32]); }
68
69#[derive(Clone, Debug, Encode, Decode)]
70pub struct Block {
71 pub header: Arc<Header>,
72 pub extrinsic: Arc<Extrinsic>,
73}
74
75pub type TrancheIndex = u8;
77
78pub fn max_segment_slice_vec_bytes() -> u32 {
80 segment_slice_len() as u32 * max_export_segments()
81}
82
83pub fn max_segment_vec_bytes() -> u32 {
85 segment_len() as u32 * max_export_segments()
86}
87
88#[derive(Clone, Debug, Default, Eq, PartialEq)]
91pub struct SegmentSliceVec(Vec<u8>);
92
93impl SegmentSliceVec {
94 pub fn raw(&self) -> &[u8] {
96 &self.0
97 }
98
99 pub fn into_inner(self) -> Vec<u8> {
101 self.0
102 }
103
104 pub fn from_bytes(data: Vec<u8>) -> Option<Self> {
106 if data.len() > segment_slice_len() * max_export_segments() as usize {
107 return None
108 }
109 if !data.len().is_multiple_of(segment_slice_len()) {
110 return None
111 }
112 Some(Self(data))
113 }
114
115 pub fn with_capacity(capacity: usize) -> Self {
117 Self(Vec::with_capacity(capacity * segment_slice_len()))
118 }
119
120 pub fn len(&self) -> usize {
122 self.0.len() / segment_slice_len()
123 }
124
125 pub fn is_empty(&self) -> bool {
127 self.0.is_empty()
128 }
129
130 pub fn push(&mut self, slice: &[u8]) -> Result<(), &'static str> {
133 if slice.len() != segment_slice_len() {
134 return Err("Slice length does not match segment slice length")
135 }
136 if slice.len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
137 return Err("Exceeded maximum segment slice vector size")
138 }
139 self.0.extend_from_slice(slice);
140 Ok(())
141 }
142
143 pub fn push_default(&mut self) -> Result<&mut [u8], &'static str> {
146 if segment_slice_len() + self.0.len() > max_segment_slice_vec_bytes() as usize {
147 return Err("Exceeded maximum segment slice vector size")
148 }
149 let len = self.0.len();
150 self.0.resize(len + segment_slice_len(), 0u8);
151 Ok(&mut self.0[len..])
152 }
153}
154
155impl std::ops::Index<usize> for SegmentSliceVec {
156 type Output = [u8];
157 fn index(&self, index: usize) -> &Self::Output {
158 &self.0[index * segment_slice_len()..(index + 1) * segment_slice_len()]
159 }
160}