#[allow(unused_imports)]
use super::Authorizer;
use crate::{chain_params, opaque, FixedVec};
use bounded_collections::{BoundedVec, Get};
use codec::{Decode, Encode, MaxEncodedLen};
use core::sync::atomic::Ordering::Relaxed;
pub const GP_VERSION: &str = "0.7.1";
pub const JAM_COMMON_ERA: u64 = 1_735_732_800;
pub const MEMO_LEN: usize = 128;
#[doc(hidden)]
pub const MAX_PREIMAGE_LEN: usize = 4 * 1024 * 1024;
#[doc(hidden)]
pub const MAX_PREIMAGE_BLOB_LEN: usize = MAX_PREIMAGE_LEN - 8;
pub const PAGE_SIZE: u32 = 4096;
pub const SUFFIX_SKIP_LEN: usize = 6;
pub const PROVEN_PER_SEGMENT: usize = 1 << SUFFIX_SKIP_LEN;
pub type TicketAttempt = u8;
const DEFAULT_PARAMS: ProtocolParameters = ProtocolParameters::full();
chain_params! {
static VAL_COUNT: _ = _(DEFAULT_PARAMS.val_count);
pub fn val_count() -> ValIndex;
pub struct ValCount; impl Get<_> for _ {}
static BASIC_PIECE_LEN: _ = _(DEFAULT_PARAMS.basic_piece_len as _);
pub fn basic_piece_len() -> usize;
static SEGMENT_PIECE_COUNT: _ = _(DEFAULT_PARAMS.segment_piece_count as _);
pub fn segment_piece_count() -> usize;
static AUTH_QUEUE_LEN: _ = _(DEFAULT_PARAMS.auth_queue_len as _);
pub fn auth_queue_len() -> usize;
pub struct AuthQueueLen; impl Get<_> for _ {}
static MIN_TURNAROUND_PERIOD: _ = _(DEFAULT_PARAMS.min_turnaround_period);
pub fn min_turnaround_period() -> Slot;
static MAX_WORK_ITEMS: _ = _(DEFAULT_PARAMS.max_work_items as _);
pub fn max_work_items() -> usize;
pub struct MaxWorkItems; impl Get<_> for _ {}
static MAX_IMPORTS: _ = _(DEFAULT_PARAMS.max_imports);
pub fn max_imports() -> u32;
pub struct MaxImports; impl Get<_> for _ {}
static MAX_EXPORTS: _ = _(DEFAULT_PARAMS.max_exports);
pub fn max_exports() -> u32;
static MAX_EXTRINSICS: _ = _(DEFAULT_PARAMS.max_extrinsics as _);
pub fn max_extrinsics() -> u32;
pub struct MaxExtrinsics; impl Get<_> for _ {}
static MAX_DEPENDENCIES: _ = _(DEFAULT_PARAMS.max_dependencies as _);
pub fn max_dependencies() -> usize;
pub struct MaxDependencies; impl Get<_> for _ {}
static MAX_INPUT: _ = _(DEFAULT_PARAMS.max_input);
pub fn max_input() -> u32;
pub struct MaxInput; impl Get<_> for _ {}
pub fn segment_slice_len() -> usize {
segment_len() / basic_piece_points()
}
pub struct SegmentSliceLen; impl Get<_> for _ {}
pub const SEGMENT_LEN: _ = (DEFAULT_PARAMS.basic_piece_len * DEFAULT_PARAMS.segment_piece_count) as usize;
pub fn segment_len() -> usize;
pub struct SegmentLen; impl Get<_> for _ {}
static SLOT_PERIOD_SEC : _ = _(DEFAULT_PARAMS.slot_period_sec as _);
pub fn slot_period_sec() -> u64;
static ROTATION_PERIOD: _ = _(DEFAULT_PARAMS.rotation_period as _);
pub fn rotation_period() -> Slot;
static EPOCH_PERIOD: _ = _(DEFAULT_PARAMS.epoch_period);
pub fn epoch_period() -> Slot;
pub struct EpochPeriod; impl Get<_> for _ {}
static EPOCH_TAIL_START: _ = _(DEFAULT_PARAMS.epoch_tail_start);
pub fn epoch_tail_start() -> Slot;
static MAX_TICKETS_PER_BLOCK: _ = _(DEFAULT_PARAMS.max_tickets_per_block as _);
pub fn max_tickets_per_block() -> usize;
pub struct MaxTicketsPerBlock; impl Get<_> for _ {}
static TICKETS_ATTEMPTS_NUMBER: _ = _(DEFAULT_PARAMS.tickets_attempts_number as _);
pub fn tickets_attempts_number() -> TicketAttempt;
pub struct TicketsAttemptsNumber; impl Get<_> for _ {}
static DEPOSIT_PER_ACCOUNT: _ = _(DEFAULT_PARAMS.deposit_per_account);
pub fn deposit_per_account() -> Balance;
static DEPOSIT_PER_ITEM: _ = _(DEFAULT_PARAMS.deposit_per_item);
pub fn deposit_per_item() -> Balance;
static DEPOSIT_PER_BYTE: _ = _(DEFAULT_PARAMS.deposit_per_byte);
pub fn deposit_per_byte() -> Balance;
static BLOCK_GAS_LIMIT: _ = _(DEFAULT_PARAMS.block_gas_limit);
pub fn block_gas_limit() -> UnsignedGas;
static MAX_IS_AUTHORIZED_GAS: _ = _(DEFAULT_PARAMS.max_is_authorized_gas);
pub fn max_is_authorized_gas() -> UnsignedGas;
static MAX_REFINE_GAS: _ = _(DEFAULT_PARAMS.max_refine_gas);
pub fn max_refine_gas() -> UnsignedGas;
static MAX_ACCUMULATE_GAS: _ = _(DEFAULT_PARAMS.max_accumulate_gas);
pub fn max_accumulate_gas() -> UnsignedGas;
static MAX_SERVICE_CODE_SIZE: _ = _(DEFAULT_PARAMS.max_service_code_size as _);
pub fn max_service_code_size() -> usize;
static MAX_AUTHORIZER_CODE_SIZE: _ = _(DEFAULT_PARAMS.max_authorizer_code_size as _);
pub fn max_authorizer_code_size() -> usize;
static RECENT_BLOCK_COUNT: _ = _(DEFAULT_PARAMS.recent_block_count as _);
pub fn recent_block_count() -> Slot;
pub struct RecentBlockCount; impl Get<_> for _ {}
pub const VALS_PER_CORE: _ = 3;
pub fn _vals_per_core() -> usize;
pub struct _ValsPerCore; impl Get<_> for _ {}
pub fn core_count() -> CoreIndex {
(val_count() as usize / VALS_PER_CORE) as CoreIndex
}
pub struct CoreCount; impl Get<_> for _ {}
pub fn max_export_segments() -> u32 {
max_exports() + max_exports().div_ceil(PROVEN_PER_SEGMENT as u32)
}
pub struct MaxExportSegments; impl Get<_> for _ {}
pub fn max_import_segments() -> u32 { max_imports() * 2 }
pub struct MaxImportSegments; impl Get<_> for _ {}
static AVAILABILITY_TIMEOUT: _ = _(DEFAULT_PARAMS.availability_timeout as _);
pub fn availability_timeout() -> Slot;
static AUTH_WINDOW: _ = _(DEFAULT_PARAMS.auth_window as _);
pub fn auth_window() -> usize;
pub struct AuthWindow; impl Get<_> for _ {}
static MAX_LOOKUP_ANCHOR_AGE: _ = _(DEFAULT_PARAMS.max_lookup_anchor_age);
pub fn max_lookup_anchor_age() -> Slot;
static MAX_REPORT_ELECTIVE_DATA: _ = _(DEFAULT_PARAMS.max_report_elective_data);
pub fn max_report_elective_data() -> u32;
pub struct MaxReportElectiveData; impl Get<_> for _ {}
}
pub fn basic_piece_points() -> usize {
basic_piece_len() / POINT_LEN
}
pub fn pieces_per_segment() -> usize {
SEGMENT_LEN / basic_piece_len()
}
#[derive(Copy, Clone, Eq, PartialEq, Debug, Encode, Decode, MaxEncodedLen)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ProtocolParameters {
pub deposit_per_item: Balance,
pub deposit_per_byte: Balance,
pub deposit_per_account: Balance,
pub core_count: CoreIndex,
pub min_turnaround_period: Slot,
pub epoch_period: Slot,
pub max_accumulate_gas: UnsignedGas,
pub max_is_authorized_gas: UnsignedGas,
pub max_refine_gas: UnsignedGas,
pub block_gas_limit: UnsignedGas,
pub recent_block_count: u16,
pub max_work_items: u16,
pub max_dependencies: u16,
pub max_tickets_per_block: u16,
pub max_lookup_anchor_age: Slot,
pub tickets_attempts_number: u16,
pub auth_window: u16,
pub slot_period_sec: u16,
pub auth_queue_len: u16,
pub rotation_period: u16,
pub max_extrinsics: u16,
pub availability_timeout: u16,
pub val_count: ValIndex,
pub max_authorizer_code_size: u32,
pub max_input: u32,
pub max_service_code_size: u32,
pub basic_piece_len: u32,
pub max_imports: u32,
pub segment_piece_count: u32,
pub max_report_elective_data: u32,
pub transfer_memo_size: u32,
pub max_exports: u32,
pub epoch_tail_start: Slot,
}
impl ProtocolParameters {
pub const fn full() -> Self {
Self {
val_count: 1023,
core_count: 341,
basic_piece_len: 684,
auth_queue_len: 80,
min_turnaround_period: 19_200,
max_work_items: 16,
max_imports: 3072,
max_exports: 3072,
max_extrinsics: 128,
max_dependencies: 8,
max_input: 13_794_305,
slot_period_sec: 6,
epoch_period: 600,
epoch_tail_start: 500,
rotation_period: 10,
block_gas_limit: 3_500_000_000,
recent_block_count: 8,
max_tickets_per_block: 16,
tickets_attempts_number: 2,
deposit_per_account: 100,
deposit_per_item: 10,
deposit_per_byte: 1,
max_is_authorized_gas: 50_000_000,
max_refine_gas: 5_000_000_000,
max_accumulate_gas: 10_000_000,
max_service_code_size: 4_000_000,
max_authorizer_code_size: 64_000,
availability_timeout: 5,
auth_window: 8,
max_lookup_anchor_age: 24 * 600,
max_report_elective_data: 48 * 1024,
segment_piece_count: 6,
transfer_memo_size: 128,
}
}
pub const fn tiny() -> Self {
let mut params = Self::full();
params.val_count = 6;
params.core_count = 2;
params.basic_piece_len = 4;
params.epoch_period = 12;
params.epoch_tail_start = 10;
params.rotation_period = 4;
params.block_gas_limit = 20_000_000;
params.max_tickets_per_block = 3;
params.tickets_attempts_number = 3;
params.max_refine_gas = 1_000_000_000;
params.segment_piece_count = 1026;
params.min_turnaround_period = 32;
params.max_lookup_anchor_age = 24;
params
}
pub fn get() -> Self {
Self {
deposit_per_item: deposit_per_item(),
deposit_per_byte: deposit_per_byte(),
deposit_per_account: deposit_per_account(),
core_count: core_count(),
min_turnaround_period: min_turnaround_period(),
epoch_period: epoch_period(),
max_accumulate_gas: max_accumulate_gas(),
max_is_authorized_gas: max_is_authorized_gas(),
max_refine_gas: max_refine_gas(),
block_gas_limit: block_gas_limit(),
recent_block_count: recent_block_count() as _,
max_work_items: max_work_items() as _,
max_dependencies: max_dependencies() as _,
max_tickets_per_block: max_tickets_per_block() as _,
max_lookup_anchor_age: max_lookup_anchor_age(),
tickets_attempts_number: tickets_attempts_number() as _,
auth_window: auth_window() as _,
slot_period_sec: slot_period_sec() as _,
auth_queue_len: auth_queue_len() as _,
rotation_period: rotation_period() as _,
max_extrinsics: max_extrinsics() as _,
availability_timeout: availability_timeout() as _,
val_count: val_count(),
max_authorizer_code_size: max_authorizer_code_size() as _,
max_input: max_input(),
max_service_code_size: max_service_code_size() as _,
basic_piece_len: basic_piece_len() as _,
max_imports: max_imports() as _,
segment_piece_count: segment_piece_count() as _,
max_report_elective_data: max_report_elective_data(),
transfer_memo_size: MEMO_LEN as _,
max_exports: max_exports(),
epoch_tail_start: epoch_tail_start(),
}
}
pub fn validate(&self) -> Result<(), &'static str> {
if !self.basic_piece_len.is_multiple_of(2) {
return Err("`basic_piece_len` is not even")
}
if !SEGMENT_LEN.is_multiple_of(self.basic_piece_len as usize) {
return Err("`basic_piece_len` does not divide into `SEGMENT_LEN` (4,104)")
}
if !self.epoch_period.is_multiple_of(self.rotation_period as Slot) {
return Err("`rotation_period` does not divide into `epoch_period`")
}
if self.epoch_tail_start >= self.epoch_period {
return Err("`epoch_tail_start` must be less than `epoch_period`")
}
if !(self.val_count as usize).is_multiple_of(VALS_PER_CORE) {
return Err("`val_count` does not divide by `VALS_PER_CORE` (3)")
}
if self.val_count != self.core_count * VALS_PER_CORE as u16 {
return Err("`val_count != core_count * VALS_PER_CORE` (3)")
}
if self.transfer_memo_size != MEMO_LEN as u32 {
return Err("`transfer_memo_size` must be equal tor `MEMO_LEN` (128)")
}
if recent_block_count() > 255 {
return Err("`recent_block_count` may be no larger than `BlockIndex::MAX` (255)")
}
Ok(())
}
pub fn apply(self) -> Result<(), &'static str> {
self.validate()?;
DEPOSIT_PER_ITEM.store(self.deposit_per_item, Relaxed);
DEPOSIT_PER_BYTE.store(self.deposit_per_byte, Relaxed);
DEPOSIT_PER_ACCOUNT.store(self.deposit_per_account, Relaxed);
MIN_TURNAROUND_PERIOD.store(self.min_turnaround_period, Relaxed);
EPOCH_PERIOD.store(self.epoch_period, Relaxed);
MAX_ACCUMULATE_GAS.store(self.max_accumulate_gas, Relaxed);
MAX_IS_AUTHORIZED_GAS.store(self.max_is_authorized_gas, Relaxed);
MAX_REFINE_GAS.store(self.max_refine_gas, Relaxed);
BLOCK_GAS_LIMIT.store(self.block_gas_limit, Relaxed);
RECENT_BLOCK_COUNT.store(self.recent_block_count as _, Relaxed);
MAX_WORK_ITEMS.store(self.max_work_items as _, Relaxed);
MAX_DEPENDENCIES.store(self.max_dependencies as _, Relaxed);
MAX_TICKETS_PER_BLOCK.store(self.max_tickets_per_block as _, Relaxed);
MAX_LOOKUP_ANCHOR_AGE.store(self.max_lookup_anchor_age as _, Relaxed);
TICKETS_ATTEMPTS_NUMBER.store(self.tickets_attempts_number as _, Relaxed);
AUTH_WINDOW.store(self.auth_window as _, Relaxed);
SLOT_PERIOD_SEC.store(self.slot_period_sec as _, Relaxed);
AUTH_QUEUE_LEN.store(self.auth_queue_len as _, Relaxed);
ROTATION_PERIOD.store(self.rotation_period as _, Relaxed);
MAX_EXTRINSICS.store(self.max_extrinsics as _, Relaxed);
AVAILABILITY_TIMEOUT.store(self.availability_timeout as _, Relaxed);
VAL_COUNT.store(self.val_count, Relaxed);
MAX_AUTHORIZER_CODE_SIZE.store(self.max_authorizer_code_size as _, Relaxed);
MAX_INPUT.store(self.max_input, Relaxed);
MAX_SERVICE_CODE_SIZE.store(self.max_service_code_size as _, Relaxed);
BASIC_PIECE_LEN.store(self.basic_piece_len as _, Relaxed);
MAX_IMPORTS.store(self.max_imports, Relaxed);
SEGMENT_PIECE_COUNT.store(self.segment_piece_count as _, Relaxed);
MAX_REPORT_ELECTIVE_DATA.store(self.max_report_elective_data, Relaxed);
MAX_EXPORTS.store(self.max_exports, Relaxed);
EPOCH_TAIL_START.store(self.epoch_tail_start, Relaxed);
Ok(())
}
}
pub const POINT_LEN: usize = 2;
#[doc(hidden)]
#[derive(Copy, Clone, Eq, PartialEq, Default, Debug)]
pub struct ValSuperMajority;
impl Get<u32> for ValSuperMajority {
fn get() -> u32 {
val_count() as u32 / 3 * 2 + 1
}
}
pub type Slot = u32;
pub type ValIndex = u16;
pub type CoreIndex = u16;
pub type ServiceId = u32;
pub type Balance = u64;
pub type DoubleBalance = u128;
pub type SignedGas = i64;
pub type UnsignedGas = u64;
pub type DoubleGas = u128;
pub type Hash = [u8; 32];
opaque! {
pub struct HeaderHash(pub [u8; 32]);
pub struct CodeHash(pub [u8; 32]);
pub struct WorkPackageHash(pub [u8; 32]);
pub struct WorkReportHash(pub [u8; 32]);
pub struct PayloadHash(pub [u8; 32]);
pub struct StateRootHash(pub [u8; 32]);
pub struct MmrPeakHash(pub [u8; 32]);
pub struct AccumulateRootHash(pub [u8; 32]);
pub struct ExtrinsicHash(pub [u8; 32]);
pub struct AuthorizerHash(pub [u8; 32]);
pub struct SegmentTreeRoot(pub [u8; 32]);
pub struct SegmentHash(pub [u8; 32]);
pub struct MerkleNodeHash(pub [u8; 32]);
pub struct AnyHash(pub [u8; 32]);
pub struct Memo(pub [u8; MEMO_LEN]);
pub struct Authorization(pub Vec<u8>);
pub struct Code(pub Vec<u8>);
pub struct WorkPayload(pub Vec<u8>);
pub struct AuthConfig(pub Vec<u8>);
pub struct AnyVec(pub Vec<u8>);
pub struct WrappedSegment(pub FixedVec<u8, SegmentLen>);
pub struct WorkOutput(pub Vec<u8>);
pub struct AuthTrace(pub Vec<u8>);
pub struct OpaqueEd25519Public(pub [u8; 32]);
pub struct OpaqueBandersnatchPublic(pub [u8; 32]);
pub struct OpaqueBlsPublic(pub [u8; 144]);
pub struct OpaqueValidatorMetadata(pub [u8; 128]);
}
#[cfg(feature = "bytes")]
opaque! {
pub struct AnyBytes(pub Bytes);
}
pub type AuthQueue = FixedVec<AuthorizerHash, AuthQueueLen>;
pub type Segment = FixedVec<u8, SegmentLen>;
pub trait ToAny {
type Any;
fn any(&self) -> Self::Any;
fn into_any(self) -> Self::Any;
}
impl ToAny for [u8; 32] {
type Any = AnyHash;
fn any(&self) -> Self::Any {
AnyHash(*self)
}
fn into_any(self) -> Self::Any {
AnyHash(self)
}
}
impl ToAny for alloc::vec::Vec<u8> {
type Any = AnyVec;
fn any(&self) -> Self::Any {
AnyVec(self.clone())
}
fn into_any(self) -> Self::Any {
AnyVec(self)
}
}
impl ToAny for &[u8] {
type Any = AnyVec;
fn any(&self) -> Self::Any {
AnyVec(self.to_vec())
}
fn into_any(self) -> Self::Any {
AnyVec(self.to_vec())
}
}
impl MaxEncodedLen for Authorization {
fn max_encoded_len() -> usize {
BoundedVec::<u8, MaxInput>::max_encoded_len()
}
}
impl MaxEncodedLen for WorkPayload {
fn max_encoded_len() -> usize {
BoundedVec::<u8, MaxInput>::max_encoded_len()
}
}
impl MaxEncodedLen for AuthConfig {
fn max_encoded_len() -> usize {
BoundedVec::<u8, MaxInput>::max_encoded_len()
}
}
impl MaxEncodedLen for AuthTrace {
fn max_encoded_len() -> usize {
BoundedVec::<u8, MaxReportElectiveData>::max_encoded_len()
}
}
impl AuthTrace {
pub fn leak(self) -> &'static [u8] {
self.0.leak()
}
}
impl MaxEncodedLen for WorkOutput {
fn max_encoded_len() -> usize {
BoundedVec::<u8, MaxReportElectiveData>::max_encoded_len()
}
}
impl WorkOutput {
pub fn leak(self) -> &'static [u8] {
self.0.leak()
}
}