#![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod constants; pub mod governance; mod weights; pub mod xcm_config; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ AsEnsureOriginWithArg, ConstU32, ConstU64, Contains, EitherOfDiverse, InstanceFilter, TransformOrigin, }, weights::{ constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, PalletId, }; use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, EnsureSigned, }; use governance::{ origins::{pallet_custom_origins, Treasurer}, TreasurySpender, }; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use polkadot_runtime_common::{ impls::{LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter}, xcm_sender::NoPriceForMessageDelivery, BlockHashCount, SlowAdjustingFeeUpdate, }; use scale_info::TypeInfo; use smallvec::smallvec; use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, IdentityLookup, Verify, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, RuntimeDebug, }; pub use sp_runtime::{MultiAddress, Perbill, Permill}; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; // XCM Imports use xcm::{ latest::{prelude::BodyId, InteriorLocation, Junction::PalletInstance}, VersionedLocation, }; use xcm_builder::PayOverXcm; #[cfg(not(feature = "runtime-benchmarks"))] use xcm_builder::ProcessXcmMessage; use crate::{ constants::currency::{deposit, CENTS, EXISTENTIAL_DEPOSIT, MICROCENTS, MILLICENTS}, weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, xcm_config::{RelayLocation, XcmOriginToTransactDispatchOrigin}, }; /// Alias to 512-bit hash when used in the context of a transaction signature on /// the chain. pub type Signature = MultiSignature; /// Some way of identifying an account on the chain. We intentionally make it /// equivalent to the public key of our transaction signing scheme. pub type AccountId = <::Signer as IdentifyAccount>::AccountId; /// Balance of an account. pub type Balance = u128; /// Index of a transaction in the chain. pub type Nonce = u32; /// A hash of some data used by the chain. pub type Hash = sp_core::H256; /// An index to a block. pub type BlockNumber = u32; /// The address format for describing accounts. pub type Address = MultiAddress; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; /// A Block signed with a Justification pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, Block, frame_system::ChainContext, Runtime, AllPalletsWithSystem, >; /// Handles converting a weight scalar to a fee value, based on the scale and /// granularity of the node's balance type. /// /// This should typically create a mapping between the following ranges: /// - `[0, MAXIMUM_BLOCK_WEIGHT]` /// - `[Balance::min, Balance::max]` /// /// Yet, it can be used for any other sort of change to weight-fee. Some /// examples being: /// - Setting it to `0` will essentially disable the weight fee. /// - Setting it to `1` will cause the literal `#[weight = x]` values to be /// charged. pub struct WeightToFee; pub const P_FACTOR: u128 = 10; pub const Q_FACTOR: u128 = 100; pub const POLY_DEGREE: u8 = 1; impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; fn polynomial() -> WeightToFeeCoefficients { // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 // MILLIUNIT: in our template, we map to 1/10 of that, or 1/10 MILLIUNIT let p = MILLICENTS / P_FACTOR; let q = Q_FACTOR * Balance::from(ExtrinsicBaseWeight::get().ref_time()); smallvec![WeightToFeeCoefficient { degree: POLY_DEGREE, negative: false, coeff_frac: Perbill::from_rational(p % q, q), coeff_integer: p / q, }] } } /// Opaque types. These are used by the CLI to instantiate machinery that don't /// need to know the specifics of the runtime. They can then be made to be /// agnostic over specific formats of data like extrinsics, allowing for them to /// continue syncing the network through upgrades to even the core data /// structures. pub mod opaque { pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; use sp_runtime::{ generic, traits::{BlakeTwo256, Hash as HashT}, }; use super::*; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. pub type Block = generic::Block; /// Opaque block identifier type. pub type BlockId = generic::BlockId; /// Opaque block hash type. pub type Hash = ::Output; } impl_opaque_keys! { pub struct SessionKeys { pub aura: Aura, } } #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("template-parachain"), impl_name: create_runtime_str!("template-parachain"), authoring_version: 1, spec_version: 1, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, state_version: 1, }; /// This determines the average expected block time that we are targeting. /// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. /// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked /// up by `pallet_aura` to implement `fn slot_duration()`. /// /// Change this to adjust the block time. pub const MILLISECS_PER_BLOCK: u64 = 12000; // NOTE: Currently it is not possible to change the slot duration after the // chain has started. Attempting to do so will brick block production. pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; // Time is measured by number of blocks. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; /// We assume that ~5% of the block weight is consumed by `on_initialize` /// handlers. This is used to limit the maximal weight of a single extrinsic. pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be /// used by `Operational` extrinsics. pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); /// We allow for 0.5 of a second of compute with a 12 second average block time. pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, ); /// Maximum number of blocks simultaneously accepted by the Runtime, not yet /// included into the relay chain. pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; /// How many parachain blocks are processed by the relay chain per parent. /// Limits the number of blocks authored per slot. pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; /// Relay chain slot duration, in milliseconds. pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; /// Maximum length for a block. pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; /// The version information used to identify this runtime when compiled /// natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } parameter_types! { pub const Version: RuntimeVersion = VERSION; // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize // the lazy contract deletion. pub RuntimeBlockLength: BlockLength = BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() .base_block(BlockExecutionWeight::get()) .for_class(DispatchClass::all(), |weights| { weights.base_extrinsic = ExtrinsicBaseWeight::get(); }) .for_class(DispatchClass::Normal, |weights| { weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); }) .for_class(DispatchClass::Operational, |weights| { weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); // Operational transactions have some extra reserved space, so that they // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. weights.reserved = Some( MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT ); }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); pub const SS58Prefix: u16 = 42; } pub struct NormalFilter; impl Contains for NormalFilter { fn contains(c: &RuntimeCall) -> bool { match c { // We filter anonymous proxy as they make "reserve" inconsistent // See: https://github.com/paritytech/substrate/blob/37cca710eed3dadd4ed5364c7686608f5175cce1/frame/proxy/src/lib.rs#L270 RuntimeCall::Proxy(method) => !matches!( method, pallet_proxy::Call::create_pure { .. } | pallet_proxy::Call::kill_pure { .. } ), _ => true, } } } /// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from /// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), /// but overridden as needed. #[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { /// The data to be stored in an account. type AccountData = pallet_balances::AccountData; /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The basic call filter to use in dispatchable. type BaseCallFilter = NormalFilter; /// The block type. type Block = Block; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; /// The maximum length of a block (in bytes). type BlockLength = RuntimeBlockLength; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The weight of database operations that the runtime can invoke. type DbWeight = RocksDbWeight; /// The type for hashing blocks and tries. type Hash = Hash; /// The lookup mechanism to get account ID from whatever is passed in /// dispatchers. type Lookup = AccountIdLookup; /// The maximum number of consumers allowed on a single account. type MaxConsumers = ConstU32<16>; /// The index type for storing how many extrinsics an account has signed. type Nonce = Nonce; /// The action to take on a Runtime Upgrade type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; /// Converts a module to an index of this module in the runtime. type PalletInfo = PalletInfo; /// The aggregated dispatch type that is available for extrinsics. type RuntimeCall = RuntimeCall; /// The ubiquitous event type. type RuntimeEvent = RuntimeEvent; /// The ubiquitous origin type. type RuntimeOrigin = RuntimeOrigin; /// This is used as an identifier of the chain. 42 is the generic substrate prefix. type SS58Prefix = SS58Prefix; /// Runtime version. type Version = Version; } parameter_types! { pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; pub const MaxScheduledPerBlock: u32 = 50; pub const NoPreimagePostponement: Option = Some(10); } impl pallet_scheduler::Config for Runtime { type MaxScheduledPerBlock = MaxScheduledPerBlock; type MaximumWeight = MaximumSchedulerWeight; type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly; type PalletsOrigin = OriginCaller; type Preimages = Preimage; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; type ScheduleOrigin = EnsureRoot; type WeightInfo = pallet_scheduler::weights::SubstrateWeight; } parameter_types! { pub const PreimageBaseDeposit: Balance = deposit(2, 64); pub const PreimageByteDeposit: Balance = deposit(0, 1); pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); } impl pallet_preimage::Config for Runtime { type Consideration = frame_support::traits::fungible::HoldConsideration< AccountId, Balances, PreimageHoldReason, frame_support::traits::LinearStoragePrice< PreimageBaseDeposit, PreimageByteDeposit, Balance, >, >; type Currency = Balances; type ManagerOrigin = EnsureRoot; type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_preimage::weights::SubstrateWeight; } impl pallet_timestamp::Config for Runtime { type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; type WeightInfo = pallet_timestamp::weights::SubstrateWeight; } impl pallet_authorship::Config for Runtime { type EventHandler = (CollatorSelection,); type FindAuthor = pallet_session::FindAccountFromAuthorIndex; } parameter_types! { pub const MaxProxies: u32 = 32; pub const MaxPending: u32 = 32; pub const ProxyDepositBase: Balance = deposit(1, 40); pub const AnnouncementDepositBase: Balance = deposit(1, 48); pub const ProxyDepositFactor: Balance = deposit(0, 33); pub const AnnouncementDepositFactor: Balance = deposit(0, 66); } /// The type used to represent the kinds of proxying allowed. /// If you are adding new pallets, consider adding new ProxyType variant #[derive( Copy, Clone, Decode, Default, Encode, Eq, MaxEncodedLen, Ord, PartialEq, PartialOrd, RuntimeDebug, TypeInfo, )] pub enum ProxyType { /// Allows to proxy all calls #[default] Any, /// Allows all non-transfer calls NonTransfer, /// Allows to finish the proxy CancelProxy, /// Allows to operate with collators list (invulnerables, candidates, etc.) Collator, } impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), ProxyType::CancelProxy => matches!( c, RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | RuntimeCall::Multisig { .. } ), ProxyType::Collator => { matches!(c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Multisig { .. }) } } } } impl pallet_proxy::Config for Runtime { type AnnouncementDepositBase = AnnouncementDepositBase; type AnnouncementDepositFactor = AnnouncementDepositFactor; type CallHasher = BlakeTwo256; type Currency = Balances; type MaxPending = MaxPending; type MaxProxies = MaxProxies; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; type ProxyType = ProxyType; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_proxy::weights::SubstrateWeight; } parameter_types! { pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; pub const MaxFreezes: u32 = 0; pub const MaxLocks: u32 = 50; pub const MaxReserves: u32 = 50; } impl pallet_balances::Config for Runtime { type AccountStore = System; /// The type for recording an account's balance. type Balance = Balance; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type FreezeIdentifier = (); type MaxFreezes = MaxFreezes; type MaxLocks = MaxLocks; type MaxReserves = MaxReserves; type ReserveIdentifier = [u8; 8]; /// The ubiquitous event type. type RuntimeEvent = RuntimeEvent; type RuntimeFreezeReason = RuntimeFreezeReason; type RuntimeHoldReason = RuntimeHoldReason; type WeightInfo = pallet_balances::weights::SubstrateWeight; } parameter_types! { pub const AssetDeposit: Balance = 10 * CENTS; pub const AssetAccountDeposit: Balance = deposit(1, 16); pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT; pub const StringLimit: u32 = 50; pub const MetadataDepositBase: Balance = deposit(1, 68); pub const MetadataDepositPerByte: Balance = deposit(0, 1); pub const RemoveItemsLimit: u32 = 1000; } impl pallet_assets::Config for Runtime { type ApprovalDeposit = ApprovalDeposit; type AssetAccountDeposit = AssetAccountDeposit; type AssetDeposit = AssetDeposit; type AssetId = u32; type AssetIdParameter = parity_scale_codec::Compact; type Balance = Balance; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); type CallbackHandle = (); type CreateOrigin = AsEnsureOriginWithArg>; type Currency = Balances; type Extra = (); type ForceOrigin = EnsureRoot; type Freezer = (); type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; type RemoveItemsLimit = RemoveItemsLimit; type RuntimeEvent = RuntimeEvent; type StringLimit = StringLimit; type WeightInfo = pallet_assets::weights::SubstrateWeight; } parameter_types! { /// Relay Chain `TransactionByteFee` / 10 pub const TransactionByteFee: Balance = 10 * MICROCENTS; pub const OperationalFeeMultiplier: u8 = 5; } impl pallet_transaction_payment::Config for Runtime { type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type LengthToFee = ConstantMultiplier; type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type OperationalFeeMultiplier = OperationalFeeMultiplier; type RuntimeEvent = RuntimeEvent; type WeightToFee = WeightToFee; } impl pallet_sudo::Config for Runtime { type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_sudo::weights::SubstrateWeight; } parameter_types! { pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; } impl cumulus_pallet_parachain_system::Config for Runtime { type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< Runtime, RELAY_CHAIN_SLOT_DURATION_MILLIS, BLOCK_PROCESSING_VELOCITY, UNINCLUDED_SEGMENT_CAPACITY, >; type DmpQueue = frame_support::traits::EnqueueWithOrigin; type OnSystemEvent = (); type OutboundXcmpMessageSource = XcmpQueue; type ReservedDmpWeight = ReservedDmpWeight; type ReservedXcmpWeight = ReservedXcmpWeight; type RuntimeEvent = RuntimeEvent; type SelfParaId = parachain_info::Pallet; type WeightInfo = cumulus_pallet_parachain_system::weights::SubstrateWeight; type XcmpMessageHandler = XcmpQueue; } impl parachain_info::Config for Runtime {} parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; pub const HeapSize: u32 = 64 * 1024; pub const MaxStale: u32 = 8; } impl pallet_message_queue::Config for Runtime { type HeapSize = HeapSize; type MaxStale = MaxStale; #[cfg(feature = "runtime-benchmarks")] type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< cumulus_primitives_core::AggregateMessageOrigin, >; #[cfg(not(feature = "runtime-benchmarks"))] type MessageProcessor = ProcessXcmMessage< AggregateMessageOrigin, xcm_executor::XcmExecutor, RuntimeCall, >; // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: type QueueChangeHandler = NarrowOriginToSibling; type QueuePausedQuery = NarrowOriginToSibling; type RuntimeEvent = RuntimeEvent; type ServiceWeight = MessageQueueServiceWeight; type Size = u32; type WeightInfo = pallet_message_queue::weights::SubstrateWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { pub const MaxInboundSuspended: u32 = 1000; } impl cumulus_pallet_xcmp_queue::Config for Runtime { type ChannelInfo = ParachainSystem; type ControllerOrigin = EnsureRoot; type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; type MaxInboundSuspended = MaxInboundSuspended; type PriceForSiblingDelivery = NoPriceForMessageDelivery; type RuntimeEvent = RuntimeEvent; type VersionWrapper = (); type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight; // Enqueue XCMP messages from siblings for later processing. type XcmpQueue = TransformOrigin; } parameter_types! { // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. pub const DepositBase: Balance = deposit(1, 88); // Additional storage item size of 32 bytes. pub const DepositFactor: Balance = deposit(0, 32); pub const MaxSignatories: u16 = 100; } impl pallet_multisig::Config for Runtime { type Currency = Balances; type DepositBase = DepositBase; type DepositFactor = DepositFactor; type MaxSignatories = MaxSignatories; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_multisig::weights::SubstrateWeight; } parameter_types! { pub const Period: u32 = 6 * HOURS; pub const Offset: u32 = 0; } impl pallet_session::Config for Runtime { type Keys = SessionKeys; type NextSessionRotation = pallet_session::PeriodicSessions; type RuntimeEvent = RuntimeEvent; // Essentially just Aura, but let's be pedantic. type SessionHandler = ::KeyTypeIdProviders; type SessionManager = CollatorSelection; type ShouldEndSession = pallet_session::PeriodicSessions; type ValidatorId = ::AccountId; // we don't have stash and controller, thus we don't need the convert as well. type ValidatorIdOf = pallet_collator_selection::IdentityCollator; type WeightInfo = pallet_session::weights::SubstrateWeight; } parameter_types! { pub const AllowMultipleBlocksPerSlot: bool = false; pub const MaxAuthorities: u32 = 100_000; } impl pallet_aura::Config for Runtime { type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = MaxAuthorities; #[cfg(feature = "experimental")] type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; } parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); pub const SessionLength: BlockNumber = 6 * HOURS; // StakingAdmin pluralistic body. pub const StakingAdminBodyId: BodyId = BodyId::Defense; } /// We allow root and the StakingAdmin to execute privileged collator selection /// operations. pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< EnsureRoot, EnsureXcm>, >; parameter_types! { pub const MaxCandidates: u32 = 100; pub const MaxInvulnerables: u32 = 20; pub const MinEligibleCollators: u32 = 4; } impl pallet_collator_selection::Config for Runtime { type Currency = Balances; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type MaxCandidates = MaxCandidates; type MaxInvulnerables = MaxInvulnerables; type MinEligibleCollators = MinEligibleCollators; type PotId = PotId; type RuntimeEvent = RuntimeEvent; type UpdateOrigin = CollatorSelectionUpdateOrigin; type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_collator_selection::IdentityCollator; type ValidatorRegistration = Session; type WeightInfo = pallet_collator_selection::weights::SubstrateWeight; } impl pallet_utility::Config for Runtime { type PalletsOrigin = OriginCaller; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_utility::weights::SubstrateWeight; } parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); pub const ProposalBondMinimum: Balance = 2000; // * CENTS pub const ProposalBondMaximum: Balance = 1;// * GRAND; pub const SpendPeriod: BlockNumber = 6 * DAYS; pub const Burn: Permill = Permill::from_perthousand(2); pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry"); pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 13). pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(13).into(); pub const MaxApprovals: u32 = 100; } parameter_types! { pub TreasuryAccount: AccountId = Treasury::account_id(); } impl pallet_treasury::Config for Runtime { type ApproveOrigin = EitherOfDiverse, Treasurer>; type AssetKind = VersionedLocatableAsset; type BalanceConverter = frame_support::traits::tokens::UnityAssetBalanceConversion; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments; type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Burn = (); type BurnDestination = (); type Currency = Balances; type MaxApprovals = MaxApprovals; type OnSlash = Treasury; type PalletId = TreasuryPalletId; type Paymaster = PayOverXcm< TreasuryInteriorLocation, crate::xcm_config::XcmRouter, crate::PolkadotXcm, ConstU32<{ 6 * HOURS }>, Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, VersionedLocationConverter, >; type PayoutPeriod = PayoutSpendPeriod; type ProposalBond = ProposalBond; type ProposalBondMaximum = ProposalBondMaximum; type ProposalBondMinimum = ProposalBondMinimum; type RejectOrigin = EitherOfDiverse, Treasurer>; type RuntimeEvent = RuntimeEvent; type SpendFunds = (); type SpendOrigin = TreasurySpender; type SpendPeriod = SpendPeriod; type WeightInfo = pallet_treasury::weights::SubstrateWeight; } // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( pub enum Runtime { // System Support System: frame_system = 0, ParachainSystem: cumulus_pallet_parachain_system = 1, Timestamp: pallet_timestamp = 2, ParachainInfo: parachain_info = 3, Proxy: pallet_proxy = 4, Utility: pallet_utility = 5, Multisig: pallet_multisig = 6, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 7, Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 8, // Monetary Balances: pallet_balances = 10, TransactionPayment: pallet_transaction_payment = 11, Assets: pallet_assets = 12, Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 13, // Governance Sudo: pallet_sudo = 15, ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 16, Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 17, Origins: pallet_custom_origins::{Origin} = 18, Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 19, // Collator Support. The order of these 4 are important and shall not change. Authorship: pallet_authorship = 20, CollatorSelection: pallet_collator_selection = 21, Session: pallet_session = 22, Aura: pallet_aura = 23, AuraExt: cumulus_pallet_aura_ext = 24, // XCM Helpers XcmpQueue: cumulus_pallet_xcmp_queue = 30, PolkadotXcm: pallet_xcm = 31, CumulusXcm: cumulus_pallet_xcm = 32, MessageQueue: pallet_message_queue = 33, } ); #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] [pallet_assets, Assets] [pallet_balances, Balances] [pallet_session, SessionBench::] [pallet_timestamp, Timestamp] [pallet_message_queue, MessageQueue] [pallet_sudo, Sudo] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_xcmp_queue, XcmpQueue] ); } impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) } fn authorities() -> Vec { Aura::authorities().into_inner() } } impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } fn execute_block(block: Block) { Executive::execute_block(block) } fn initialize_block(header: &::Header) { Executive::initialize_block(header) } } impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { OpaqueMetadata::new(Runtime::metadata().into()) } fn metadata_at_version(version: u32) -> Option { Runtime::metadata_at_version(version) } fn metadata_versions() -> sp_std::vec::Vec { Runtime::metadata_versions() } } impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { Executive::apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { Executive::finalize_block() } fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents( block: Block, data: sp_inherents::InherentData, ) -> sp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction( source: TransactionSource, tx: ::Extrinsic, block_hash: ::Hash, ) -> TransactionValidity { Executive::validate_transaction(source, tx, block_hash) } } impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { Executive::offchain_worker(header) } } impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) } fn decode_session_keys( encoded: Vec, ) -> Option, KeyTypeId)>> { SessionKeys::decode_into_raw_public_keys(&encoded) } } impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Nonce { System::account_nonce(account) } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { fn query_info( uxt: ::Extrinsic, len: u32, ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } fn query_fee_details( uxt: ::Extrinsic, len: u32, ) -> pallet_transaction_payment::FeeDetails { TransactionPayment::query_fee_details(uxt, len) } fn query_weight_to_fee(weight: Weight) -> Balance { TransactionPayment::weight_to_fee(weight) } fn query_length_to_fee(length: u32) -> Balance { TransactionPayment::length_to_fee(length) } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi for Runtime { fn query_call_info( call: RuntimeCall, len: u32, ) -> pallet_transaction_payment::RuntimeDispatchInfo { TransactionPayment::query_call_info(call, len) } fn query_call_fee_details( call: RuntimeCall, len: u32, ) -> pallet_transaction_payment::FeeDetails { TransactionPayment::query_call_fee_details(call, len) } fn query_weight_to_fee(weight: Weight) -> Balance { TransactionPayment::weight_to_fee(weight) } fn query_length_to_fee(length: u32) -> Balance { TransactionPayment::length_to_fee(length) } } impl cumulus_primitives_core::CollectCollationInfo for Runtime { fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { ParachainSystem::collect_collation_info(header) } } #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { let weight = Executive::try_runtime_upgrade(checks).unwrap(); (weight, RuntimeBlockWeights::get().max_block) } fn execute_block( block: Block, state_root_check: bool, signature_check: bool, select: frame_try_runtime::TryStateSelect, ) -> Weight { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() } } #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( Vec, Vec, ) { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); (list, storage_info) } fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig ) -> Result, sp_runtime::RuntimeString> { use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; use frame_system_benchmarking::Pallet as SystemBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); Ok(()) } fn verify_set_code() { System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); } } use cumulus_pallet_session_benchmarking::Pallet as SessionBench; impl cumulus_pallet_session_benchmarking::Config for Runtime {} use frame_support::traits::WhitelistedStorageKeys; let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); let mut batches = Vec::::new(); let params = (&config, &whitelist); add_benchmarks!(params, batches); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } } impl sp_genesis_builder::GenesisBuilder for Runtime { fn create_default_config() -> Vec { create_default_config::() } fn build_config(config: Vec) -> sp_genesis_builder::Result { build_config::(config) } } } cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, } // tests #[cfg(test)] mod tests { use super::*; // RUNTIME_API_VERSIONS constant is generated by a macro and is private. #[test] fn check_version() { assert_eq!( VERSION, RuntimeVersion { spec_name: create_runtime_str!("template-parachain"), impl_name: create_runtime_str!("template-parachain"), authoring_version: 1, spec_version: 1, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, state_version: 1, } ); } }