jam_types/
simple.rs

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