// Copyright (C) Parity Technologies (UK) Ltd. // 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. //! # Asset Hub Zagros Runtime //! //! Testnet for Asset Hub Pezkuwi. #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "512"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod bridge_to_ethereum_config; mod genesis_config_presets; mod weights; pub mod xcm_config; // Configurations for next functionality. mod bag_thresholds; pub mod governance; #[cfg(not(feature = "runtime-benchmarks"))] mod migrations; mod staking; use governance::{pezpallet_custom_origins, FellowshipAdmin, GeneralAdmin, StakingAdmin, Treasurer}; extern crate alloc; use alloc::{vec, vec::Vec}; pub use assets_common::local_and_foreign_assets::ForeignAssetReserveData; use assets_common::{ local_and_foreign_assets::{LocalFromLeft, TargetFromLeft}, AssetIdForPoolAssets, AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert, }; use bp_asset_hub_zagros::CreateForeignAssetDeposit; use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen}; use pezcumulus_pezpallet_teyrchain_system::{RelayNumberMonotonicallyIncreases, RelaychainDataProvider}; use pezcumulus_primitives_core::{relay_chain::AccountIndex, AggregateMessageOrigin, ParaId}; use pezframe_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_state, get_preset}, ord_parameter_types, parameter_types, traits::{ fungible::{self, HoldConsideration}, fungibles, tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect}, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, ConstantStoragePrice, EitherOfDiverse, Equals, InstanceFilter, LinearStoragePrice, Nothing, TransformOrigin, WithdrawReasons, }, weights::{ConstantMultiplier, Weight}, BoundedVec, PalletId, }; use pezframe_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, EnsureSigned, EnsureSignedBy, }; use pezpallet_asset_conversion_tx_payment::SwapAssetAdapter; use pezpallet_assets_precompiles::{InlineIdConfig, ERC20}; use pezpallet_nfts::{DestroyWitness, PalletFeatures}; use pezpallet_nomination_pools::PoolId; use pezpallet_revive::evm::runtime::EthExtra; use pezpallet_xcm::EnsureXcm; use pezpallet_xcm_precompiles::XcmPrecompile; use pezsp_api::impl_runtime_apis; use pezsp_core::{crypto::KeyTypeId, OpaqueMetadata}; use pezsp_runtime::{ generic, impl_opaque_keys, traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Saturating, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedU128, Perbill, Permill, RuntimeDebug, }; #[cfg(feature = "std")] use pezsp_version::NativeVersion; use pezsp_version::RuntimeVersion; use testnet_teyrchains_constants::zagros::{ consensus::*, currency::*, snowbridge::EthereumNetwork, time::*, }; use teyrchains_common::{ impls::DealWithFees, message_queue::*, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, NORMAL_DISPATCH_RATIO, }; use xcm_config::{ ForeignAssetsConvertedConcreteId, LocationToAccountId, PoolAssetsConvertedConcreteId, PoolAssetsPalletLocation, TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, XcmConfig, XcmOriginToTransactDispatchOrigin, ZagrosLocation, }; use zagros_runtime_constants::time::DAYS as RC_DAYS; #[cfg(any(feature = "std", test))] pub use pezsp_runtime::BuildStorage; use assets_common::{ foreign_creators::ForeignCreators, matching::{FromNetwork, FromSiblingTeyrchain}, }; use pezkuwi_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, InMemoryDbWeight}; use xcm::{ latest::prelude::AssetId, prelude::{ VersionedAsset, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, XcmVersion, }, }; use xcm_runtime_pezapis::{ dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects}, fees::Error as XcmPaymentApiError, }; #[cfg(feature = "runtime-benchmarks")] use pezframe_support::traits::PalletInfoAccess; #[cfg(feature = "runtime-benchmarks")] use xcm::latest::prelude::{ Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, NonFungible, ParentThen, Response, WeightLimit, XCM_VERSION, }; impl_opaque_keys! { pub struct SessionKeys { pub aura: Aura, } } #[pezsp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { // Note: "westmint" is the legacy name for this chain. It has been renamed to // "asset-hub-zagros". Many wallets/tools depend on the `spec_name`, so it remains "westmint" // for the time being. Wallets/tools should update to treat "asset-hub-zagros" equally. spec_name: alloc::borrow::Cow::Borrowed("westmint"), impl_name: alloc::borrow::Cow::Borrowed("westmint"), authoring_version: 1, spec_version: 1_020_004, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 16, 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() } } parameter_types! { 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; } // Configure FRAME pallets to include in runtime. #[derive_impl(pezframe_system::config_preludes::TeyrchainDefaultConfig)] impl pezframe_system::Config for Runtime { type BlockWeights = RuntimeBlockWeights; type BlockLength = RuntimeBlockLength; type AccountId = AccountId; type Nonce = Nonce; type Hash = Hash; type Block = Block; type BlockHashCount = BlockHashCount; type DbWeight = InMemoryDbWeight; type Version = Version; type AccountData = pezpallet_balances::AccountData; type SystemWeightInfo = weights::pezframe_system::WeightInfo; type ExtensionsWeightInfo = weights::pezframe_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = pezcumulus_pezpallet_teyrchain_system::TeyrchainSetCode; type MaxConsumers = pezframe_support::traits::ConstU32<16>; type MultiBlockMigrator = MultiBlockMigrations; type SingleBlockMigrations = Migrations; } impl pezcumulus_pezpallet_weight_reclaim::Config for Runtime { type WeightInfo = weights::pezcumulus_pezpallet_weight_reclaim::WeightInfo; } impl pezpallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = ConstU64<0>; type WeightInfo = weights::pezpallet_timestamp::WeightInfo; } impl pezpallet_authorship::Config for Runtime { type FindAuthor = pezpallet_session::FindAccountFromAuthorIndex; type EventHandler = (CollatorSelection,); } parameter_types! { pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; } impl pezpallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; /// The type for recording an account's balance. type Balance = Balance; /// The ubiquitous event type. type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = weights::pezpallet_balances::WeightInfo; type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; type RuntimeHoldReason = RuntimeHoldReason; type RuntimeFreezeReason = RuntimeFreezeReason; type FreezeIdentifier = RuntimeFreezeReason; type MaxFreezes = pezframe_support::traits::VariantCountOf; type DoneSlashHandler = (); } parameter_types! { /// Relay Chain `TransactionByteFee` / 10 pub const TransactionByteFee: Balance = MILLICENTS; } /// `pezpallet_revive` requires this specific `WeightToFee` implementation. /// /// This is needed because we make certain assumptions about how weight /// is mapped to fees. Enforced at compile time. pub type WeightToFee = pezpallet_revive::evm::fees::BlockRatioFee< // p CENTS, // q { 100 * ExtrinsicBaseWeight::get().ref_time() as u128 }, Runtime, >; impl pezpallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = pezpallet_transaction_payment::FungibleAdapter>; type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; type WeightInfo = weights::pezpallet_transaction_payment::WeightInfo; } parameter_types! { pub const AssetDeposit: Balance = UNITS / 10; // 1 / 10 ZGR deposit to create asset pub const AssetAccountDeposit: Balance = deposit(1, 16); pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT; pub const AssetsStringLimit: u32 = 50; /// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1) // https://github.com/pezkuwichain/kurdistan-sdk/blob/main/bizinikiwi/pezframe/assets/src/lib.rs#L257L271 pub const MetadataDepositBase: Balance = deposit(1, 68); pub const MetadataDepositPerByte: Balance = deposit(0, 1); } pub type AssetsForceOrigin = EnsureRoot; // Called "Trust Backed" assets because these are generally registered by some account, and users of // the asset assume it has some claimed backing. The pallet is called `Assets` in // `construct_runtime` to avoid breaking changes on storage reads. pub type TrustBackedAssetsInstance = pezpallet_assets::Instance1; type TrustBackedAssetsCall = pezpallet_assets::Call; impl pezpallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type AssetId = AssetIdForTrustBackedAssets; type AssetIdParameter = codec::Compact; type ReserveData = (); type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = AssetDeposit; type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; type ApprovalDeposit = ApprovalDeposit; type StringLimit = AssetsStringLimit; type Holder = (); type Freezer = AssetsFreezer; type Extra = (); type WeightInfo = weights::pezpallet_assets_local::WeightInfo; type CallbackHandle = pezpallet_assets::AutoIncAssetId; type AssetAccountDeposit = AssetAccountDeposit; type RemoveItemsLimit = ConstU32<1000>; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); } // Allow Freezes for the `Assets` pallet pub type AssetsFreezerInstance = pezpallet_assets_freezer::Instance1; impl pezpallet_assets_freezer::Config for Runtime { type RuntimeFreezeReason = RuntimeFreezeReason; type RuntimeEvent = RuntimeEvent; } parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); } ord_parameter_types! { pub const AssetConversionOrigin: pezsp_runtime::AccountId32 = AccountIdConversion::::into_account_truncating(&AssetConversionPalletId::get()); } pub type PoolAssetsInstance = pezpallet_assets::Instance3; impl pezpallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type RemoveItemsLimit = ConstU32<1000>; type AssetId = u32; type AssetIdParameter = u32; type ReserveData = (); type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ConstU128<0>; type AssetAccountDeposit = ConstU128<0>; type MetadataDepositBase = ConstU128<0>; type MetadataDepositPerByte = ConstU128<0>; type ApprovalDeposit = ConstU128<0>; type StringLimit = ConstU32<50>; type Holder = (); type Freezer = PoolAssetsFreezer; type Extra = (); type WeightInfo = weights::pezpallet_assets_pool::WeightInfo; type CallbackHandle = (); #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); } // Allow Freezes for the `PoolAssets` pallet pub type PoolAssetsFreezerInstance = pezpallet_assets_freezer::Instance3; impl pezpallet_assets_freezer::Config for Runtime { type RuntimeFreezeReason = RuntimeFreezeReason; type RuntimeEvent = RuntimeEvent; } /// Union fungibles implementation for `Assets` and `ForeignAssets`. pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, xcm::v5::Location, >, xcm::v5::Location, AccountId, >; /// Union fungibles implementation for `AssetsFreezer` and `ForeignAssetsFreezer`. pub type LocalAndForeignAssetsFreezer = fungibles::UnionOf< AssetsFreezer, ForeignAssetsFreezer, LocalFromLeft< AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, xcm::v5::Location, >, xcm::v5::Location, AccountId, >; /// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. pub type NativeAndNonPoolAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, TargetFromLeft, xcm::v5::Location, AccountId, >; /// Union fungibles implementation for [`LocalAndForeignAssetsFreezer`] and [`Balances`]. pub type NativeAndNonPoolAssetsFreezer = fungible::UnionOf< Balances, LocalAndForeignAssetsFreezer, TargetFromLeft, xcm::v5::Location, AccountId, >; /// Union fungibles implementation for [`PoolAssets`] and [`NativeAndNonPoolAssets`]. /// /// NOTE: Should be kept updated to include ALL balances and assets in the runtime. pub type NativeAndAllAssets = fungibles::UnionOf< PoolAssets, NativeAndNonPoolAssets, LocalFromLeft< AssetIdForPoolAssetsConvert, AssetIdForPoolAssets, xcm::v5::Location, >, xcm::v5::Location, AccountId, >; /// Union fungibles implementation for [`PoolAssetsFreezer`] and [`NativeAndNonPoolAssetsFreezer`]. /// /// NOTE: Should be kept updated to include ALL balances and assets in the runtime. pub type NativeAndAllAssetsFreezer = fungibles::UnionOf< PoolAssetsFreezer, NativeAndNonPoolAssetsFreezer, LocalFromLeft< AssetIdForPoolAssetsConvert, AssetIdForPoolAssets, xcm::v5::Location, >, xcm::v5::Location, AccountId, >; pub type PoolIdToAccountId = pezpallet_asset_conversion::AccountIdConverter< AssetConversionPalletId, (xcm::v5::Location, xcm::v5::Location), >; impl pezpallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = pezsp_core::U256; type AssetKind = xcm::v5::Location; type Assets = NativeAndNonPoolAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = pezpallet_asset_conversion::WithFirstAsset< ZagrosLocation, AccountId, Self::AssetKind, PoolIdToAccountId, >; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam type PoolSetupFeeAsset = ZagrosLocation; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; type PalletId = AssetConversionPalletId; type MaxSwapPathLength = ConstU32<3>; type MintMinLiquidity = ConstU128<100>; type WeightInfo = weights::pezpallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< ZagrosLocation, teyrchain_info::Pallet, xcm_config::TrustBackedAssetsPalletIndex, xcm::v5::Location, >; } #[cfg(feature = "runtime-benchmarks")] pub struct PalletAssetRewardsBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] impl pezpallet_asset_rewards::benchmarking::BenchmarkHelper for PalletAssetRewardsBenchmarkHelper { fn staked_asset() -> Location { Location::new( 0, [PalletInstance(::index() as u8), GeneralIndex(100)], ) } fn reward_asset() -> Location { Location::new( 0, [PalletInstance(::index() as u8), GeneralIndex(101)], ) } } parameter_types! { pub const MinVestedTransfer: Balance = 100 * CENTS; pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); } impl pezpallet_vesting::Config for Runtime { const MAX_VESTING_SCHEDULES: u32 = 100; type BlockNumberProvider = RelaychainDataProvider; type BlockNumberToBalance = ConvertInto; type Currency = Balances; type MinVestedTransfer = MinVestedTransfer; type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pezpallet_vesting::WeightInfo; type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; } parameter_types! { pub const AssetRewardsPalletId: PalletId = PalletId(*b"py/astrd"); pub const RewardsPoolCreationHoldReason: RuntimeHoldReason = RuntimeHoldReason::AssetRewards(pezpallet_asset_rewards::HoldReason::PoolCreation); // 1 item, 135 bytes into the storage on pool creation. pub const StakePoolCreationDeposit: Balance = deposit(1, 135); } impl pezpallet_asset_rewards::Config for Runtime { type RuntimeEvent = RuntimeEvent; type PalletId = AssetRewardsPalletId; type Balance = Balance; type Assets = NativeAndAllAssets; type AssetsFreezer = NativeAndAllAssetsFreezer; type AssetId = xcm::v5::Location; type CreatePoolOrigin = EnsureSigned; type RuntimeFreezeReason = RuntimeFreezeReason; type Consideration = HoldConsideration< AccountId, Balances, RewardsPoolCreationHoldReason, ConstantStoragePrice, >; type WeightInfo = weights::pezpallet_asset_rewards::WeightInfo; type BlockNumberProvider = pezframe_system::Pallet; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = PalletAssetRewardsBenchmarkHelper; } impl pezpallet_asset_conversion_ops::Config for Runtime { type RuntimeEvent = RuntimeEvent; type PriorAccountIdConverter = pezpallet_asset_conversion::AccountIdConverterNoSeed< ::PoolId, >; type AssetsRefund = ::Assets; type PoolAssetsRefund = ::PoolAssets; type PoolAssetsTeam = ::PoolAssets; type DepositAsset = Balances; type WeightInfo = weights::pezpallet_asset_conversion_ops::WeightInfo; } parameter_types! { pub const ForeignAssetsAssetDeposit: Balance = CreateForeignAssetDeposit::get(); pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get(); pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get(); pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get(); pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get(); pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get(); } /// Assets managed by some foreign location. Note: we do not declare a `ForeignAssetsCall` type, as /// this type is used in proxy definitions. We assume that a foreign location would not want to set /// an individual, local account as a proxy for the issuance of their assets. This issuance should /// be managed by the foreign location's governance. pub type ForeignAssetsInstance = pezpallet_assets::Instance2; impl pezpallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type AssetId = xcm::v5::Location; type AssetIdParameter = xcm::v5::Location; type ReserveData = ForeignAssetReserveData; type Currency = Balances; type CreateOrigin = ForeignCreators< ( FromSiblingTeyrchain, xcm::v5::Location>, FromNetwork, xcm_config::bridging::to_pezkuwichain::PezkuwichainAssetFromAssetHubPezkuwichain, ), LocationToAccountId, AccountId, xcm::v5::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; type MetadataDepositBase = ForeignAssetsMetadataDepositBase; type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte; type ApprovalDeposit = ForeignAssetsApprovalDeposit; type StringLimit = ForeignAssetsAssetsStringLimit; type Holder = (); type Freezer = ForeignAssetsFreezer; type Extra = (); type WeightInfo = weights::pezpallet_assets_foreign::WeightInfo; type CallbackHandle = (); type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit; type RemoveItemsLimit = pezframe_support::traits::ConstU32<1000>; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::LocationAssetsBenchmarkHelper; } // Allow Freezes for the `ForeignAssets` pallet pub type ForeignAssetsFreezerInstance = pezpallet_assets_freezer::Instance2; impl pezpallet_assets_freezer::Config for Runtime { type RuntimeFreezeReason = RuntimeFreezeReason; type RuntimeEvent = RuntimeEvent; } 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: u32 = 100; } impl pezpallet_multisig::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type Currency = Balances; type DepositBase = DepositBase; type DepositFactor = DepositFactor; type MaxSignatories = MaxSignatories; type WeightInfo = weights::pezpallet_multisig::WeightInfo; type BlockNumberProvider = System; } impl pezpallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; type WeightInfo = weights::pezpallet_utility::WeightInfo; } parameter_types! { // One storage item; key size 32, value size 8; . pub const ProxyDepositBase: Balance = deposit(1, 40); // Additional storage item size of 33 bytes. pub const ProxyDepositFactor: Balance = deposit(0, 33); pub const MaxProxies: u16 = 32; // One storage item; key size 32, value size 16 pub const AnnouncementDepositBase: Balance = deposit(1, 48); pub const AnnouncementDepositFactor: Balance = deposit(0, 66); pub const MaxPending: u16 = 32; } /// The type used to represent the kinds of proxying allowed. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, DecodeWithMemTracking, RuntimeDebug, MaxEncodedLen, scale_info::TypeInfo, )] pub enum ProxyType { /// Fully permissioned proxy. Can execute any call on behalf of _proxied_. Any, /// Can execute any call that does not transfer funds or assets. NonTransfer, /// Proxy with the ability to reject time-delay proxy announcements. CancelProxy, /// Assets proxy. Can execute any call from `assets`, **including asset transfers**. Assets, /// Owner proxy. Can execute calls related to asset ownership. AssetOwner, /// Asset manager. Can execute calls related to asset management. AssetManager, /// Collator selection proxy. Can execute calls related to collator selection mechanism. Collator, // New variants introduced by the Asset Hub Migration from the Relay Chain. /// Allow to do governance. /// /// Contains pallets `Treasury`, `Bounties`, `Utility`, `ChildBounties`, `ConvictionVoting`, /// `Referenda` and `Whitelist`. Governance, /// Allows access to staking related calls. /// /// Contains the `Staking`, `Session`, `Utility`, `FastUnstake`, `VoterList`, `NominationPools` /// pallets. Staking, /// Allows access to nomination pools related calls. /// /// Contains the `NominationPools` and `Utility` pallets. NominationPools, /// Placeholder variant to track the state before the Asset Hub Migration. OldSudoBalances, /// Placeholder variant to track the state before the Asset Hub Migration. OldIdentityJudgement, /// Placeholder variant to track the state before the Asset Hub Migration. OldAuction, /// Placeholder variant to track the state before the Asset Hub Migration. OldParaRegistration, } impl Default for ProxyType { fn default() -> Self { Self::Any } } impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, ProxyType::OldSudoBalances | ProxyType::OldIdentityJudgement | ProxyType::OldAuction | ProxyType::OldParaRegistration => false, ProxyType::NonTransfer => !matches!( c, RuntimeCall::Balances { .. } | RuntimeCall::Assets { .. } | RuntimeCall::NftFractionalization { .. } | RuntimeCall::Nfts { .. } | RuntimeCall::Uniques { .. } | RuntimeCall::Scheduler(..) | RuntimeCall::Treasury(..) | // We allow calling `vest` and merging vesting schedules, but obviously not // vested transfers. RuntimeCall::Vesting(pezpallet_vesting::Call::vested_transfer { .. }) | RuntimeCall::ConvictionVoting(..) | RuntimeCall::Referenda(..) | RuntimeCall::Whitelist(..) ), ProxyType::CancelProxy => matches!( c, RuntimeCall::Proxy(pezpallet_proxy::Call::reject_announcement { .. }) | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, RuntimeCall::Assets { .. } | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } | RuntimeCall::NftFractionalization { .. } | RuntimeCall::Nfts { .. } | RuntimeCall::Uniques { .. } ) }, ProxyType::AssetOwner => matches!( c, RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::redeposit { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::transfer_ownership { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::set_team { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::set_collection_max_supply { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::lock_collection { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::create { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::destroy { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::transfer_ownership { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::set_team { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::set_metadata { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::set_attribute { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::set_collection_metadata { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::clear_metadata { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::clear_attribute { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::clear_collection_metadata { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::set_collection_max_supply { .. }) | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) | RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::mint_pre_signed { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::set_attributes_pre_signed { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::lock_item_transfer { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::unlock_item_transfer { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::lock_item_properties { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::set_metadata { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::clear_metadata { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::set_collection_metadata { .. }) | RuntimeCall::Nfts(pezpallet_nfts::Call::clear_collection_metadata { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::mint { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::burn { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::freeze { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::thaw { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::freeze_collection { .. }) | RuntimeCall::Uniques(pezpallet_uniques::Call::thaw_collection { .. }) | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, RuntimeCall::CollatorSelection { .. } | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } ), // New variants introduced by the Asset Hub Migration from the Relay Chain. ProxyType::Governance => matches!( c, RuntimeCall::Treasury(..) | RuntimeCall::Utility(..) | RuntimeCall::ConvictionVoting(..) | RuntimeCall::Referenda(..) | RuntimeCall::Whitelist(..) ), ProxyType::Staking => { matches!( c, RuntimeCall::Staking(..) | RuntimeCall::Session(..) | RuntimeCall::Utility(..) | RuntimeCall::NominationPools(..) | RuntimeCall::VoterList(..) ) }, ProxyType::NominationPools => { matches!(c, RuntimeCall::NominationPools(..) | RuntimeCall::Utility(..)) }, } } fn is_superset(&self, o: &Self) -> bool { match (self, o) { (x, y) if x == y => true, (ProxyType::Any, _) => true, (_, ProxyType::Any) => false, (ProxyType::Assets, ProxyType::AssetOwner) => true, (ProxyType::Assets, ProxyType::AssetManager) => true, ( ProxyType::NonTransfer, ProxyType::Collator | ProxyType::Governance | ProxyType::Staking | ProxyType::NominationPools, ) => true, _ => false, } } } impl pezpallet_proxy::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type Currency = Balances; type ProxyType = ProxyType; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; type MaxProxies = MaxProxies; type WeightInfo = weights::pezpallet_proxy::WeightInfo; type MaxPending = MaxPending; type CallHasher = BlakeTwo256; type AnnouncementDepositBase = AnnouncementDepositBase; type AnnouncementDepositFactor = AnnouncementDepositFactor; type BlockNumberProvider = RelaychainDataProvider; } parameter_types! { pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); } impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime { type WeightInfo = weights::pezcumulus_pezpallet_teyrchain_system::WeightInfo; type RuntimeEvent = RuntimeEvent; type OnSystemEvent = (); type SelfParaId = teyrchain_info::Pallet; type DmpQueue = pezframe_support::traits::EnqueueWithOrigin; type ReservedDmpWeight = ReservedDmpWeight; type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; type ConsensusHook = ConsensusHook; type RelayParentOffset = ConstU32<0>; } type ConsensusHook = pezcumulus_pezpallet_aura_ext::FixedVelocityConsensusHook< Runtime, RELAY_CHAIN_SLOT_DURATION_MILLIS, BLOCK_PROCESSING_VELOCITY, UNINCLUDED_SEGMENT_CAPACITY, >; impl teyrchain_info::Config for Runtime {} parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * 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; // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: type QueueChangeHandler = NarrowOriginToSibling; type QueuePausedQuery = NarrowOriginToSibling; type HeapSize = pezsp_core::ConstU32<{ 103 * 1024 }>; type MaxStale = pezsp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl pezcumulus_pezpallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. pub FeeAssetId: AssetId = AssetId(xcm_config::ZagrosLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } pub type PriceForSiblingTeyrchainDelivery = pezkuwi_runtime_common::xcm_sender::ExponentialPrice< FeeAssetId, BaseDeliveryFee, TransactionByteFee, XcmpQueue, >; impl pezcumulus_pezpallet_xcmp_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ChannelInfo = TeyrchainSystem; type VersionWrapper = PezkuwiXcm; // Enqueue XCMP messages from siblings for later processing. type XcmpQueue = TransformOrigin; type MaxInboundSuspended = ConstU32<1_000>; type MaxActiveOutboundChannels = ConstU32<128>; // Most on-chain HRMP channels are configured to use 102400 bytes of max message size, so we // need to set the page size larger than that until we reduce the channel size on-chain. type MaxPageSize = ConstU32<{ 103 * 1024 }>; type ControllerOrigin = EnsureRoot; type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; type WeightInfo = weights::pezcumulus_pezpallet_xcmp_queue::WeightInfo; type PriceForSiblingDelivery = PriceForSiblingTeyrchainDelivery; } impl pezcumulus_pezpallet_xcmp_queue::migration::v5::V5Config for Runtime { // This must be the same as the `ChannelInfo` from the `Config`: type ChannelList = TeyrchainSystem; } parameter_types! { pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; } parameter_types! { pub const Period: u32 = 6 * HOURS; pub const Offset: u32 = 0; } impl pezpallet_session::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ValidatorId = ::AccountId; // we don't have stash and controller, thus we don't need the convert as well. type ValidatorIdOf = pezpallet_collator_selection::IdentityCollator; type ShouldEndSession = pezpallet_session::PeriodicSessions; type NextSessionRotation = pezpallet_session::PeriodicSessions; type SessionManager = CollatorSelection; // Essentially just Aura, but let's be pedantic. type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisablingStrategy = (); type WeightInfo = weights::pezpallet_session::WeightInfo; type Currency = Balances; type KeyDeposit = (); } impl pezpallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; type AllowMultipleBlocksPerSlot = ConstBool; type SlotDuration = ConstU64; } parameter_types! { pub const PotId: PalletId = PalletId(*b"PotStake"); pub const SessionLength: BlockNumber = 6 * HOURS; } pub type CollatorSelectionUpdateOrigin = EnsureRoot; impl pezpallet_collator_selection::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type UpdateOrigin = CollatorSelectionUpdateOrigin; type PotId = PotId; type MaxCandidates = ConstU32<100>; type MinEligibleCollators = ConstU32<4>; type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; type ValidatorId = ::AccountId; type ValidatorIdOf = pezpallet_collator_selection::IdentityCollator; type ValidatorRegistration = Session; type WeightInfo = weights::pezpallet_collator_selection::WeightInfo; } parameter_types! { pub StakingPot: AccountId = CollatorSelection::account_id(); } impl pezpallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type AssetId = xcm::v5::Location; type OnChargeAssetTransaction = SwapAssetAdapter< ZagrosLocation, NativeAndNonPoolAssets, AssetConversion, ResolveAssetTo, >; type WeightInfo = weights::pezpallet_asset_conversion_tx_payment::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = AssetConversionTxHelper; } parameter_types! { pub const UniquesCollectionDeposit: Balance = UNITS / 10; // 1 / 10 UNIT deposit to create a collection pub const UniquesItemDeposit: Balance = UNITS / 1_000; // 1 / 1000 UNIT deposit to mint an item pub const UniquesMetadataDepositBase: Balance = deposit(1, 129); pub const UniquesAttributeDepositBase: Balance = deposit(1, 0); pub const UniquesDepositPerByte: Balance = deposit(0, 1); } impl pezpallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CollectionId = CollectionId; type ItemId = ItemId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type CollectionDeposit = UniquesCollectionDeposit; type ItemDeposit = UniquesItemDeposit; type MetadataDepositBase = UniquesMetadataDepositBase; type AttributeDepositBase = UniquesAttributeDepositBase; type DepositPerByte = UniquesDepositPerByte; type StringLimit = ConstU32<128>; type KeyLimit = ConstU32<32>; type ValueLimit = ConstU32<64>; type WeightInfo = weights::pezpallet_uniques::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type Helper = (); type CreateOrigin = AsEnsureOriginWithArg>; type Locker = (); } parameter_types! { pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction"); pub NewAssetSymbol: BoundedVec = (*b"FRAC").to_vec().try_into().unwrap(); pub NewAssetName: BoundedVec = (*b"Frac").to_vec().try_into().unwrap(); } impl pezpallet_nft_fractionalization::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Deposit = AssetDeposit; type Currency = Balances; type NewAssetSymbol = NewAssetSymbol; type NewAssetName = NewAssetName; type StringLimit = AssetsStringLimit; type NftCollectionId = ::CollectionId; type NftId = ::ItemId; type AssetBalance = ::Balance; type AssetId = >::AssetId; type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = weights::pezpallet_nft_fractionalization::WeightInfo; type RuntimeHoldReason = RuntimeHoldReason; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = (); } parameter_types! { pub NftsPalletFeatures: PalletFeatures = PalletFeatures::all_enabled(); pub const NftsMaxDeadlineDuration: BlockNumber = 12 * 30 * DAYS; // re-use the Uniques deposits pub const NftsCollectionDeposit: Balance = UniquesCollectionDeposit::get(); pub const NftsItemDeposit: Balance = UniquesItemDeposit::get(); pub const NftsMetadataDepositBase: Balance = UniquesMetadataDepositBase::get(); pub const NftsAttributeDepositBase: Balance = UniquesAttributeDepositBase::get(); pub const NftsDepositPerByte: Balance = UniquesDepositPerByte::get(); } impl pezpallet_nfts::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CollectionId = CollectionId; type ItemId = ItemId; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; type Locker = (); type CollectionDeposit = NftsCollectionDeposit; type ItemDeposit = NftsItemDeposit; type MetadataDepositBase = NftsMetadataDepositBase; type AttributeDepositBase = NftsAttributeDepositBase; type DepositPerByte = NftsDepositPerByte; type StringLimit = ConstU32<256>; type KeyLimit = ConstU32<64>; type ValueLimit = ConstU32<256>; type ApprovalsLimit = ConstU32<20>; type ItemAttributesApprovalsLimit = ConstU32<30>; type MaxTips = ConstU32<10>; type MaxDeadlineDuration = NftsMaxDeadlineDuration; type MaxAttributesPerCall = ConstU32<10>; type Features = NftsPalletFeatures; type OffchainSignature = Signature; type OffchainPublic = ::Signer; type WeightInfo = weights::pezpallet_nfts::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type Helper = (); type BlockNumberProvider = RelaychainDataProvider; } /// XCM router instance to BridgeHub with bridging capabilities for `Pezkuwichain` global /// consensus with dynamic fees and back-pressure. pub type ToPezkuwichainXcmRouterInstance = pezpallet_xcm_bridge_hub_router::Instance1; impl pezpallet_xcm_bridge_hub_router::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pezpallet_xcm_bridge_hub_router::WeightInfo; type UniversalLocation = xcm_config::UniversalLocation; type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub; type BridgedNetworkId = xcm_config::bridging::to_pezkuwichain::PezkuwichainNetwork; type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PezkuwiXcm; type BridgeHubOrigin = pezframe_support::traits::EitherOfDiverse< EnsureRoot, EnsureXcm>, >; type ToBridgeHubSender = XcmpQueue; type LocalXcmChannelManager = pezcumulus_pezpallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; } parameter_types! { pub const DepositPerItem: Balance = deposit(1, 0); pub const DepositPerChildTrieItem: Balance = deposit(1, 0) / 100; pub const DepositPerByte: Balance = deposit(0, 1); pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30); pub const MaxEthExtrinsicWeight: FixedU128 = FixedU128::from_rational(9, 10); } impl pezpallet_revive::Config for Runtime { type Time = Timestamp; type Balance = Balance; type Currency = Balances; type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; type DepositPerItem = DepositPerItem; type DepositPerChildTrieItem = DepositPerChildTrieItem; type DepositPerByte = DepositPerByte; type WeightInfo = pezpallet_revive::weights::BizinikiwiWeight; type Precompiles = ( ERC20, TrustBackedAssetsInstance>, ERC20, PoolAssetsInstance>, XcmPrecompile, ); type AddressMapper = pezpallet_revive::AccountId32Mapper; type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>; type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>; type UnsafeUnstableInterface = ConstBool; type AllowEVMBytecode = ConstBool; type UploadOrigin = EnsureSigned; type InstantiateOrigin = EnsureSigned; type RuntimeHoldReason = RuntimeHoldReason; type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type ChainId = ConstU64<420_420_421>; type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12. type FindAuthor = ::FindAuthor; type FeeInfo = pezpallet_revive::evm::fees::Info; type MaxEthExtrinsicWeight = MaxEthExtrinsicWeight; type DebugEnabled = ConstBool; } parameter_types! { pub MbmServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; pub FastUnstakeName: &'static str = "FastUnstake"; } impl pezpallet_migrations::Config for Runtime { type RuntimeEvent = RuntimeEvent; // Always use mocked migrations for test runtimes to ensure benchmarks succeed type Migrations = pezpallet_migrations::mock_helpers::MockedMigrations; type CursorMaxLen = ConstU32<65_536>; type IdentifierMaxLen = ConstU32<256>; type MigrationStatusHandler = (); type FailedMigrationHandler = pezframe_support::migrations::FreezeChainOnFailedMigration; type MaxServiceWeight = MbmServiceWeight; type WeightInfo = weights::pezpallet_migrations::WeightInfo; } parameter_types! { pub MaximumSchedulerWeight: pezframe_support::weights::Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; } impl pezpallet_scheduler::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; type RuntimeEvent = RuntimeEvent; type PalletsOrigin = OriginCaller; type RuntimeCall = RuntimeCall; type MaximumWeight = MaximumSchedulerWeight; type ScheduleOrigin = EnsureRoot; #[cfg(feature = "runtime-benchmarks")] type MaxScheduledPerBlock = ConstU32<{ 512 * 15 }>; // MaxVotes * TRACKS_DATA length #[cfg(not(feature = "runtime-benchmarks"))] type MaxScheduledPerBlock = ConstU32<50>; type WeightInfo = weights::pezpallet_scheduler::WeightInfo; type OriginPrivilegeCmp = pezframe_support::traits::EqualPrivilegeOnly; type Preimages = Preimage; type BlockNumberProvider = RelaychainDataProvider; } parameter_types! { pub const PreimageBaseDeposit: Balance = deposit(2, 64); pub const PreimageByteDeposit: Balance = deposit(0, 1); pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pezpallet_preimage::HoldReason::Preimage); } impl pezpallet_preimage::Config for Runtime { type WeightInfo = weights::pezpallet_preimage::WeightInfo; type RuntimeEvent = RuntimeEvent; type Currency = Balances; type ManagerOrigin = EnsureRoot; type Consideration = HoldConsideration< AccountId, Balances, PreimageHoldReason, LinearStoragePrice, >; } parameter_types! { /// Deposit for an index in the indices pallet. /// /// 32 bytes for the account ID and 16 for the deposit. We cannot use `max_encoded_len` since it /// is not const. pub const IndexDeposit: Balance = deposit(1, 32 + 16); } impl pezpallet_indices::Config for Runtime { type AccountIndex = AccountIndex; type Currency = Balances; type Deposit = IndexDeposit; type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pezpallet_indices::WeightInfo; } impl pezpallet_ah_ops::Config for Runtime { type Currency = Balances; type RcBlockNumberProvider = RelaychainDataProvider; type WeightInfo = weights::pezpallet_ah_ops::WeightInfo; } impl pezpallet_sudo::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type WeightInfo = weights::pezpallet_sudo::WeightInfo; } // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime { // System support stuff. System: pezframe_system = 0, TeyrchainSystem: pezcumulus_pezpallet_teyrchain_system = 1, // RandomnessCollectiveFlip = 2 removed Timestamp: pezpallet_timestamp = 3, TeyrchainInfo: teyrchain_info = 4, WeightReclaim: pezcumulus_pezpallet_weight_reclaim = 5, MultiBlockMigrations: pezpallet_migrations = 6, Preimage: pezpallet_preimage = 7, Scheduler: pezpallet_scheduler = 8, Sudo: pezpallet_sudo = 9, // Monetary stuff. Balances: pezpallet_balances = 10, TransactionPayment: pezpallet_transaction_payment = 11, // AssetTxPayment: pezpallet_asset_tx_payment = 12, AssetTxPayment: pezpallet_asset_conversion_tx_payment = 13, Vesting: pezpallet_vesting = 14, // Collator support. the order of these 5 are important and shall not change. Authorship: pezpallet_authorship = 20, CollatorSelection: pezpallet_collator_selection = 21, Session: pezpallet_session = 22, Aura: pezpallet_aura = 23, AuraExt: pezcumulus_pezpallet_aura_ext = 24, // XCM helpers. XcmpQueue: pezcumulus_pezpallet_xcmp_queue = 30, PezkuwiXcm: pezpallet_xcm = 31, CumulusXcm: pezcumulus_pezpallet_xcm = 32, // Bridge utilities. ToPezkuwichainXcmRouter: pezpallet_xcm_bridge_hub_router:: = 34, MessageQueue: pezpallet_message_queue = 35, // Snowbridge SnowbridgeSystemFrontend: snowbridge_pezpallet_system_frontend = 36, // Handy utilities. Utility: pezpallet_utility = 40, Multisig: pezpallet_multisig = 41, Proxy: pezpallet_proxy = 42, Indices: pezpallet_indices = 43, // The main stage. Assets: pezpallet_assets:: = 50, Uniques: pezpallet_uniques = 51, Nfts: pezpallet_nfts = 52, ForeignAssets: pezpallet_assets:: = 53, NftFractionalization: pezpallet_nft_fractionalization = 54, PoolAssets: pezpallet_assets:: = 55, AssetConversion: pezpallet_asset_conversion = 56, AssetsFreezer: pezpallet_assets_freezer:: = 57, ForeignAssetsFreezer: pezpallet_assets_freezer:: = 58, PoolAssetsFreezer: pezpallet_assets_freezer:: = 59, Revive: pezpallet_revive = 60, AssetRewards: pezpallet_asset_rewards = 61, StateTrieMigration: pezpallet_state_trie_migration = 70, // Staking. Staking: pezpallet_staking_async = 80, NominationPools: pezpallet_nomination_pools = 81, // decommissioned in AHs. // FastUnstake: pezpallet_fast_unstake = 82, VoterList: pezpallet_bags_list:: = 83, DelegatedStaking: pezpallet_delegated_staking = 84, StakingRcClient: pezpallet_staking_async_rc_client = 89, // Staking election apparatus. MultiBlockElection: pezpallet_election_provider_multi_block = 85, MultiBlockElectionVerifier: pezpallet_election_provider_multi_block::verifier = 86, MultiBlockElectionUnsigned: pezpallet_election_provider_multi_block::unsigned = 87, MultiBlockElectionSigned: pezpallet_election_provider_multi_block::signed = 88, // Governance. ConvictionVoting: pezpallet_conviction_voting = 90, Referenda: pezpallet_referenda = 91, Origins: pezpallet_custom_origins = 92, Whitelist: pezpallet_whitelist = 93, Treasury: pezpallet_treasury = 94, AssetRate: pezpallet_asset_rate = 95, // TODO: the pallet instance should be removed once all pools have migrated // to the new account IDs. AssetConversionMigration: pezpallet_asset_conversion_ops = 200, AhOps: pezpallet_ah_ops = 254, } ); /// The address format for describing accounts. pub type Address = pezsp_runtime::MultiAddress; /// 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 = pezcumulus_pezpallet_weight_reclaim::StorageWeightReclaim< Runtime, ( pezframe_system::AuthorizeCall, pezframe_system::CheckNonZeroSender, pezframe_system::CheckSpecVersion, pezframe_system::CheckTxVersion, pezframe_system::CheckGenesis, pezframe_system::CheckEra, pezframe_system::CheckNonce, pezframe_system::CheckWeight, pezpallet_asset_conversion_tx_payment::ChargeAssetTxPayment, pezframe_metadata_hash_extension::CheckMetadataHash, pezpallet_revive::evm::tx_extension::SetOrigin, ), >; /// Default extensions applied to Ethereum transactions. #[derive(Clone, PartialEq, Eq, Debug)] pub struct EthExtraImpl; impl EthExtra for EthExtraImpl { type Config = Runtime; type Extension = TxExtension; fn get_eth_extension(nonce: u32, tip: Balance) -> Self::Extension { ( pezframe_system::AuthorizeCall::::new(), pezframe_system::CheckNonZeroSender::::new(), pezframe_system::CheckSpecVersion::::new(), pezframe_system::CheckTxVersion::::new(), pezframe_system::CheckGenesis::::new(), pezframe_system::CheckMortality::from(generic::Era::Immortal), pezframe_system::CheckNonce::::from(nonce), pezframe_system::CheckWeight::::new(), pezpallet_asset_conversion_tx_payment::ChargeAssetTxPayment::::from(tip, None), pezframe_metadata_hash_extension::CheckMetadataHash::::new(false), pezpallet_revive::evm::tx_extension::SetOrigin::::new_from_eth_transaction(), ) .into() } } /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = pezpallet_revive::evm::runtime::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( // v9420 pezpallet_nfts::migration::v1::MigrateToV1, // unreleased pezpallet_collator_selection::migration::v2::MigrationToV2, // unreleased pezpallet_multisig::migrations::v1::MigrateToV1, // unreleased InitStorageVersions, // unreleased DeleteUndecodableStorage, // unreleased pezcumulus_pezpallet_xcmp_queue::migration::v4::MigrationToV4, pezcumulus_pezpallet_xcmp_queue::migration::v5::MigrateV4ToV5, // unreleased pezpallet_assets::migration::next_asset_id::SetNextAssetId< ConstU32<50_000_000>, Runtime, TrustBackedAssetsInstance, >, pezpallet_session::migrations::v1::MigrateV0ToV1< Runtime, pezpallet_session::migrations::v1::InitOffenceSeverity, >, pezframe_support::migrations::RemovePallet< FastUnstakeName, ::DbWeight, >, // permanent pezpallet_xcm::migration::MigrateToLatestXcmVersion, pezcumulus_pezpallet_aura_ext::migration::MigrateV0ToV1, ); /// Asset Hub Zagros has some undecodable storage, delete it. /// See for more info. /// /// First we remove the bad Hold, then the bad NFT collection. pub struct DeleteUndecodableStorage; impl pezframe_support::traits::OnRuntimeUpgrade for DeleteUndecodableStorage { fn on_runtime_upgrade() -> Weight { use pezsp_core::crypto::Ss58Codec; let mut writes = 0; // Remove Holds for account with undecodable hold // Zagros doesn't have any HoldReasons implemented yet, so it's safe to just blanket remove // any for this account. match AccountId::from_ss58check("5GCCJthVSwNXRpbeg44gysJUx9vzjdGdfWhioeM7gCg6VyXf") { Ok(a) => { tracing::info!(target: "bridges::on_runtime_upgrade", "Removing holds for account with bad hold"); pezpallet_balances::Holds::::remove(a); writes.saturating_inc(); }, Err(_) => { tracing::error!(target: "bridges::on_runtime_upgrade", "CleanupUndecodableStorage: Somehow failed to convert valid SS58 address into an AccountId!"); }, }; // Destroy undecodable NFT item 1 writes.saturating_inc(); match pezpallet_nfts::Pallet::::do_burn(3, 1, |_| Ok(())) { Ok(_) => { tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT item 1"); }, Err(e) => { tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT item"); return ::DbWeight::get().reads_writes(0, writes); }, } // Destroy undecodable NFT item 2 writes.saturating_inc(); match pezpallet_nfts::Pallet::::do_burn(3, 2, |_| Ok(())) { Ok(_) => { tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT item 2"); }, Err(e) => { tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT item"); return ::DbWeight::get().reads_writes(0, writes); }, } // Finally, we can destroy the collection writes.saturating_inc(); match pezpallet_nfts::Pallet::::do_destroy_collection( 3, DestroyWitness { attributes: 0, item_metadatas: 1, item_configs: 0 }, None, ) { Ok(_) => { tracing::info!(target: "bridges::on_runtime_upgrade", "Destroyed undecodable NFT collection"); }, Err(e) => { tracing::error!(target: "bridges::on_runtime_upgrade", error=?e, "Failed to destroy undecodable NFT collection"); }, }; ::DbWeight::get().reads_writes(0, writes) } } /// Migration to initialize storage versions for pallets added after genesis. /// /// Ideally this would be done automatically (see /// ), but it probably won't be ready for some /// time and it's beneficial to get try-runtime-cli on-runtime-upgrade checks into the CI, so we're /// doing it manually. pub struct InitStorageVersions; impl pezframe_support::traits::OnRuntimeUpgrade for InitStorageVersions { fn on_runtime_upgrade() -> Weight { use pezframe_support::traits::{GetStorageVersion, StorageVersion}; let mut writes = 0; if PezkuwiXcm::on_chain_storage_version() == StorageVersion::new(0) { PezkuwiXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) { ForeignAssets::in_code_storage_version().put::(); writes.saturating_inc(); } if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) { PoolAssets::in_code_storage_version().put::(); writes.saturating_inc(); } ::DbWeight::get().reads_writes(3, writes) } } /// Executive: handles dispatch to the various modules. pub type Executive = pezframe_executive::Executive< Runtime, Block, pezframe_system::ChainContext, Runtime, AllPalletsWithSystem, >; #[cfg(feature = "runtime-benchmarks")] pub struct AssetConversionTxHelper; #[cfg(feature = "runtime-benchmarks")] impl pezpallet_asset_conversion_tx_payment::BenchmarkHelperTrait< AccountId, pezcumulus_primitives_core::Location, pezcumulus_primitives_core::Location, > for AssetConversionTxHelper { fn create_asset_id_parameter( seed: u32, ) -> (pezcumulus_primitives_core::Location, pezcumulus_primitives_core::Location) { // Use a different teyrchain foreign assets pallet so that the asset is indeed foreign. let asset_id = pezcumulus_primitives_core::Location::new( 1, [ pezcumulus_primitives_core::Junction::Teyrchain(3000), pezcumulus_primitives_core::Junction::PalletInstance(53), pezcumulus_primitives_core::Junction::GeneralIndex(seed.into()), ], ); (asset_id.clone(), asset_id) } fn setup_balances_and_pool(asset_id: pezcumulus_primitives_core::Location, account: AccountId) { use pezframe_support::{assert_ok, traits::fungibles::Mutate}; assert_ok!(ForeignAssets::force_create( RuntimeOrigin::root(), asset_id.clone().into(), account.clone().into(), /* owner */ true, /* is_sufficient */ 1, )); let lp_provider = account.clone(); use pezframe_support::traits::Currency; let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into()); assert_ok!(ForeignAssets::mint_into( asset_id.clone().into(), &lp_provider, u64::MAX.into() )); let token_native = alloc::boxed::Box::new(pezcumulus_primitives_core::Location::new( 1, pezcumulus_primitives_core::Junctions::Here, )); let token_second = alloc::boxed::Box::new(asset_id); assert_ok!(AssetConversion::create_pool( RuntimeOrigin::signed(lp_provider.clone()), token_native.clone(), token_second.clone() )); assert_ok!(AssetConversion::add_liquidity( RuntimeOrigin::signed(lp_provider.clone()), token_native, token_second, (u32::MAX / 2).into(), // 1 desired u32::MAX.into(), // 2 desired 1, // 1 min 1, // 2 min lp_provider, )); } } #[cfg(feature = "runtime-benchmarks")] mod benches { pezframe_benchmarking::define_benchmarks!( [pezframe_system, SystemBench::] [pezframe_system_extensions, SystemExtensionsBench::] [pezpallet_asset_conversion_ops, AssetConversionMigration] [pezpallet_asset_rate, AssetRate] [pezpallet_assets, Local] [pezpallet_assets, Foreign] [pezpallet_assets, Pool] [pezpallet_asset_conversion, AssetConversion] [pezpallet_asset_rewards, AssetRewards] [pezpallet_asset_conversion_tx_payment, AssetTxPayment] [pezpallet_bags_list, VoterList] [pezpallet_balances, Balances] [pezpallet_conviction_voting, ConvictionVoting] [pezpallet_election_provider_multi_block, MultiBlockElection] [pezpallet_election_provider_multi_block::verifier, MultiBlockElectionVerifier] [pezpallet_election_provider_multi_block::unsigned, MultiBlockElectionUnsigned] [pezpallet_election_provider_multi_block::signed, MultiBlockElectionSigned] [pezpallet_message_queue, MessageQueue] [pezpallet_migrations, MultiBlockMigrations] [pezpallet_multisig, Multisig] [pezpallet_nft_fractionalization, NftFractionalization] [pezpallet_nfts, Nfts] [pezpallet_proxy, Proxy] [pezpallet_session, SessionBench::] [pezpallet_staking_async, Staking] [pezpallet_uniques, Uniques] [pezpallet_utility, Utility] [pezpallet_timestamp, Timestamp] [pezpallet_transaction_payment, TransactionPayment] [pezpallet_collator_selection, CollatorSelection] [pezcumulus_pezpallet_teyrchain_system, TeyrchainSystem] [pezcumulus_pezpallet_xcmp_queue, XcmpQueue] [pezpallet_treasury, Treasury] [pezpallet_vesting, Vesting] [pezpallet_whitelist, Whitelist] [pezpallet_xcm_bridge_hub_router, ToPezkuwichain] [pezpallet_asset_conversion_ops, AssetConversionMigration] [pezpallet_revive, Revive] // XCM [pezpallet_xcm, PalletXcmExtrinsicsBenchmark::] // NOTE: Make sure you point to the individual modules below. [pezpallet_xcm_benchmarks::fungible, XcmBalances] [pezpallet_xcm_benchmarks::generic, XcmGeneric] [pezcumulus_pezpallet_weight_reclaim, WeightReclaim] [snowbridge_pezpallet_system_frontend, SnowbridgeSystemFrontend] ); } pezpallet_revive::impl_runtime_apis_plus_revive_traits!( Runtime, Revive, Executive, EthExtraImpl, impl pezsp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> pezsp_consensus_aura::SlotDuration { pezsp_consensus_aura::SlotDuration::from_millis(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_core::GetTeyrchainInfo for Runtime { fn teyrchain_id() -> ParaId { TeyrchainInfo::teyrchain_id() } } impl pezcumulus_primitives_core::TargetBlockRate for Runtime { fn target_block_rate() -> u32 { 1 } } 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_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_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 pezframe_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Nonce { System::account_nonce(account) } } impl pezpallet_nfts_runtime_api::NftsApi for Runtime { fn owner(collection: u32, item: u32) -> Option { >::owner(&collection, &item) } fn collection_owner(collection: u32) -> Option { >::collection_owner(&collection) } fn attribute( collection: u32, item: u32, key: Vec, ) -> Option> { >::attribute(&collection, &item, &key) } fn custom_attribute( account: AccountId, collection: u32, item: u32, key: Vec, ) -> Option> { >::custom_attribute( &account, &collection, &item, &key, ) } fn system_attribute( collection: u32, item: Option, key: Vec, ) -> Option> { >::system_attribute(&collection, item.as_ref(), &key) } fn collection_attribute(collection: u32, key: Vec) -> Option> { >::collection_attribute(&collection, &key) } } impl pezpallet_asset_conversion::AssetConversionApi< Block, Balance, xcm::v5::Location, > for Runtime { fn quote_price_exact_tokens_for_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } fn quote_price_tokens_for_exact_tokens(asset1: xcm::v5::Location, asset2: xcm::v5::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } fn get_reserves(asset1: xcm::v5::Location, asset2: xcm::v5::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } impl pezpallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { fn query_info( uxt: ::Extrinsic, len: u32, ) -> pezpallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } fn query_fee_details( uxt: ::Extrinsic, len: u32, ) -> pezpallet_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 xcm_runtime_pezapis::fees::XcmPaymentApi for Runtime { fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result, XcmPaymentApiError> { let native_token = xcm_config::ZagrosLocation::get(); // We accept the native token to pay fees. let mut acceptable_assets = vec![AssetId(native_token.clone())]; // We also accept all assets in a pool with the native token. acceptable_assets.extend( assets_common::PoolAdapter::::get_assets_in_pool_with(native_token) .map_err(|()| XcmPaymentApiError::VersionedConversionFailed)? ); PezkuwiXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets) } fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result { type Trader = ::Trader; PezkuwiXcm::query_weight_to_asset_fee::(weight, asset) } fn query_xcm_weight(message: VersionedXcm<()>) -> Result { PezkuwiXcm::query_xcm_weight(message) } fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>, asset_id: VersionedAssetId) -> Result { type AssetExchanger = ::AssetExchanger; PezkuwiXcm::query_delivery_fees::(destination, message, asset_id) } } impl xcm_runtime_pezapis::dry_run::DryRunApi for Runtime { fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result, XcmDryRunApiError> { PezkuwiXcm::dry_run_call::(origin, call, result_xcms_version) } fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm) -> Result, XcmDryRunApiError> { PezkuwiXcm::dry_run_xcm::(origin_location, xcm) } } impl xcm_runtime_pezapis::conversions::LocationToAccountApi for Runtime { fn convert_location(location: VersionedLocation) -> Result< AccountId, xcm_runtime_pezapis::conversions::Error > { xcm_runtime_pezapis::conversions::LocationToAccountHelper::< AccountId, xcm_config::LocationToAccountId, >::convert_location(location) } } impl xcm_runtime_pezapis::trusted_query::TrustedQueryApi for Runtime { fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_pezapis::trusted_query::XcmTrustedQueryResult { PezkuwiXcm::is_trusted_reserve(asset, location) } fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_pezapis::trusted_query::XcmTrustedQueryResult { PezkuwiXcm::is_trusted_teleporter(asset, location) } } impl xcm_runtime_pezapis::authorized_aliases::AuthorizedAliasersApi for Runtime { fn authorized_aliasers(target: VersionedLocation) -> Result< Vec, xcm_runtime_pezapis::authorized_aliases::Error > { PezkuwiXcm::authorized_aliasers(target) } fn is_authorized_alias(origin: VersionedLocation, target: VersionedLocation) -> Result< bool, xcm_runtime_pezapis::authorized_aliases::Error > { PezkuwiXcm::is_authorized_alias(origin, target) } } impl pezpallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi for Runtime { fn query_call_info( call: RuntimeCall, len: u32, ) -> pezpallet_transaction_payment::RuntimeDispatchInfo { TransactionPayment::query_call_info(call, len) } fn query_call_fee_details( call: RuntimeCall, len: u32, ) -> pezpallet_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 assets_common::runtime_api::FungiblesApi< Block, AccountId, > for Runtime { fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pezpallet_balance { let balance = Balances::free_balance(account.clone()); if balance > 0 { vec![convert_balance::(balance)?] } else { vec![] } }, // collect pezpallet_assets (TrustBackedAssets) convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>( Assets::account_balances(account.clone()) .iter() .filter(|(_, balance)| balance > &0) )?, // collect pezpallet_assets (ForeignAssets) convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>( ForeignAssets::account_balances(account.clone()) .iter() .filter(|(_, balance)| balance > &0) )?, // collect pezpallet_assets (PoolAssets) convert::<_, _, _, _, PoolAssetsConvertedConcreteId>( PoolAssets::account_balances(account) .iter() .filter(|(_, balance)| balance > &0) )?, // collect ... e.g. other tokens ].concat().into()) } } impl pezcumulus_primitives_core::CollectCollationInfo for Runtime { fn collect_collation_info(header: &::Header) -> pezcumulus_primitives_core::CollationInfo { TeyrchainSystem::collect_collation_info(header) } } impl pezpallet_asset_rewards::AssetRewards for Runtime { fn pool_creation_cost() -> Balance { StakePoolCreationDeposit::get() } } #[cfg(feature = "try-runtime")] impl pezframe_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: pezframe_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { let weight = Executive::try_runtime_upgrade(checks).unwrap(); (weight, RuntimeBlockWeights::get().max_block) } fn execute_block( block: ::LazyBlock, state_root_check: bool, signature_check: bool, select: pezframe_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() } } impl pezpallet_nomination_pools_runtime_api::NominationPoolsApi< Block, AccountId, Balance, > for Runtime { fn pending_rewards(member: AccountId) -> Balance { NominationPools::api_pending_rewards(member).unwrap_or_default() } fn points_to_balance(pool_id: PoolId, points: Balance) -> Balance { NominationPools::api_points_to_balance(pool_id, points) } fn balance_to_points(pool_id: PoolId, new_funds: Balance) -> Balance { NominationPools::api_balance_to_points(pool_id, new_funds) } fn pool_pending_slash(pool_id: PoolId) -> Balance { NominationPools::api_pool_pending_slash(pool_id) } fn member_pending_slash(member: AccountId) -> Balance { NominationPools::api_member_pending_slash(member) } fn pool_needs_delegate_migration(pool_id: PoolId) -> bool { NominationPools::api_pool_needs_delegate_migration(pool_id) } fn member_needs_delegate_migration(member: AccountId) -> bool { NominationPools::api_member_needs_delegate_migration(member) } fn member_total_balance(member: AccountId) -> Balance { NominationPools::api_member_total_balance(member) } fn pool_balance(pool_id: PoolId) -> Balance { NominationPools::api_pool_balance(pool_id) } fn pool_accounts(pool_id: PoolId) -> (AccountId, AccountId) { NominationPools::api_pool_accounts(pool_id) } } impl pezpallet_staking_runtime_api::StakingApi for Runtime { fn nominations_quota(balance: Balance) -> u32 { Staking::api_nominations_quota(balance) } fn eras_stakers_page_count(era: pezsp_staking::EraIndex, account: AccountId) -> pezsp_staking::Page { Staking::api_eras_stakers_page_count(era, account) } fn pending_rewards(era: pezsp_staking::EraIndex, account: AccountId) -> bool { Staking::api_pending_rewards(era, 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::Pallet as SystemBench; use pezframe_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use pezcumulus_pezpallet_session_benchmarking::Pallet as SessionBench; use pezpallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use pezpallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; // This is defined once again in dispatch_benchmark, because list_benchmarks! // and add_benchmarks! are macros exported by define_benchmarks! macros and those types // are referenced in that call. type XcmBalances = pezpallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pezpallet_xcm_benchmarks::generic::Pallet::; // Benchmark files generated for `Assets/ForeignAssets` instances are by default // `pezpallet_assets_assets.rs / pezpallet_assets_foreign_assets`, which is not really nice, // so with this redefinition we can change names to nicer: // `pezpallet_assets_local.rs / pezpallet_assets_foreign.rs`. type Local = pezpallet_assets::Pallet::; type Foreign = pezpallet_assets::Pallet::; type Pool = pezpallet_assets::Pallet::; type ToPezkuwichain = XcmBridgeHubRouterBench; 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 pezframe_support::assert_ok; use pezsp_storage::TrackedStorageKey; use pezframe_system_benchmarking::Pallet as SystemBench; use pezframe_system_benchmarking::extensions::Pallet 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 pezcumulus_pezpallet_session_benchmarking::Pallet as SessionBench; use xcm_config::{MaxAssetsIntoHolding, ZagrosLocation}; impl pezcumulus_pezpallet_session_benchmarking::Config for Runtime {} use testnet_teyrchains_constants::zagros::locations::{PeopleParaId, PeopleLocation}; parameter_types! { pub ExistentialDepositAsset: Option = Some(( ZagrosLocation::get(), ExistentialDeposit::get() ).into()); pub RandomParaId: ParaId = ParaId::new(43211234); } use pezpallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pezpallet_xcm::benchmarking::Config for Runtime { type DeliveryHelper = ( pezkuwi_runtime_common::xcm_sender::ToTeyrchainDeliveryHelper< xcm_config::XcmConfig, ExistentialDepositAsset, PriceForSiblingTeyrchainDelivery, RandomParaId, TeyrchainSystem >, pezkuwi_runtime_common::xcm_sender::ToTeyrchainDeliveryHelper< xcm_config::XcmConfig, ExistentialDepositAsset, PriceForSiblingTeyrchainDelivery, PeopleParaId, TeyrchainSystem >); fn reachable_dest() -> Option { Some(PeopleLocation::get()) } fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(ZagrosLocation::get()) }, PeopleLocation::get(), )) } fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // We get an account to create USDT and give it enough ZGR to exist. let account = pezframe_benchmarking::whitelisted_caller(); assert_ok!(>::mint_into( &account, ExistentialDeposit::get() + (1_000 * UNITS) )); // We then create USDT. let usdt_id = 1984u32; let usdt_location = Location::new(0, [PalletInstance(50), GeneralIndex(usdt_id.into())]); assert_ok!(Assets::force_create( RuntimeOrigin::root(), usdt_id.into(), account.clone().into(), true, 1 )); // And return USDT as the reserve transferable asset. Some(( Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(usdt_location) }, ParentThen(Teyrchain(RandomParaId::get().into()).into()).into(), )) } fn set_up_complex_asset_transfer( ) -> Option<(XcmAssets, AssetId, Location, alloc::boxed::Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) let dest: Location = PeopleLocation::get(); let fee_amount = EXISTENTIAL_DEPOSIT; let fee_asset: Asset = (ZagrosLocation::get(), fee_amount).into(); let who = pezframe_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit let balance = fee_amount + EXISTENTIAL_DEPOSIT * 1000; let _ = >::make_free_balance_be( &who, balance, ); // verify initial balance assert_eq!(Balances::free_balance(&who), balance); // set up local asset let asset_amount = 10u128; let initial_asset_amount = asset_amount * 10; let (asset_id, _, _) = pezpallet_assets::benchmarking::create_default_minted_asset::< Runtime, pezpallet_assets::Instance1 >(true, initial_asset_amount); let asset_location = Location::new( 0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); let transfer_asset: Asset = (asset_location, asset_amount).into(); let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into(); let fee_asset_id = fee_asset.id; // verify transferred successfully let verify = alloc::boxed::Box::new(move || { // verify native balance after transfer, decreased by transferred fee amount // (plus transport fees) assert!(Balances::free_balance(&who) <= balance - fee_amount); // verify asset balance decreased by exactly transferred amount assert_eq!( Assets::balance(asset_id.into(), &who), initial_asset_amount - asset_amount, ); }); Some((assets, fee_asset_id, dest, verify)) } fn get_asset() -> Asset { use pezframe_benchmarking::whitelisted_caller; use pezframe_support::traits::tokens::fungible::{Inspect, Mutate}; let account = whitelisted_caller(); assert_ok!(>::mint_into( &account, >::minimum_balance(), )); let asset_id = 1984; assert_ok!(Assets::force_create( RuntimeOrigin::root(), asset_id.into(), account.into(), true, 1u128, )); let amount = 1_000_000u128; let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]); Asset { id: AssetId(asset_location), fun: Fungible(amount), } } } use pezpallet_xcm_bridge_hub_router::benchmarking::{ Pallet as XcmBridgeHubRouterBench, Config as XcmBridgeHubRouterConfig, }; impl XcmBridgeHubRouterConfig for Runtime { fn make_congested() { pezcumulus_pezpallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } fn ensure_bridged_target_destination() -> Result { TeyrchainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_pezkuwichain::AssetHubPezkuwichain::get(); let _ = PezkuwiXcm::force_xcm_version( RuntimeOrigin::root(), alloc::boxed::Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { tracing::error!( target: "bridges::benchmark", error=?e, origin=?RuntimeOrigin::root(), location=?bridged_asset_hub, version=?XCM_VERSION, "Failed to dispatch `force_xcm_version`" ); BenchmarkError::Stop("XcmVersion was not stored!") })?; Ok(bridged_asset_hub) } } use pezpallet_xcm_benchmarks::asset_instance_from; impl pezpallet_xcm_benchmarks::Config for Runtime { type XcmConfig = xcm_config::XcmConfig; type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = pezkuwi_runtime_common::xcm_sender::ToTeyrchainDeliveryHelper< xcm_config::XcmConfig, ExistentialDepositAsset, PriceForSiblingTeyrchainDelivery, PeopleParaId, TeyrchainSystem >; fn valid_destination() -> Result { Ok(PeopleLocation::get()) } fn worst_case_holding(depositable_count: u32) -> XcmAssets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles - 2; // -2 for two `iter::once` bellow let fungibles_amount: u128 = 100; (0..holding_fungibles) .map(|i| { Asset { id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * (i + 1) as u128), // non-zero amount } }) .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) .chain(core::iter::once(Asset { id: AssetId(ZagrosLocation::get()), fun: Fungible(1_000_000 * UNITS) })) .chain((0..holding_non_fungibles).map(|i| Asset { id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>() .into() } } parameter_types! { pub TrustedTeleporter: Option<(Location, Asset)> = Some(( PeopleLocation::get(), Asset { fun: Fungible(UNITS), id: AssetId(ZagrosLocation::get()) }, )); pub TrustedReserve: Option<(Location, Asset)> = Some({ use pezframe_support::traits::tokens::fungible::{Inspect, Mutate}; let roc_id = xcm_config::bridging::to_pezkuwichain::RocLocation::get(); let roc = Asset::from((roc_id.clone(), 1000000000000 as u128)); let reserve = xcm_config::bridging::to_pezkuwichain::AssetHubPezkuwichain::get(); let (account, _) = pezpallet_xcm_benchmarks::account_and_location::(1); assert_ok!(>::mint_into( &account, >::minimum_balance(), )); // register foreign TYRs assert_ok!(ForeignAssets::force_create( RuntimeOrigin::root(), roc_id.clone().into(), account.clone().into(), true, 1u128, )); let reserves = ForeignAssetReserveData { reserve, teleportable: false }; // set trusted reserve assert_ok!(ForeignAssets::set_reserves( RuntimeOrigin::signed(account), roc_id.clone().into(), vec![reserves.clone()], )); (reserves.reserve, roc) }); } impl pezpallet_xcm_benchmarks::fungible::Config for Runtime { type TransactAsset = Balances; type CheckedAccount = xcm_config::TeleportTracking; type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; fn get_asset() -> Asset { use pezframe_support::traits::tokens::fungible::{Inspect, Mutate}; let (account, _) = pezpallet_xcm_benchmarks::account_and_location::(1); assert_ok!(>::mint_into( &account, >::minimum_balance(), )); let asset_id = 1984; assert_ok!(Assets::force_create( RuntimeOrigin::root(), asset_id.into(), account.clone().into(), true, 1u128, )); let amount = 1_000_000u128; let asset_location = Location::new(0, [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())]); Asset { id: AssetId(asset_location), fun: Fungible(amount), } } } impl pezpallet_xcm_benchmarks::generic::Config for Runtime { type TransactAsset = Balances; type RuntimeCall = RuntimeCall; fn worst_case_response() -> (u64, Response) { (0u64, Response::Version(Default::default())) } fn worst_case_asset_exchange() -> Result<(XcmAssets, XcmAssets), BenchmarkError> { let native_asset_location = ZagrosLocation::get(); let native_asset_id = AssetId(native_asset_location.clone()); let (account, _) = pezpallet_xcm_benchmarks::account_and_location::(1); let origin = RuntimeOrigin::signed(account.clone()); let asset_location = Location::new(1, [Teyrchain(2001)]); let asset_id = AssetId(asset_location.clone()); assert_ok!(>::mint_into( &account, ExistentialDeposit::get() + (1_000 * UNITS) )); assert_ok!(ForeignAssets::force_create( RuntimeOrigin::root(), asset_location.clone().into(), account.clone().into(), true, 1, )); assert_ok!(ForeignAssets::mint( origin.clone(), asset_location.clone().into(), account.clone().into(), 3_000 * UNITS, )); assert_ok!(AssetConversion::create_pool( origin.clone(), native_asset_location.clone().into(), asset_location.clone().into(), )); assert_ok!(AssetConversion::add_liquidity( origin, native_asset_location.into(), asset_location.into(), 1_000 * UNITS, 2_000 * UNITS, 1, 1, account.into(), )); let give_assets: XcmAssets = (native_asset_id, 500 * UNITS).into(); let receive_assets: XcmAssets = (asset_id, 660 * UNITS).into(); Ok((give_assets, receive_assets)) } fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() .ok_or(BenchmarkError::Skip) } fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok(( PeopleLocation::get(), pezframe_system::Call::remark_with_event { remark: vec![] }.into() )) } fn subscribe_origin() -> Result { Ok(PeopleLocation::get()) } fn claimable_asset() -> Result<(Location, Location, XcmAssets), BenchmarkError> { let origin = PeopleLocation::get(); let assets: XcmAssets = (AssetId(ZagrosLocation::get()), 1_000 * UNITS).into(); let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> { Ok((Asset { id: AssetId(ZagrosLocation::get()), fun: Fungible(1_000 * UNITS), }, WeightLimit::Limited(Weight::from_parts(5000, 5000)))) } fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // Any location can alias to an internal location. // Here teyrchain 1001 aliases to an internal account. Ok(( Location::new(1, [Teyrchain(1001)]), Location::new(1, [Teyrchain(1001), AccountId32 { id: [111u8; 32], network: None }]), )) } } type XcmBalances = pezpallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pezpallet_xcm_benchmarks::generic::Pallet::; type Local = pezpallet_assets::Pallet::; type Foreign = pezpallet_assets::Pallet::; type Pool = pezpallet_assets::Pallet::; type ToPezkuwichain = XcmBridgeHubRouterBench; 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() } } ); pezcumulus_pezpallet_teyrchain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = pezcumulus_pezpallet_aura_ext::BlockExecutor::, } parameter_types! { // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) pub const MigrationSignedDepositPerItem: Balance = CENTS; pub const MigrationSignedDepositBase: Balance = 2_000 * CENTS; pub const MigrationMaxKeyLen: u32 = 512; } impl pezpallet_state_trie_migration::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type RuntimeHoldReason = RuntimeHoldReason; type SignedDepositPerItem = MigrationSignedDepositPerItem; type SignedDepositBase = MigrationSignedDepositBase; // An origin that can control the whole pallet: should be Root, or a part of your council. type ControlOrigin = pezframe_system::EnsureSignedBy; // specific account for the migration, can trigger the signed migrations. type SignedFilter = pezframe_system::EnsureSignedBy; // Replace this with weight based on your runtime. type WeightInfo = pezpallet_state_trie_migration::weights::BizinikiwiWeight; type MaxKeyLen = MigrationMaxKeyLen; } pezframe_support::ord_parameter_types! { pub const MigController: AccountId = AccountId::from(hex_literal::hex!("8458ed39dc4b6f6c7255f7bc42be50c2967db126357c999d44e12ca7ac80dc52")); pub const RootMigController: AccountId = AccountId::from(hex_literal::hex!("8458ed39dc4b6f6c7255f7bc42be50c2967db126357c999d44e12ca7ac80dc52")); } #[test] fn ensure_key_ss58() { use pezframe_support::traits::SortedMembers; use pezsp_core::crypto::Ss58Codec; let acc = AccountId::from_ss58check("5F4EbSkZz18X36xhbsjvDNs6NuZ82HyYtq5UiJ1h9SBHJXZD").unwrap(); assert_eq!(acc, MigController::sorted_members()[0]); let acc = AccountId::from_ss58check("5F4EbSkZz18X36xhbsjvDNs6NuZ82HyYtq5UiJ1h9SBHJXZD").unwrap(); assert_eq!(acc, RootMigController::sorted_members()[0]); }