1#[allow(unused_imports)]
2use super::Authorizer;
3use crate::{chain_params, opaque, FixedVec};
4use bounded_collections::{BoundedVec, Get};
5use codec::{Decode, Encode, MaxEncodedLen};
6use core::sync::atomic::Ordering::Relaxed;
7
8pub const GP_VERSION: &str = "0.7.1";
10
11pub const JAM_COMMON_ERA: u64 = 1_735_732_800;
14
15pub const MEMO_LEN: usize = 128;
17
18#[doc(hidden)]
20pub const MAX_PREIMAGE_LEN: usize = 4 * 1024 * 1024;
22
23#[doc(hidden)]
28pub const MAX_PREIMAGE_BLOB_LEN: usize = MAX_PREIMAGE_LEN - 8;
29
30pub const PAGE_SIZE: u32 = 4096;
32
33pub const SUFFIX_SKIP_LEN: usize = 6;
36
37pub const PROVEN_PER_SEGMENT: usize = 1 << SUFFIX_SKIP_LEN;
45
46pub type TicketAttempt = u8;
48
49const DEFAULT_PARAMS: ProtocolParameters = ProtocolParameters::full();
50
51chain_params! {
52 static VAL_COUNT: _ = _(DEFAULT_PARAMS.val_count);
54 pub fn val_count() -> ValIndex;
55 pub struct ValCount; impl Get<_> for _ {}
56
57 static BASIC_PIECE_LEN: _ = _(DEFAULT_PARAMS.basic_piece_len as _);
59 pub fn basic_piece_len() -> usize;
60
61 static SEGMENT_PIECE_COUNT: _ = _(DEFAULT_PARAMS.segment_piece_count as _);
63 pub fn segment_piece_count() -> usize;
64
65 static AUTH_QUEUE_LEN: _ = _(DEFAULT_PARAMS.auth_queue_len as _);
67 pub fn auth_queue_len() -> usize;
68 pub struct AuthQueueLen; impl Get<_> for _ {}
69
70 static MIN_TURNAROUND_PERIOD: _ = _(DEFAULT_PARAMS.min_turnaround_period);
79 pub fn min_turnaround_period() -> Slot;
80
81 static MAX_WORK_ITEMS: _ = _(DEFAULT_PARAMS.max_work_items as _);
83 pub fn max_work_items() -> usize;
84 pub struct MaxWorkItems; impl Get<_> for _ {}
85
86 static MAX_IMPORTS: _ = _(DEFAULT_PARAMS.max_imports);
88 pub fn max_imports() -> u32;
89 pub struct MaxImports; impl Get<_> for _ {}
90
91 static MAX_EXPORTS: _ = _(DEFAULT_PARAMS.max_exports);
93 pub fn max_exports() -> u32;
94
95 static MAX_EXTRINSICS: _ = _(DEFAULT_PARAMS.max_extrinsics as _);
97 pub fn max_extrinsics() -> u32;
98 pub struct MaxExtrinsics; impl Get<_> for _ {}
99
100 static MAX_DEPENDENCIES: _ = _(DEFAULT_PARAMS.max_dependencies as _);
102 pub fn max_dependencies() -> usize;
103 pub struct MaxDependencies; impl Get<_> for _ {}
104
105 static MAX_INPUT: _ = _(DEFAULT_PARAMS.max_input);
107 pub fn max_input() -> u32;
108 pub struct MaxInput; impl Get<_> for _ {}
109
110 pub fn segment_slice_len() -> usize {
112 segment_len() / basic_piece_points()
113 }
114 pub struct SegmentSliceLen; impl Get<_> for _ {}
115
116 pub const SEGMENT_LEN: _ = (DEFAULT_PARAMS.basic_piece_len * DEFAULT_PARAMS.segment_piece_count) as usize;
118 pub fn segment_len() -> usize;
119 pub struct SegmentLen; impl Get<_> for _ {}
120
121 static SLOT_PERIOD_SEC : _ = _(DEFAULT_PARAMS.slot_period_sec as _);
123 pub fn slot_period_sec() -> u64;
124
125 static ROTATION_PERIOD: _ = _(DEFAULT_PARAMS.rotation_period as _);
127 pub fn rotation_period() -> Slot;
128
129 static EPOCH_PERIOD: _ = _(DEFAULT_PARAMS.epoch_period);
131 pub fn epoch_period() -> Slot;
132 pub struct EpochPeriod; impl Get<_> for _ {}
133
134 static EPOCH_TAIL_START: _ = _(DEFAULT_PARAMS.epoch_tail_start);
136 pub fn epoch_tail_start() -> Slot;
137
138 static MAX_TICKETS_PER_BLOCK: _ = _(DEFAULT_PARAMS.max_tickets_per_block as _);
140 pub fn max_tickets_per_block() -> usize;
141 pub struct MaxTicketsPerBlock; impl Get<_> for _ {}
142
143 static TICKETS_ATTEMPTS_NUMBER: _ = _(DEFAULT_PARAMS.tickets_attempts_number as _);
150 pub fn tickets_attempts_number() -> TicketAttempt;
151 pub struct TicketsAttemptsNumber; impl Get<_> for _ {}
152
153 static DEPOSIT_PER_ACCOUNT: _ = _(DEFAULT_PARAMS.deposit_per_account);
154 pub fn deposit_per_account() -> Balance;
155
156 static DEPOSIT_PER_ITEM: _ = _(DEFAULT_PARAMS.deposit_per_item);
157 pub fn deposit_per_item() -> Balance;
158
159 static DEPOSIT_PER_BYTE: _ = _(DEFAULT_PARAMS.deposit_per_byte);
160 pub fn deposit_per_byte() -> Balance;
161
162 static BLOCK_GAS_LIMIT: _ = _(DEFAULT_PARAMS.block_gas_limit);
166 pub fn block_gas_limit() -> UnsignedGas;
167
168 static MAX_IS_AUTHORIZED_GAS: _ = _(DEFAULT_PARAMS.max_is_authorized_gas);
170 pub fn max_is_authorized_gas() -> UnsignedGas;
171
172 static MAX_REFINE_GAS: _ = _(DEFAULT_PARAMS.max_refine_gas);
174 pub fn max_refine_gas() -> UnsignedGas;
175
176 static MAX_ACCUMULATE_GAS: _ = _(DEFAULT_PARAMS.max_accumulate_gas);
178 pub fn max_accumulate_gas() -> UnsignedGas;
179
180 static MAX_SERVICE_CODE_SIZE: _ = _(DEFAULT_PARAMS.max_service_code_size as _);
181 pub fn max_service_code_size() -> usize;
182
183 static MAX_AUTHORIZER_CODE_SIZE: _ = _(DEFAULT_PARAMS.max_authorizer_code_size as _);
184 pub fn max_authorizer_code_size() -> usize;
185
186 static RECENT_BLOCK_COUNT: _ = _(DEFAULT_PARAMS.recent_block_count as _);
189 pub fn recent_block_count() -> Slot;
190 pub struct RecentBlockCount; impl Get<_> for _ {}
191
192 pub const VALS_PER_CORE: _ = 3;
194 pub fn _vals_per_core() -> usize;
195 pub struct _ValsPerCore; impl Get<_> for _ {}
196
197 pub fn core_count() -> CoreIndex {
199 (val_count() as usize / VALS_PER_CORE) as CoreIndex
200 }
201 pub struct CoreCount; impl Get<_> for _ {}
202
203 pub fn max_export_segments() -> u32 {
205 max_exports() + max_exports().div_ceil(PROVEN_PER_SEGMENT as u32)
206 }
207 pub struct MaxExportSegments; impl Get<_> for _ {}
208
209 pub fn max_import_segments() -> u32 { max_imports() * 2 }
212 pub struct MaxImportSegments; impl Get<_> for _ {}
213
214 static AVAILABILITY_TIMEOUT: _ = _(DEFAULT_PARAMS.availability_timeout as _);
216 pub fn availability_timeout() -> Slot;
217
218 static AUTH_WINDOW: _ = _(DEFAULT_PARAMS.auth_window as _);
220 pub fn auth_window() -> usize;
221 pub struct AuthWindow; impl Get<_> for _ {}
222
223 static MAX_LOOKUP_ANCHOR_AGE: _ = _(DEFAULT_PARAMS.max_lookup_anchor_age);
225 pub fn max_lookup_anchor_age() -> Slot;
226
227 static MAX_REPORT_ELECTIVE_DATA: _ = _(DEFAULT_PARAMS.max_report_elective_data);
230 pub fn max_report_elective_data() -> u32;
231 pub struct MaxReportElectiveData; impl Get<_> for _ {}
232}
233
234pub fn basic_piece_points() -> usize {
236 basic_piece_len() / POINT_LEN
237}
238
239pub fn pieces_per_segment() -> usize {
241 SEGMENT_LEN / basic_piece_len()
242}
243
244#[derive(Copy, Clone, Eq, PartialEq, Debug, Encode, Decode, MaxEncodedLen)]
246#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
247pub struct ProtocolParameters {
248 pub deposit_per_item: Balance,
250 pub deposit_per_byte: Balance,
253 pub deposit_per_account: Balance,
255 pub core_count: CoreIndex,
257 pub min_turnaround_period: Slot,
259 pub epoch_period: Slot,
261 pub max_accumulate_gas: UnsignedGas,
263 pub max_is_authorized_gas: UnsignedGas,
265 pub max_refine_gas: UnsignedGas,
267 pub block_gas_limit: UnsignedGas,
269 pub recent_block_count: u16,
271 pub max_work_items: u16,
273 pub max_dependencies: u16,
275 pub max_tickets_per_block: u16,
277 pub max_lookup_anchor_age: Slot,
279 pub tickets_attempts_number: u16,
282 pub auth_window: u16,
284 pub slot_period_sec: u16,
286 pub auth_queue_len: u16,
288 pub rotation_period: u16,
290 pub max_extrinsics: u16,
292 pub availability_timeout: u16,
294 pub val_count: ValIndex,
296 pub max_authorizer_code_size: u32,
298 pub max_input: u32,
300 pub max_service_code_size: u32,
302 pub basic_piece_len: u32,
305 pub max_imports: u32,
307 pub segment_piece_count: u32,
309 pub max_report_elective_data: u32,
311 pub transfer_memo_size: u32,
313 pub max_exports: u32,
315 pub epoch_tail_start: Slot,
317}
318
319impl ProtocolParameters {
320 pub const fn full() -> Self {
321 Self {
322 val_count: 1023,
323 core_count: 341,
324 basic_piece_len: 684,
325 auth_queue_len: 80,
326 min_turnaround_period: 19_200,
327 max_work_items: 16,
328 max_imports: 3072,
329 max_exports: 3072,
330 max_extrinsics: 128,
331 max_dependencies: 8,
332 max_input: 13_794_305,
333 slot_period_sec: 6,
334 epoch_period: 600,
335 epoch_tail_start: 500,
336 rotation_period: 10,
337 block_gas_limit: 3_500_000_000,
338 recent_block_count: 8,
339 max_tickets_per_block: 16,
340 tickets_attempts_number: 2,
341 deposit_per_account: 100,
342 deposit_per_item: 10,
343 deposit_per_byte: 1,
344 max_is_authorized_gas: 50_000_000,
345 max_refine_gas: 5_000_000_000,
346 max_accumulate_gas: 10_000_000,
347 max_service_code_size: 4_000_000,
348 max_authorizer_code_size: 64_000,
349 availability_timeout: 5,
350 auth_window: 8,
351 max_lookup_anchor_age: 24 * 600,
352 max_report_elective_data: 48 * 1024,
353 segment_piece_count: 6,
354 transfer_memo_size: 128,
355 }
356 }
357 pub const fn tiny() -> Self {
358 let mut params = Self::full();
359 params.val_count = 6;
360 params.core_count = 2;
361 params.basic_piece_len = 4;
362 params.epoch_period = 12;
363 params.epoch_tail_start = 10;
364 params.rotation_period = 4;
365 params.block_gas_limit = 20_000_000;
366 params.max_tickets_per_block = 3;
367 params.tickets_attempts_number = 3;
368 params.max_refine_gas = 1_000_000_000;
369 params.segment_piece_count = 1026;
370 params.min_turnaround_period = 32;
373 params.max_lookup_anchor_age = 24;
375 params
376 }
377
378 pub fn get() -> Self {
379 Self {
380 deposit_per_item: deposit_per_item(),
381 deposit_per_byte: deposit_per_byte(),
382 deposit_per_account: deposit_per_account(),
383 core_count: core_count(),
384 min_turnaround_period: min_turnaround_period(),
385 epoch_period: epoch_period(),
386 max_accumulate_gas: max_accumulate_gas(),
387 max_is_authorized_gas: max_is_authorized_gas(),
388 max_refine_gas: max_refine_gas(),
389 block_gas_limit: block_gas_limit(),
390 recent_block_count: recent_block_count() as _,
391 max_work_items: max_work_items() as _,
392 max_dependencies: max_dependencies() as _,
393 max_tickets_per_block: max_tickets_per_block() as _,
394 max_lookup_anchor_age: max_lookup_anchor_age(),
395 tickets_attempts_number: tickets_attempts_number() as _,
396 auth_window: auth_window() as _,
397 slot_period_sec: slot_period_sec() as _,
398 auth_queue_len: auth_queue_len() as _,
399 rotation_period: rotation_period() as _,
400 max_extrinsics: max_extrinsics() as _,
401 availability_timeout: availability_timeout() as _,
402 val_count: val_count(),
403 max_authorizer_code_size: max_authorizer_code_size() as _,
404 max_input: max_input(),
405 max_service_code_size: max_service_code_size() as _,
406 basic_piece_len: basic_piece_len() as _,
407 max_imports: max_imports() as _,
408 segment_piece_count: segment_piece_count() as _,
409 max_report_elective_data: max_report_elective_data(),
410 transfer_memo_size: MEMO_LEN as _,
411 max_exports: max_exports(),
412 epoch_tail_start: epoch_tail_start(),
413 }
414 }
415 pub fn validate(&self) -> Result<(), &'static str> {
416 if !self.basic_piece_len.is_multiple_of(2) {
417 return Err("`basic_piece_len` is not even")
418 }
419 if !SEGMENT_LEN.is_multiple_of(self.basic_piece_len as usize) {
420 return Err("`basic_piece_len` does not divide into `SEGMENT_LEN` (4,104)")
421 }
422 if !self.epoch_period.is_multiple_of(self.rotation_period as Slot) {
423 return Err("`rotation_period` does not divide into `epoch_period`")
424 }
425 if self.epoch_tail_start >= self.epoch_period {
426 return Err("`epoch_tail_start` must be less than `epoch_period`")
427 }
428 if !(self.val_count as usize).is_multiple_of(VALS_PER_CORE) {
429 return Err("`val_count` does not divide by `VALS_PER_CORE` (3)")
430 }
431 if self.val_count != self.core_count * VALS_PER_CORE as u16 {
432 return Err("`val_count != core_count * VALS_PER_CORE` (3)")
433 }
434 if self.transfer_memo_size != MEMO_LEN as u32 {
435 return Err("`transfer_memo_size` must be equal tor `MEMO_LEN` (128)")
436 }
437 if recent_block_count() > 255 {
438 return Err("`recent_block_count` may be no larger than `BlockIndex::MAX` (255)")
439 }
440 Ok(())
441 }
442 pub fn apply(self) -> Result<(), &'static str> {
443 self.validate()?;
444 DEPOSIT_PER_ITEM.store(self.deposit_per_item, Relaxed);
445 DEPOSIT_PER_BYTE.store(self.deposit_per_byte, Relaxed);
446 DEPOSIT_PER_ACCOUNT.store(self.deposit_per_account, Relaxed);
447 MIN_TURNAROUND_PERIOD.store(self.min_turnaround_period, Relaxed);
448 EPOCH_PERIOD.store(self.epoch_period, Relaxed);
449 MAX_ACCUMULATE_GAS.store(self.max_accumulate_gas, Relaxed);
450 MAX_IS_AUTHORIZED_GAS.store(self.max_is_authorized_gas, Relaxed);
451 MAX_REFINE_GAS.store(self.max_refine_gas, Relaxed);
452 BLOCK_GAS_LIMIT.store(self.block_gas_limit, Relaxed);
453 RECENT_BLOCK_COUNT.store(self.recent_block_count as _, Relaxed);
454 MAX_WORK_ITEMS.store(self.max_work_items as _, Relaxed);
455 MAX_DEPENDENCIES.store(self.max_dependencies as _, Relaxed);
456 MAX_TICKETS_PER_BLOCK.store(self.max_tickets_per_block as _, Relaxed);
457 MAX_LOOKUP_ANCHOR_AGE.store(self.max_lookup_anchor_age as _, Relaxed);
458 TICKETS_ATTEMPTS_NUMBER.store(self.tickets_attempts_number as _, Relaxed);
459 AUTH_WINDOW.store(self.auth_window as _, Relaxed);
460 SLOT_PERIOD_SEC.store(self.slot_period_sec as _, Relaxed);
461 AUTH_QUEUE_LEN.store(self.auth_queue_len as _, Relaxed);
462 ROTATION_PERIOD.store(self.rotation_period as _, Relaxed);
463 MAX_EXTRINSICS.store(self.max_extrinsics as _, Relaxed);
464 AVAILABILITY_TIMEOUT.store(self.availability_timeout as _, Relaxed);
465 VAL_COUNT.store(self.val_count, Relaxed);
466 MAX_AUTHORIZER_CODE_SIZE.store(self.max_authorizer_code_size as _, Relaxed);
467 MAX_INPUT.store(self.max_input, Relaxed);
468 MAX_SERVICE_CODE_SIZE.store(self.max_service_code_size as _, Relaxed);
469 BASIC_PIECE_LEN.store(self.basic_piece_len as _, Relaxed);
470 MAX_IMPORTS.store(self.max_imports, Relaxed);
471 SEGMENT_PIECE_COUNT.store(self.segment_piece_count as _, Relaxed);
472 MAX_REPORT_ELECTIVE_DATA.store(self.max_report_elective_data, Relaxed);
473 MAX_EXPORTS.store(self.max_exports, Relaxed);
474 EPOCH_TAIL_START.store(self.epoch_tail_start, Relaxed);
475 Ok(())
476 }
477}
478
479pub const POINT_LEN: usize = 2;
481
482#[doc(hidden)]
484#[derive(Copy, Clone, Eq, PartialEq, Default, Debug)]
485pub struct ValSuperMajority;
486impl Get<u32> for ValSuperMajority {
487 fn get() -> u32 {
488 val_count() as u32 / 3 * 2 + 1
489 }
490}
491
492pub type Slot = u32;
497pub type ValIndex = u16;
499pub type CoreIndex = u16;
501pub type ServiceId = u32;
503pub type Balance = u64;
505pub type DoubleBalance = u128;
507pub type SignedGas = i64;
510pub type UnsignedGas = u64;
512pub type DoubleGas = u128;
514
515pub type Hash = [u8; 32];
520
521opaque! {
522 pub struct HeaderHash(pub [u8; 32]);
524
525 pub struct CodeHash(pub [u8; 32]);
527
528 pub struct WorkPackageHash(pub [u8; 32]);
530
531 pub struct WorkReportHash(pub [u8; 32]);
533
534 pub struct PayloadHash(pub [u8; 32]);
536
537 pub struct StateRootHash(pub [u8; 32]);
539
540 pub struct MmrPeakHash(pub [u8; 32]);
542
543 pub struct AccumulateRootHash(pub [u8; 32]);
545
546 pub struct ExtrinsicHash(pub [u8; 32]);
548
549 pub struct AuthorizerHash(pub [u8; 32]);
551
552 pub struct SegmentTreeRoot(pub [u8; 32]);
554
555 pub struct SegmentHash(pub [u8; 32]);
557
558 pub struct MerkleNodeHash(pub [u8; 32]);
560
561 pub struct AnyHash(pub [u8; 32]);
565
566 pub struct Memo(pub [u8; MEMO_LEN]);
568
569 pub struct Authorization(pub Vec<u8>);
571
572 pub struct Code(pub Vec<u8>);
574
575 pub struct WorkPayload(pub Vec<u8>);
577
578 pub struct AuthConfig(pub Vec<u8>);
580
581 pub struct AnyVec(pub Vec<u8>);
585
586 pub struct WrappedSegment(pub FixedVec<u8, SegmentLen>);
590
591 pub struct WorkOutput(pub Vec<u8>);
593
594 pub struct AuthTrace(pub Vec<u8>);
596
597 pub struct OpaqueEd25519Public(pub [u8; 32]);
601
602 pub struct OpaqueBandersnatchPublic(pub [u8; 32]);
606
607 pub struct OpaqueBlsPublic(pub [u8; 144]);
611
612 pub struct OpaqueValidatorMetadata(pub [u8; 128]);
614}
615
616#[cfg(feature = "bytes")]
617opaque! {
618 pub struct AnyBytes(pub Bytes);
622}
623
624pub type AuthQueue = FixedVec<AuthorizerHash, AuthQueueLen>;
626
627pub type Segment = FixedVec<u8, SegmentLen>;
629pub trait ToAny {
632 type Any;
633 fn any(&self) -> Self::Any;
634 fn into_any(self) -> Self::Any;
635}
636
637impl ToAny for [u8; 32] {
638 type Any = AnyHash;
639 fn any(&self) -> Self::Any {
640 AnyHash(*self)
641 }
642 fn into_any(self) -> Self::Any {
643 AnyHash(self)
644 }
645}
646
647impl ToAny for alloc::vec::Vec<u8> {
648 type Any = AnyVec;
649 fn any(&self) -> Self::Any {
650 AnyVec(self.clone())
651 }
652 fn into_any(self) -> Self::Any {
653 AnyVec(self)
654 }
655}
656
657impl ToAny for &[u8] {
658 type Any = AnyVec;
659 fn any(&self) -> Self::Any {
660 AnyVec(self.to_vec())
661 }
662 fn into_any(self) -> Self::Any {
663 AnyVec(self.to_vec())
664 }
665}
666
667impl MaxEncodedLen for Authorization {
668 fn max_encoded_len() -> usize {
669 BoundedVec::<u8, MaxInput>::max_encoded_len()
670 }
671}
672
673impl MaxEncodedLen for WorkPayload {
674 fn max_encoded_len() -> usize {
675 BoundedVec::<u8, MaxInput>::max_encoded_len()
676 }
677}
678
679impl MaxEncodedLen for AuthConfig {
680 fn max_encoded_len() -> usize {
681 BoundedVec::<u8, MaxInput>::max_encoded_len()
682 }
683}
684
685impl MaxEncodedLen for AuthTrace {
686 fn max_encoded_len() -> usize {
687 BoundedVec::<u8, MaxReportElectiveData>::max_encoded_len()
688 }
689}
690
691impl AuthTrace {
692 pub fn leak(self) -> &'static [u8] {
693 self.0.leak()
694 }
695}
696
697impl MaxEncodedLen for WorkOutput {
698 fn max_encoded_len() -> usize {
699 BoundedVec::<u8, MaxReportElectiveData>::max_encoded_len()
700 }
701}
702
703impl WorkOutput {
704 pub fn leak(self) -> &'static [u8] {
705 self.0.leak()
706 }
707}