jam_types/
simple.rs

1#[allow(unused_imports)]
2use super::Authorizer;
3use crate::{chain_params, opaque, FixedVec};
4use bounded_collections::Get;
5use core::sync::atomic::Ordering::Relaxed;
6use scale::{Decode, Encode};
7
8/// Beginning of the Jam "Common Era" (1200 UTC on January 1, 2025),
9/// as seconds after the Unix epoch.
10pub const JAM_COMMON_ERA: u64 = 1_735_732_800;
11
12/// Length of a transfer memo in bytes.
13pub const MEMO_LEN: usize = 128;
14
15#[cfg(not(feature = "tiny"))]
16mod defaults {
17	use super::ValIndex;
18	pub(super) const VAL_COUNT: ValIndex = 1023;
19	pub(super) const BASIC_PIECE_LEN: usize = 684;
20}
21
22#[cfg(feature = "tiny")]
23mod defaults {
24	use super::ValIndex;
25	pub(super) const VAL_COUNT: ValIndex = 6;
26	pub(super) const BASIC_PIECE_LEN: usize = 4;
27}
28
29chain_params! {
30	/// Total number of validators in the JAM.
31	static VAL_COUNT: _ = _(defaults::VAL_COUNT);
32	pub fn val_count() -> ValIndex;
33	pub struct ValCount; impl Get<_> for _ {}
34
35	/// Number of bytes in a basic EC piece.
36	static BASIC_PIECE_LEN: _ = _(defaults::BASIC_PIECE_LEN);
37	pub fn basic_piece_len() -> usize;
38
39	/// Number of authorizations in a queue allocated to a core.
40	static AUTH_QUEUE_LEN: _ = _(80);
41	pub fn auth_queue_len() -> usize;
42	pub struct AuthQueueLen; impl Get<_> for _ {}
43
44	/// Minimum period in blocks between going from becoming `Available` to `Zombie`, and then
45	/// again from `Zombie` to non-existent.
46	///
47	/// This ensures firstly that any data added and referenced in a Work Report's lookup anchor
48	/// block will remain on-chain right up until the latest possible time a dispute might
49	/// conclude. Secondly, it ensure that we only need to record one "flip-flop" of the data's
50	/// availability in order to be able to determine whether it's available or not at any block
51	/// within this period.
52	static MIN_TURNAROUND_PERIOD: _ = _(28_800);
53	pub fn min_turnaround_period() -> Slot;
54
55	/// Maximum number of Work Items in a Work Package.
56	static MAX_WORK_ITEMS: _ = _(16);
57	pub fn max_work_items() -> usize;
58	pub struct MaxWorkItems; impl Get<_> for _ {}
59
60	/// Maximum number of imports in a Work Package.
61	static MAX_IMPORTS: _ = _(3072);
62	pub fn max_imports() -> u32;
63	pub struct MaxImports; impl Get<_> for _ {}
64
65	/// Maximum number of exports in a Work Package.
66	static MAX_EXPORTS: _ = _(3072);
67	pub fn max_exports() -> u32;
68
69	/// Maximum number of extrinsics in a Work Package.
70	static MAX_EXTRINSICS: _ = _(128);
71	pub fn max_extrinsics() -> u32;
72
73	/// Maximum number of dependencies (total of prerequisites and SR lookup entries).
74	static MAX_DEPENDENCIES: _ = _(8);
75	pub fn max_dependencies() -> usize;
76
77	/// Maximum size of a Work Package together with all extrinsic data and imported segments.
78	static MAX_INPUT: _ = _(12 * 1024 * 1024);
79	pub fn max_input() -> u32;
80
81	/// Returns the number of bytes in a segment slice.
82	pub fn segment_slice_len() -> usize {
83		segment_len() / basic_piece_points()
84	}
85	pub struct SegmentSliceLen; impl Get<_> for _ {}
86
87	/// Number of bytes in a segment. This is fixed.
88	pub const SEGMENT_LEN: _ = 4104;
89	pub fn segment_len() -> usize;
90	pub struct SegmentLen; impl Get<_> for _ {}
91}
92
93/// Number of points in a piece.
94pub fn basic_piece_points() -> usize {
95	basic_piece_len() / POINT_LEN
96}
97
98/// Returns the number of pieces in a segment.
99pub fn pieces_per_segment() -> usize {
100	SEGMENT_LEN / basic_piece_len()
101}
102
103/// Baseline parameters for the JAM protocol.
104#[derive(Copy, Clone, Eq, PartialEq, Debug, Encode, Decode)]
105pub struct Parameters {
106	/// Total number of validators in the JAM. Must be divisible by guarantor group size (3).
107	pub val_count: ValIndex,
108	/// Number of octets in a basic piece. Must be even and divide into segment length (4,104).
109	pub basic_piece_len: u32,
110	/// Number of authorizations in a queue allocated to a core.
111	pub auth_queue_len: u32,
112	/// Minimum period in blocks between going from becoming `Available` to `Zombie`, and then
113	/// again from `Zombie` to non-existent.
114	pub min_turnaround_period: Slot,
115	/// Maximum number of Work Items in a Work Package.
116	pub max_work_items: u32,
117	/// Maximum number of imports in a Work Package.
118	pub max_imports: u32,
119	/// Maximum number of exports in a Work Package.
120	pub max_exports: u32,
121	/// Maximum number of extrinsics in a Work Package.
122	pub max_extrinsics: u32,
123	/// Maximum number of dependencies (total of prerequisites and SR lookup entries).
124	pub max_dependencies: u32,
125	/// Maximum size of a Work Package together with all extrinsic data and imported segments.
126	pub max_input: u32,
127}
128
129impl Parameters {
130	pub fn get() -> Self {
131		Self {
132			val_count: val_count(),
133			basic_piece_len: basic_piece_len() as u32,
134			auth_queue_len: auth_queue_len() as u32,
135			min_turnaround_period: min_turnaround_period(),
136			max_work_items: max_work_items() as u32,
137			max_imports: max_imports(),
138			max_exports: max_exports(),
139			max_extrinsics: max_extrinsics(),
140			max_dependencies: max_dependencies() as u32,
141			max_input: max_input(),
142		}
143	}
144	pub fn validate(self) -> Result<(), &'static str> {
145		if self.basic_piece_len % 2 != 0 {
146			return Err("`basic_piece_len` is not even")
147		}
148		if SEGMENT_LEN % (self.basic_piece_len as usize) != 0 {
149			return Err("`basic_piece_len` does not divide into `SEGMENT_LEN` (4,104)")
150		}
151		Ok(())
152	}
153	pub fn apply(self) -> Result<(), &'static str> {
154		self.validate()?;
155		VAL_COUNT.store(self.val_count, Relaxed);
156		BASIC_PIECE_LEN.store(self.basic_piece_len as usize, Relaxed);
157		AUTH_QUEUE_LEN.store(self.auth_queue_len as usize, Relaxed);
158		MIN_TURNAROUND_PERIOD.store(self.min_turnaround_period, Relaxed);
159		MAX_WORK_ITEMS.store(self.max_work_items as usize, Relaxed);
160		MAX_IMPORTS.store(self.max_imports, Relaxed);
161		MAX_EXPORTS.store(self.max_exports, Relaxed);
162		MAX_EXTRINSICS.store(self.max_extrinsics, Relaxed);
163		MAX_DEPENDENCIES.store(self.max_dependencies as usize, Relaxed);
164		MAX_INPUT.store(self.max_input, Relaxed);
165		Ok(())
166	}
167}
168
169/// Number of bytes in an erasure-coding point.
170pub const POINT_LEN: usize = 2;
171
172/// Validators super-majority.
173#[doc(hidden)]
174#[derive(Copy, Clone, Eq, PartialEq, Default, Debug)]
175pub struct ValSuperMajority;
176impl Get<u32> for ValSuperMajority {
177	fn get() -> u32 {
178		val_count() as u32 / 3 * 2 + 1
179	}
180}
181
182/// Type that represents a time slot of six seconds.
183///
184/// This can be either in a relative sense or as a period which has elapsed from the Polkadot
185/// Common Era, beginning 1200 UTC, 1 January 2025.
186pub type Slot = u32;
187/// Type to represent the index of a validator.
188pub type ValIndex = u16;
189/// Type to represent the index of a compute core.
190pub type CoreIndex = u16;
191/// Type to represent the index of a service.
192pub type ServiceId = u32;
193/// Type to represent a balance.
194pub type Balance = u64;
195/// Type which is double the length of Balance, for non-overflowing multiplies.
196#[doc(hidden)]
197pub type DoubleBalance = u128;
198/// Type to represent some gas which may be below zero. This is used primarily for the `invoke`
199/// hostcall API which must be able to return a negative gas amount in case of a gas overrun.
200pub type SignedGas = i64;
201/// Type to represent some gas which must be at least zero.
202pub type UnsignedGas = u64;
203/// Type which is double the length of Gas, for non-overflowing multiplies.
204#[doc(hidden)]
205pub type DoubleGas = u128;
206
207/// A basic 256-bit data value.
208///
209/// This should generally not be used directly in the rich data types, but instead one of the
210/// rich opaque hash types to avoid accidental misuse and provide pretty-print facilities.
211pub type Hash = [u8; 32];
212
213opaque! {
214	/// Hash of an encoded block header.
215	pub struct HeaderHash(pub [u8; 32]);
216
217	/// Hash of PVM program code.
218	pub struct CodeHash(pub [u8; 32]);
219
220	/// Hash of an encoded Work Package.
221	pub struct WorkPackageHash(pub [u8; 32]);
222
223	/// Hash of an encoded Work Report.
224	#[doc(hidden)]
225	pub struct WorkReportHash(pub [u8; 32]);
226
227	/// Hash of a Work Item's [WorkPayload].
228	pub struct PayloadHash(pub [u8; 32]);
229
230	/// Hash of the JAM state root.
231	#[doc(hidden)]
232	pub struct StateRootHash(pub [u8; 32]);
233
234	/// Hash of an MMR peak.
235	#[doc(hidden)]
236	pub struct MmrPeakHash(pub [u8; 32]);
237
238	/// Hash of an accumulation tree root node.
239	#[doc(hidden)]
240	pub struct AccumulateRootHash(pub [u8; 32]);
241
242	/// Hash of a piece of extrinsic data.
243	pub struct ExtrinsicHash(pub [u8; 32]);
244
245	/// Hash of an encoded [Authorizer] value.
246	pub struct AuthorizerHash(pub [u8; 32]);
247
248	/// Hash of a segment tree root node.
249	pub struct SegmentTreeRoot(pub [u8; 32]);
250
251	/// Hash of a [Segment] value.
252	pub struct SegmentHash(pub [u8; 32]);
253
254	/// Hash of a Merkle tree node.
255	#[doc(hidden)]
256	pub struct MerkleNodeHash(pub [u8; 32]);
257
258	/// Non usage-specific hash.
259	///
260	/// This can be useful for pretty-printing [type@Hash] values.
261	#[doc(hidden)]
262	pub struct AnyHash(pub [u8; 32]);
263
264	/// Transfer memo data, included with balance transfers between services.
265	pub struct Memo(pub [u8; MEMO_LEN]);
266
267	/// Data constituting the Authorization Token in a Work Package.
268	pub struct Authorization(pub Vec<u8>);
269
270	/// PVM Program code.
271	#[doc(hidden)]
272	pub struct Code(pub Vec<u8>);
273
274	/// Payload data defining a Work Item.
275	pub struct WorkPayload(pub Vec<u8>);
276
277	/// Authorization parameter.
278	pub struct AuthParam(pub Vec<u8>);
279
280	/// Non usage-specific data.
281	///
282	/// This can be useful for pretty-printing `Vec<u8>` values.
283	#[doc(hidden)]
284	pub struct AnyVec(pub Vec<u8>);
285
286	/// Output data of Refinement operation, passed into Accumulation.
287	pub struct WorkOutput(pub Vec<u8>);
288
289	/// Output data of Is Authorized operation, passed into both Refinement and Accumulation.
290	pub struct AuthOutput(pub Vec<u8>);
291
292	/// A Work Package Bundle, the aggregation of the Work Package, extrinsics, imports and import
293	/// proofs.
294	#[doc(hidden)]
295	pub struct Bundle(pub Vec<u8>);
296
297	/// Plain-old-data struct of the same length as an encoded Ed25519 public key.
298	///
299	/// This has no cryptographic functionality or dependencies.
300	pub struct OpaqueEd25519Public(pub [u8; 32]);
301
302	/// Plain-old-data struct of the same length as an encoded Bandersnatch public key.
303	///
304	/// This has no cryptographic functionality or dependencies.
305	pub struct OpaqueBandersnatchPublic(pub [u8; 32]);
306
307	/// Plain-old-data struct of the same length as an encoded BLS public key.
308	///
309	/// This has no cryptographic functionality or dependencies.
310	pub struct OpaqueBlsPublic(pub [u8; 144]);
311
312	/// Additional information on a validator, opaque to the actual usage.
313	pub struct OpaqueValidatorMetadata(pub [u8; 128]);
314}
315
316/// A queue of [AuthorizerHash]s, each of which will be rotated into the authorizer pool for a core.
317pub type AuthQueue = FixedVec<AuthorizerHash, AuthQueueLen>;
318
319/// A segment of data.
320pub type Segment = FixedVec<u8, SegmentLen>;
321// TODO: ^^^ Measure performance penalty for this not being 4096.