// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! # Glutton Zagros Runtime //! //! The purpose of the Glutton teyrchain is to do stress testing on the Dicle //! network. This runtime targets the Zagros runtime to allow development //! separate to the Dicle runtime. //! //! There may be multiple instances of the Glutton teyrchain deployed and //! connected to its parent relay chain. //! //! These teyrchains are not holding any real value. Their purpose is to stress //! test the network. //! //! ### Governance //! //! Glutton defers its governance (namely, its `Root` origin), to its Relay //! Chain parent, Dicle (or Zagros for development purposes). //! //! ### XCM //! //! Since the main goal of Glutton is solely stress testing, the teyrchain will //! only be able receive XCM messages from the Relay Chain via DMP. This way the //! Glutton teyrchains will be able to listen for upgrades that are coming from //! the Relay chain. #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "256"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod genesis_config_presets; pub mod weights; pub mod xcm_config; extern crate alloc; use alloc::{vec, vec::Vec}; use pezcumulus_pezpallet_teyrchain_system::RelayNumberMonotonicallyIncreases; use pezsp_api::impl_runtime_apis; pub use pezsp_consensus_aura::sr25519::AuthorityId as AuraId; use pezsp_core::{crypto::KeyTypeId, OpaqueMetadata}; use pezsp_runtime::{ generic, impl_opaque_keys, traits::{BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, }; #[cfg(feature = "std")] use pezsp_version::NativeVersion; use pezsp_version::RuntimeVersion; use pezcumulus_primitives_core::{AggregateMessageOrigin, ParaId}; pub use pezframe_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, IsInVec, Randomness, }, weights::{ constants::{ BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, }, IdentityFee, Weight, }, PalletId, StorageValue, }; use pezframe_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, }; #[cfg(any(feature = "std", test))] pub use pezsp_runtime::BuildStorage; pub use pezsp_runtime::{Perbill, Permill}; use testnet_teyrchains_constants::zagros::consensus::*; use teyrchains_common::{AccountId, Signature}; impl_opaque_keys! { pub struct SessionKeys { pub aura: Aura, } } #[pezsp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: alloc::borrow::Cow::Borrowed("glutton-zagros"), impl_name: alloc::borrow::Cow::Borrowed("glutton-zagros"), authoring_version: 1, spec_version: 1_020_001, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, system_version: 1, }; /// 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() } } /// We assume that ~10% of the block weight is consumed by `on_initialize` handlers. /// This is used to limit the maximal weight of a single extrinsic. const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used /// by Operational extrinsics. const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); parameter_types! { pub const BlockHashCount: BlockNumber = 4096; pub const Version: RuntimeVersion = VERSION; pub RuntimeBlockLength: BlockLength = BlockLength::max_with_normal_ratio(5 * 1024 * 1024, 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: u8 = 42; } #[derive_impl(pezframe_system::config_preludes::TeyrchainDefaultConfig)] impl pezframe_system::Config for Runtime { type AccountId = AccountId; type Nonce = Nonce; type Hash = Hash; type Block = Block; type BlockHashCount = BlockHashCount; type Version = Version; type BlockWeights = RuntimeBlockWeights; type BlockLength = RuntimeBlockLength; type SS58Prefix = SS58Prefix; type OnSetCode = pezcumulus_pezpallet_teyrchain_system::TeyrchainSetCode; type MaxConsumers = pezframe_support::traits::ConstU32<16>; } parameter_types! { // We do anything the parent chain tells us in this runtime. pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(2); pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; } type ConsensusHook = pezcumulus_pezpallet_aura_ext::FixedVelocityConsensusHook< Runtime, RELAY_CHAIN_SLOT_DURATION_MILLIS, 3, 9, >; impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnSystemEvent = (); type SelfParaId = teyrchain_info::Pezpallet; type DmpQueue = pezframe_support::traits::EnqueueWithOrigin; type OutboundXcmpMessageSource = (); type ReservedDmpWeight = ReservedDmpWeight; type XcmpMessageHandler = (); type ReservedXcmpWeight = (); type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; type ConsensusHook = ConsensusHook; type WeightInfo = weights::pezcumulus_pezpallet_teyrchain_system::WeightInfo; type RelayParentOffset = ConstU32<0>; } parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; } impl pezpallet_message_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pezpallet_message_queue::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type MessageProcessor = pezpallet_message_queue::mock_helpers::NoopMessageProcessor< pezcumulus_primitives_core::AggregateMessageOrigin, >; #[cfg(not(feature = "runtime-benchmarks"))] type MessageProcessor = xcm_builder::ProcessXcmMessage< AggregateMessageOrigin, xcm_executor::XcmExecutor, RuntimeCall, >; type Size = u32; type QueueChangeHandler = (); // No XCMP queue pezpallet deployed. type QueuePausedQuery = (); type HeapSize = pezsp_core::ConstU32<{ 103 * 1024 }>; type MaxStale = pezsp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl teyrchain_info::Config for Runtime {} impl pezcumulus_pezpallet_aura_ext::Config for Runtime {} impl pezpallet_timestamp::Config for Runtime { type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = ConstU64<0>; type WeightInfo = weights::pezpallet_timestamp::WeightInfo; } impl pezpallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; type AllowMultipleBlocksPerSlot = ConstBool; type SlotDuration = ConstU64<2000>; } impl pezpallet_glutton::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pezpallet_glutton::WeightInfo; type AdminOrigin = EnsureRoot; } impl pezpallet_sudo::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type WeightInfo = (); } construct_runtime! { pub enum Runtime { System: pezframe_system = 0, TeyrchainSystem: pezcumulus_pezpallet_teyrchain_system = 1, TeyrchainInfo: teyrchain_info = 2, Timestamp: pezpallet_timestamp = 3, // DMP handler. CumulusXcm: pezcumulus_pezpallet_xcm = 10, MessageQueue: pezpallet_message_queue = 11, // The main stage. Glutton: pezpallet_glutton = 20, // Collator support Aura: pezpallet_aura = 30, AuraExt: pezcumulus_pezpallet_aura_ext = 31, // Sudo. Sudo: pezpallet_sudo = 255, } } /// Index of a transaction in the chain. pub type Nonce = u32; /// A hash of some data used by the chain. pub type Hash = pezsp_core::H256; /// An index to a block. pub type BlockNumber = u32; /// The address format for describing accounts. pub type Address = pezsp_runtime::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 extension to the basic transaction logic. pub type TxExtension = ( pezframe_system::AuthorizeCall, pezpallet_sudo::CheckOnlySudoAccount, pezframe_system::CheckNonZeroSender, pezframe_system::CheckSpecVersion, pezframe_system::CheckTxVersion, pezframe_system::CheckGenesis, pezframe_system::CheckEra, pezframe_system::CheckWeight, pezframe_system::WeightReclaim, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = pezframe_executive::Executive< Runtime, Block, pezframe_system::ChainContext, Runtime, AllPalletsWithSystem, >; #[cfg(feature = "runtime-benchmarks")] mod benches { pezframe_benchmarking::define_benchmarks!( [pezcumulus_pezpallet_teyrchain_system, TeyrchainSystem] [pezframe_system, SystemBench::] [pezframe_system_extensions, SystemExtensionsBench::] [pezpallet_glutton, Glutton] [pezpallet_message_queue, MessageQueue] [pezpallet_timestamp, Timestamp] ); } impl_runtime_apis! { impl pezsp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } fn execute_block(block: ::LazyBlock) { Executive::execute_block(block) } fn initialize_block(header: &::Header) -> pezsp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } impl pezsp_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() -> alloc::vec::Vec { Runtime::metadata_versions() } } impl pezsp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> pezsp_consensus_aura::SlotDuration { pezsp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) } fn authorities() -> Vec { pezpallet_aura::Authorities::::get().into_inner() } } impl pezcumulus_primitives_core::RelayParentOffsetApi for Runtime { fn relay_parent_offset() -> u32 { 0 } } impl pezcumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { fn can_build_upon( included_hash: ::Hash, slot: pezcumulus_primitives_aura::Slot, ) -> bool { ConsensusHook::can_build_upon(included_hash, slot) } } impl pezsp_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: pezsp_inherents::InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents(block: ::LazyBlock, data: pezsp_inherents::InherentData) -> pezsp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } } impl pezsp_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 pezsp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { Executive::offchain_worker(header) } } impl pezsp_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 pezcumulus_primitives_core::CollectCollationInfo for Runtime { fn collect_collation_info(header: &::Header) -> pezcumulus_primitives_core::CollationInfo { TeyrchainSystem::collect_collation_info(header) } } impl pezframe_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Nonce { System::account_nonce(account) } } #[cfg(feature = "runtime-benchmarks")] impl pezframe_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( Vec, Vec, ) { use pezframe_benchmarking::BenchmarkList; use pezframe_support::traits::StorageInfoTrait; use pezframe_system_benchmarking::Pezpallet as SystemBench; use pezframe_system_benchmarking::extensions::Pezpallet as SystemExtensionsBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); (list, storage_info) } #[allow(non_local_definitions)] fn dispatch_benchmark( config: pezframe_benchmarking::BenchmarkConfig ) -> Result, alloc::string::String> { use pezframe_benchmarking::{BenchmarkBatch, BenchmarkError}; use pezsp_storage::TrackedStorageKey; use pezframe_system_benchmarking::Pezpallet as SystemBench; use pezframe_system_benchmarking::extensions::Pezpallet as SystemExtensionsBench; impl pezframe_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &alloc::vec::Vec) -> Result<(), BenchmarkError> { TeyrchainSystem::initialize_for_set_code_benchmark(code.len() as u32); Ok(()) } fn verify_set_code() { System::assert_last_event(pezcumulus_pezpallet_teyrchain_system::Event::::ValidationFunctionStored.into()); } } use pezframe_support::traits::WhitelistedStorageKeys; let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); let mut batches = Vec::::new(); let params = (&config, &whitelist); add_benchmarks!(params, batches); Ok(batches) } } impl pezsp_genesis_builder::GenesisBuilder for Runtime { fn build_state(config: Vec) -> pezsp_genesis_builder::Result { build_state::(config) } fn get_preset(id: &Option) -> Option> { get_preset::(id, &genesis_config_presets::get_preset) } fn preset_names() -> Vec { genesis_config_presets::preset_names() } } impl pezcumulus_primitives_core::GetTeyrchainInfo for Runtime { fn teyrchain_id() -> ParaId { TeyrchainInfo::teyrchain_id() } } impl pezcumulus_primitives_core::TargetBlockRate for Runtime { fn target_block_rate() -> u32 { 1 } } } pezcumulus_pezpallet_teyrchain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = pezcumulus_pezpallet_aura_ext::BlockExecutor::, }