12345678910111213141516171819#![cfg_attr(not(feature = "std"), no_std)]2021#![recursion_limit = "1024"]22#![allow(clippy::from_over_into, clippy::identity_op)]23#![allow(clippy::fn_to_numeric_cast_with_truncation)]2425#[cfg(feature = "std")]26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));2728use sp_api::impl_runtime_apis;29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_runtime::DispatchError;31use fp_self_contained::*;32333435use sp_runtime::{36 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,37 traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero, Member},38 transaction_validity::{TransactionSource, TransactionValidity},39 ApplyExtrinsicResult, RuntimeAppPublic,40};4142use sp_std::prelude::*;4344#[cfg(feature = "std")]45use sp_version::NativeVersion;46use sp_version::RuntimeVersion;47pub use pallet_transaction_payment::{48 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,49};5051pub use pallet_balances::Call as BalancesCall;52pub use pallet_evm::{53 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,54 OnMethodCall, Account as EVMAccount, FeeCalculator, GasWeightMapping,55};56pub use frame_support::{57 construct_runtime, match_types,58 dispatch::DispatchResult,59 PalletId, parameter_types, StorageValue, ConsensusEngineId,60 traits::{61 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,62 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,63 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,64 },65 weights::{66 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},67 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,68 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,69 WeightToFee,70 },71};72use pallet_unique_scheduler::DispatchCall;73use up_data_structs::{74 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits,75 CollectionStats, RpcCollection,76 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},77 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,78 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkCollectionId, RmrkNftId,79 RmrkNftChild, RmrkPropertyKey, RmrkResourceId, RmrkBaseId,80};81828384use frame_system::{85 self as frame_system, EnsureRoot, EnsureSigned,86 limits::{BlockWeights, BlockLength},87};88use sp_arithmetic::{89 traits::{BaseArithmetic, Unsigned},90};91use smallvec::smallvec;92use codec::{Encode, Decode};93use fp_rpc::TransactionStatus;94use sp_runtime::{95 traits::{96 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf,97 Saturating, CheckedConversion,98 },99 generic::Era,100 transaction_validity::TransactionValidityError,101 DispatchErrorWithPostInfo, SaturatedConversion,102};103104105pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;106107108use pallet_xcm::XcmPassthrough;109use polkadot_parachain::primitives::Sibling;110use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};111use xcm_builder::{112 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,113 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,114 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,115 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,116 ParentIsPreset,117};118use xcm_executor::{Config, XcmExecutor, Assets};119use sp_std::{cmp::Ordering, marker::PhantomData};120121use xcm::latest::{122 123 AssetId::{Concrete},124 Fungibility::Fungible as XcmFungible,125 MultiAsset,126 Error as XcmError,127};128use xcm_executor::traits::{MatchesFungible, WeightTrader};129130use unique_runtime_common::{131 impl_common_runtime_apis,132 types::*,133 constants::*,134 dispatch::{CollectionDispatchT, CollectionDispatch},135 sponsoring::UniqueSponsorshipHandler,136 eth_sponsoring::UniqueEthSponsorshipHandler,137 weights::CommonWeights,138};139140pub const RUNTIME_NAME: &str = "quartz";141pub const TOKEN_SYMBOL: &str = "QTZ";142143type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;144145impl RuntimeInstance for Runtime {146 type CrossAccountId = self::CrossAccountId;147148 type TransactionConverter = self::TransactionConverter;149150 fn get_transaction_converter() -> TransactionConverter {151 TransactionConverter152 }153}154155156157pub type AccountIndex = u32;158159160pub type Balance = u128;161162163pub type Index = u32;164165166pub type Hash = sp_core::H256;167168169pub type DigestItem = generic::DigestItem;170171172173174175pub mod opaque {176 use sp_std::prelude::*;177 use sp_runtime::impl_opaque_keys;178 use super::Aura;179180 pub use unique_runtime_common::types::*;181182 impl_opaque_keys! {183 pub struct SessionKeys {184 pub aura: Aura,185 }186 }187}188189190pub const VERSION: RuntimeVersion = RuntimeVersion {191 spec_name: create_runtime_str!(RUNTIME_NAME),192 impl_name: create_runtime_str!(RUNTIME_NAME),193 authoring_version: 1,194 spec_version: 924012,195 impl_version: 0,196 apis: RUNTIME_API_VERSIONS,197 transaction_version: 1,198 state_version: 0,199};200201#[derive(codec::Encode, codec::Decode)]202pub enum XCMPMessage<XAccountId, XBalance> {203 204 TransferToken(XAccountId, XBalance),205}206207208#[cfg(feature = "std")]209pub fn native_version() -> NativeVersion {210 NativeVersion {211 runtime_version: VERSION,212 can_author_with: Default::default(),213 }214}215216type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;217218pub struct DealWithFees;219impl OnUnbalanced<NegativeImbalance> for DealWithFees {220 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {221 if let Some(fees) = fees_then_tips.next() {222 223 let mut split = fees.ration(100, 0);224 if let Some(tips) = fees_then_tips.next() {225 226 tips.ration_merge_into(100, 0, &mut split);227 }228 Treasury::on_unbalanced(split.0);229 230 }231 }232}233234parameter_types! {235 pub const BlockHashCount: BlockNumber = 2400;236 pub RuntimeBlockLength: BlockLength =237 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);238 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);239 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;240 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()241 .base_block(BlockExecutionWeight::get())242 .for_class(DispatchClass::all(), |weights| {243 weights.base_extrinsic = ExtrinsicBaseWeight::get();244 })245 .for_class(DispatchClass::Normal, |weights| {246 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);247 })248 .for_class(DispatchClass::Operational, |weights| {249 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);250 251 252 weights.reserved = Some(253 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT254 );255 })256 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)257 .build_or_panic();258 pub const Version: RuntimeVersion = VERSION;259 pub const SS58Prefix: u8 = 255;260}261262parameter_types! {263 pub const ChainId: u64 = 8881;264}265266pub struct FixedFee;267impl FeeCalculator for FixedFee {268 fn min_gas_price() -> (U256, u64) {269 (MIN_GAS_PRICE.into(), 0)270 }271}272273274275276parameter_types! {277 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;278 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;279 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();280}281282283284285const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);286parameter_types! {287 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());288}289290pub enum FixedGasWeightMapping {}291impl GasWeightMapping for FixedGasWeightMapping {292 fn gas_to_weight(gas: u64) -> Weight {293 gas.saturating_mul(WeightPerGas::get())294 }295 fn weight_to_gas(weight: Weight) -> u64 {296 weight / WeightPerGas::get()297 }298}299300impl pallet_evm::account::Config for Runtime {301 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;302 type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;303 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;304}305306impl pallet_evm::Config for Runtime {307 type BlockGasLimit = BlockGasLimit;308 type FeeCalculator = FixedFee;309 type GasWeightMapping = FixedGasWeightMapping;310 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;311 type CallOrigin = EnsureAddressTruncated<Self>;312 type WithdrawOrigin = EnsureAddressTruncated<Self>;313 type AddressMapping = HashedAddressMapping<Self::Hashing>;314 type PrecompilesType = ();315 type PrecompilesValue = ();316 type Currency = Balances;317 type Event = Event;318 type OnMethodCall = (319 pallet_evm_migration::OnMethodCall<Self>,320 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,321 CollectionDispatchT<Self>,322 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,323 );324 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;325 type ChainId = ChainId;326 type Runner = pallet_evm::runner::stack::Runner<Self>;327 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;328 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;329 type FindAuthor = EthereumFindAuthor<Aura>;330}331332impl pallet_evm_migration::Config for Runtime {333 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;334}335336pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);337impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {338 fn find_author<'a, I>(digests: I) -> Option<H160>339 where340 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,341 {342 if let Some(author_index) = F::find_author(digests) {343 let authority_id = Aura::authorities()[author_index as usize].clone();344 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));345 }346 None347 }348}349350impl pallet_ethereum::Config for Runtime {351 type Event = Event;352 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;353}354355impl pallet_randomness_collective_flip::Config for Runtime {}356357impl frame_system::Config for Runtime {358 359 type AccountData = pallet_balances::AccountData<Balance>;360 361 type AccountId = AccountId;362 363 type BaseCallFilter = Everything;364 365 type BlockHashCount = BlockHashCount;366 367 type BlockLength = RuntimeBlockLength;368 369 type BlockNumber = BlockNumber;370 371 type BlockWeights = RuntimeBlockWeights;372 373 type Call = Call;374 375 type DbWeight = RocksDbWeight;376 377 type Event = Event;378 379 type Hash = Hash;380 381 type Hashing = BlakeTwo256;382 383 type Header = generic::Header<BlockNumber, BlakeTwo256>;384 385 type Index = Index;386 387 type Lookup = AccountIdLookup<AccountId, ()>;388 389 type OnKilledAccount = ();390 391 type OnNewAccount = ();392 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;393 394 type Origin = Origin;395 396 type PalletInfo = PalletInfo;397 398 type SS58Prefix = SS58Prefix;399 400 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;401 402 type Version = Version;403 type MaxConsumers = ConstU32<16>;404}405406parameter_types! {407 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;408}409410impl pallet_timestamp::Config for Runtime {411 412 type Moment = u64;413 type OnTimestampSet = ();414 type MinimumPeriod = MinimumPeriod;415 type WeightInfo = ();416}417418parameter_types! {419 420 pub const ExistentialDeposit: u128 = 0;421 pub const MaxLocks: u32 = 50;422 pub const MaxReserves: u32 = 50;423}424425impl pallet_balances::Config for Runtime {426 type MaxLocks = MaxLocks;427 type MaxReserves = MaxReserves;428 type ReserveIdentifier = [u8; 16];429 430 type Balance = Balance;431 432 type Event = Event;433 type DustRemoval = Treasury;434 type ExistentialDeposit = ExistentialDeposit;435 type AccountStore = System;436 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;437}438439pub const fn deposit(items: u32, bytes: u32) -> Balance {440 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE441}442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493parameter_types! {494 495 496 pub const OperationalFeeMultiplier: u8 = 5;497}498499500pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);501502impl<T> WeightToFeePolynomial for LinearFee<T>503where504 T: BaseArithmetic + From<u32> + Copy + Unsigned,505{506 type Balance = T;507508 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {509 smallvec!(WeightToFeeCoefficient {510 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),511 coeff_frac: Perbill::zero(),512 negative: false,513 degree: 1,514 })515 }516}517518impl pallet_transaction_payment::Config for Runtime {519 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;520 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;521 type OperationalFeeMultiplier = OperationalFeeMultiplier;522 type WeightToFee = LinearFee<Balance>;523 type FeeMultiplierUpdate = ();524}525526parameter_types! {527 pub const ProposalBond: Permill = Permill::from_percent(5);528 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;529 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;530 pub const SpendPeriod: BlockNumber = 5 * MINUTES;531 pub const Burn: Permill = Permill::from_percent(0);532 pub const TipCountdown: BlockNumber = 1 * DAYS;533 pub const TipFindersFee: Percent = Percent::from_percent(20);534 pub const TipReportDepositBase: Balance = 1 * UNIQUE;535 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;536 pub const BountyDepositBase: Balance = 1 * UNIQUE;537 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;538 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");539 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;540 pub const MaximumReasonLength: u32 = 16384;541 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);542 pub const BountyValueMinimum: Balance = 5 * UNIQUE;543 pub const MaxApprovals: u32 = 100;544}545546impl pallet_treasury::Config for Runtime {547 type PalletId = TreasuryModuleId;548 type Currency = Balances;549 type ApproveOrigin = EnsureRoot<AccountId>;550 type RejectOrigin = EnsureRoot<AccountId>;551 type Event = Event;552 type OnSlash = ();553 type ProposalBond = ProposalBond;554 type ProposalBondMinimum = ProposalBondMinimum;555 type ProposalBondMaximum = ProposalBondMaximum;556 type SpendPeriod = SpendPeriod;557 type Burn = Burn;558 type BurnDestination = ();559 type SpendFunds = ();560 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;561 type MaxApprovals = MaxApprovals;562}563564impl pallet_sudo::Config for Runtime {565 type Event = Event;566 type Call = Call;567}568569pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);570571impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider572 for RelayChainBlockNumberProvider<T>573{574 type BlockNumber = BlockNumber;575576 fn current_block_number() -> Self::BlockNumber {577 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()578 .map(|d| d.relay_parent_number)579 .unwrap_or_default()580 }581}582583parameter_types! {584 pub const MinVestedTransfer: Balance = 10 * UNIQUE;585 pub const MaxVestingSchedules: u32 = 28;586}587588impl orml_vesting::Config for Runtime {589 type Event = Event;590 type Currency = pallet_balances::Pallet<Runtime>;591 type MinVestedTransfer = MinVestedTransfer;592 type VestedTransferOrigin = EnsureSigned<AccountId>;593 type WeightInfo = ();594 type MaxVestingSchedules = MaxVestingSchedules;595 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;596}597598parameter_types! {599 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;600 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;601}602603impl cumulus_pallet_parachain_system::Config for Runtime {604 type Event = Event;605 type SelfParaId = parachain_info::Pallet<Self>;606 type OnSystemEvent = ();607 608 609 610 611 612 type OutboundXcmpMessageSource = XcmpQueue;613 type DmpMessageHandler = DmpQueue;614 type ReservedDmpWeight = ReservedDmpWeight;615 type ReservedXcmpWeight = ReservedXcmpWeight;616 type XcmpMessageHandler = XcmpQueue;617}618619impl parachain_info::Config for Runtime {}620621impl cumulus_pallet_aura_ext::Config for Runtime {}622623parameter_types! {624 pub const RelayLocation: MultiLocation = MultiLocation::parent();625 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;626 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();627 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();628}629630631632633pub type LocationToAccountId = (634 635 ParentIsPreset<AccountId>,636 637 SiblingParachainConvertsVia<Sibling, AccountId>,638 639 AccountId32Aliases<RelayNetwork, AccountId>,640);641642pub struct OnlySelfCurrency;643impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {644 fn matches_fungible(a: &MultiAsset) -> Option<B> {645 match (&a.id, &a.fun) {646 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),647 _ => None,648 }649 }650}651652653pub type LocalAssetTransactor = CurrencyAdapter<654 655 Balances,656 657 OnlySelfCurrency,658 659 LocationToAccountId,660 661 AccountId,662 663 (),664>;665666667668669pub type XcmOriginToTransactDispatchOrigin = (670 671 672 673 SovereignSignedViaLocation<LocationToAccountId, Origin>,674 675 676 RelayChainAsNative<RelayOrigin, Origin>,677 678 679 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,680 681 682 ParentAsSuperuser<Origin>,683 684 685 SignedAccountId32AsNative<RelayNetwork, Origin>,686 687 XcmPassthrough<Origin>,688);689690parameter_types! {691 692 pub UnitWeightCost: Weight = 1_000_000;693 694 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);695 pub const MaxInstructions: u32 = 100;696 pub const MaxAuthorities: u32 = 100_000;697}698699match_types! {700 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {701 MultiLocation { parents: 1, interior: Here } |702 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }703 };704}705706pub type Barrier = (707 TakeWeightCredit,708 AllowTopLevelPaidExecutionFrom<Everything>,709 710);711712pub struct UsingOnlySelfCurrencyComponents<713 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,714 AssetId: Get<MultiLocation>,715 AccountId,716 Currency: CurrencyT<AccountId>,717 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,718>(719 Weight,720 Currency::Balance,721 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,722);723impl<724 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,725 AssetId: Get<MultiLocation>,726 AccountId,727 Currency: CurrencyT<AccountId>,728 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,729 > WeightTrader730 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>731{732 fn new() -> Self {733 Self(0, Zero::zero(), PhantomData)734 }735736 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {737 let amount = WeightToFee::weight_to_fee(&weight);738 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;739740 741 let option1: xcm::v1::AssetId = Concrete(MultiLocation {742 parents: 1,743 interior: X1(Parachain(ParachainInfo::parachain_id().into())),744 });745 746 let option2: xcm::v1::AssetId = Concrete(MultiLocation {747 parents: 0,748 interior: Here,749 });750751 let required = if payment.fungible.contains_key(&option1) {752 (option1, u128_amount).into()753 } else if payment.fungible.contains_key(&option2) {754 (option2, u128_amount).into()755 } else {756 (Concrete(MultiLocation::default()), u128_amount).into()757 };758759 let unused = payment760 .checked_sub(required)761 .map_err(|_| XcmError::TooExpensive)?;762 self.0 = self.0.saturating_add(weight);763 self.1 = self.1.saturating_add(amount);764 Ok(unused)765 }766767 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {768 let weight = weight.min(self.0);769 let amount = WeightToFee::weight_to_fee(&weight);770 self.0 -= weight;771 self.1 = self.1.saturating_sub(amount);772 let amount: u128 = amount.saturated_into();773 if amount > 0 {774 Some((AssetId::get(), amount).into())775 } else {776 None777 }778 }779}780impl<781 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,782 AssetId: Get<MultiLocation>,783 AccountId,784 Currency: CurrencyT<AccountId>,785 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,786 > Drop787 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>788{789 fn drop(&mut self) {790 OnUnbalanced::on_unbalanced(Currency::issue(self.1));791 }792}793794pub struct XcmConfig;795impl Config for XcmConfig {796 type Call = Call;797 type XcmSender = XcmRouter;798 799 type AssetTransactor = LocalAssetTransactor;800 type OriginConverter = XcmOriginToTransactDispatchOrigin;801 type IsReserve = NativeAsset;802 type IsTeleporter = (); 803 type LocationInverter = LocationInverter<Ancestry>;804 type Barrier = Barrier;805 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;806 type Trader =807 UsingOnlySelfCurrencyComponents<LinearFee<Balance>, RelayLocation, AccountId, Balances, ()>;808 type ResponseHandler = (); 809 type SubscriptionService = PolkadotXcm;810811 type AssetTrap = PolkadotXcm;812 type AssetClaims = PolkadotXcm;813}814815816817818819820pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);821822823824pub type XcmRouter = (825 826 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,827 828 XcmpQueue,829);830831impl pallet_evm_coder_substrate::Config for Runtime {}832833impl pallet_xcm::Config for Runtime {834 type Event = Event;835 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;836 type XcmRouter = XcmRouter;837 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;838 type XcmExecuteFilter = Everything;839 type XcmExecutor = XcmExecutor<XcmConfig>;840 type XcmTeleportFilter = Everything;841 type XcmReserveTransferFilter = Everything;842 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;843 type LocationInverter = LocationInverter<Ancestry>;844 type Origin = Origin;845 type Call = Call;846 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;847 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;848}849850impl cumulus_pallet_xcm::Config for Runtime {851 type Event = Event;852 type XcmExecutor = XcmExecutor<XcmConfig>;853}854855impl cumulus_pallet_xcmp_queue::Config for Runtime {856 type WeightInfo = ();857 type Event = Event;858 type XcmExecutor = XcmExecutor<XcmConfig>;859 type ChannelInfo = ParachainSystem;860 type VersionWrapper = ();861 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;862 type ControllerOrigin = EnsureRoot<AccountId>;863 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;864}865866impl cumulus_pallet_dmp_queue::Config for Runtime {867 type Event = Event;868 type XcmExecutor = XcmExecutor<XcmConfig>;869 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;870}871872impl pallet_aura::Config for Runtime {873 type AuthorityId = AuraId;874 type DisabledValidators = ();875 type MaxAuthorities = MaxAuthorities;876}877878parameter_types! {879 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();880 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;881}882883impl pallet_common::Config for Runtime {884 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;885 type Event = Event;886 type Currency = Balances;887 type CollectionCreationPrice = CollectionCreationPrice;888 type TreasuryAccountId = TreasuryAccountId;889 type CollectionDispatch = CollectionDispatchT<Self>;890891 type EvmTokenAddressMapping = EvmTokenAddressMapping;892 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;893 type ContractAddress = EvmCollectionHelpersAddress;894}895896impl pallet_structure::Config for Runtime {897 type Event = Event;898 type Call = Call;899 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;900}901902impl pallet_fungible::Config for Runtime {903 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;904}905impl pallet_refungible::Config for Runtime {906 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;907}908impl pallet_nonfungible::Config for Runtime {909 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;910}911912913914915916917918919920921922impl pallet_unique::Config for Runtime {923 type Event = Event;924 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;925 type CommonWeightInfo = CommonWeights<Self>;926 type RefungibleExtensionsWeightInfo = CommonWeights<Self>;927}928929parameter_types! {930 pub const InflationBlockInterval: BlockNumber = 100; 931}932933934impl pallet_inflation::Config for Runtime {935 type Currency = Balances;936 type TreasuryAccountId = TreasuryAccountId;937 type InflationBlockInterval = InflationBlockInterval;938 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;939}940941parameter_types! {942 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *943 RuntimeBlockWeights::get().max_block;944 pub const MaxScheduledPerBlock: u32 = 50;945}946947type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;948use frame_support::traits::NamedReservableCurrency;949950fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {951 (952 frame_system::CheckSpecVersion::<Runtime>::new(),953 frame_system::CheckGenesis::<Runtime>::new(),954 frame_system::CheckEra::<Runtime>::from(Era::Immortal),955 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(956 from,957 )),958 frame_system::CheckWeight::<Runtime>::new(),959 960 961 )962}9639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051parameter_types! {1052 pub const NoPreimagePostponement: Option<u32> = Some(10);1053 pub const Preimage: Option<u32> = Some(10);1054}105510561057pub struct OriginPrivilegeCmp;10581059impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {1060 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {1061 Some(Ordering::Equal)1062 }1063}106410651066106710681069107010711072107310741075107610771078107910801081type EvmSponsorshipHandler = (1082 UniqueEthSponsorshipHandler<Runtime>,1083 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,1084);1085type SponsorshipHandler = (1086 UniqueSponsorshipHandler<Runtime>,1087 1088 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,1089);10901091impl pallet_evm_transaction_payment::Config for Runtime {1092 type EvmSponsorshipHandler = EvmSponsorshipHandler;1093 type Currency = Balances;1094}10951096impl pallet_charge_transaction::Config for Runtime {1097 type SponsorshipHandler = SponsorshipHandler;1098}109911001101110211031104parameter_types! {1105 1106 pub const HelpersContractAddress: H160 = H160([1107 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,1108 ]);11091110 1111 pub const EvmCollectionHelpersAddress: H160 = H160([1112 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,1113 ]);1114}11151116impl pallet_evm_contract_helpers::Config for Runtime {1117 type ContractAddress = HelpersContractAddress;1118 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1119}11201121construct_runtime!(1122 pub enum Runtime where1123 Block = Block,1124 NodeBlock = opaque::Block,1125 UncheckedExtrinsic = UncheckedExtrinsic1126 {1127 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,1128 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,11291130 Aura: pallet_aura::{Pallet, Config<T>} = 22,1131 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,11321133 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,1134 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,1135 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,1136 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,1137 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,1138 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,1139 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,1140 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,1141 1142 11431144 1145 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,1146 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,1147 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,1148 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,11491150 1151 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,1152 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,1153 1154 1155 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,1156 1157 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,1158 Fungible: pallet_fungible::{Pallet, Storage} = 67,1159 1160 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,1161 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,1162 1163 11641165 1166 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,1167 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,11681169 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,1170 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1171 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1172 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1173 }1174);11751176pub struct TransactionConverter;11771178impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {1179 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {1180 UncheckedExtrinsic::new_unsigned(1181 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1182 )1183 }1184}11851186impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {1187 fn convert_transaction(1188 &self,1189 transaction: pallet_ethereum::Transaction,1190 ) -> opaque::UncheckedExtrinsic {1191 let extrinsic = UncheckedExtrinsic::new_unsigned(1192 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1193 );1194 let encoded = extrinsic.encode();1195 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])1196 .expect("Encoded extrinsic is always valid")1197 }1198}119912001201pub type Address = sp_runtime::MultiAddress<AccountId, ()>;12021203pub type Header = generic::Header<BlockNumber, BlakeTwo256>;12041205pub type Block = generic::Block<Header, UncheckedExtrinsic>;12061207pub type SignedBlock = generic::SignedBlock<Block>;12081209pub type BlockId = generic::BlockId<Block>;12101211pub type SignedExtra = (1212 frame_system::CheckSpecVersion<Runtime>,1213 1214 frame_system::CheckGenesis<Runtime>,1215 frame_system::CheckEra<Runtime>,1216 frame_system::CheckNonce<Runtime>,1217 frame_system::CheckWeight<Runtime>,1218 ChargeTransactionPayment,1219 1220 pallet_ethereum::FakeTransactionFinalizer<Runtime>,1221);12221223pub type SignedExtraScheduler = (1224 frame_system::CheckSpecVersion<Runtime>,1225 frame_system::CheckGenesis<Runtime>,1226 frame_system::CheckEra<Runtime>,1227 frame_system::CheckNonce<Runtime>,1228 frame_system::CheckWeight<Runtime>,1229 1230);12311232pub type UncheckedExtrinsic =1233 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;12341235pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;12361237pub type Executive = frame_executive::Executive<1238 Runtime,1239 Block,1240 frame_system::ChainContext<Runtime>,1241 Runtime,1242 AllPalletsReversedWithSystemFirst,1243>;12441245impl_opaque_keys! {1246 pub struct SessionKeys {1247 pub aura: Aura,1248 }1249}12501251impl fp_self_contained::SelfContainedCall for Call {1252 type SignedInfo = H160;12531254 fn is_self_contained(&self) -> bool {1255 match self {1256 Call::Ethereum(call) => call.is_self_contained(),1257 _ => false,1258 }1259 }12601261 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {1262 match self {1263 Call::Ethereum(call) => call.check_self_contained(),1264 _ => None,1265 }1266 }12671268 fn validate_self_contained(1269 &self,1270 info: &Self::SignedInfo,1271 dispatch_info: &DispatchInfoOf<Call>,1272 len: usize,1273 ) -> Option<TransactionValidity> {1274 match self {1275 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),1276 _ => None,1277 }1278 }12791280 fn pre_dispatch_self_contained(1281 &self,1282 info: &Self::SignedInfo,1283 ) -> Option<Result<(), TransactionValidityError>> {1284 match self {1285 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),1286 _ => None,1287 }1288 }12891290 fn apply_self_contained(1291 self,1292 info: Self::SignedInfo,1293 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {1294 match self {1295 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(1296 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),1297 )),1298 _ => None,1299 }1300 }1301}13021303macro_rules! dispatch_unique_runtime {1304 ($collection:ident.$method:ident($($name:ident),*)) => {{1305 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1306 let dispatch = collection.as_dyn();13071308 Ok::<_, DispatchError>(dispatch.$method($($name),*))1309 }};1310}13111312impl_common_runtime_apis! {1313 #![custom_apis]13141315 impl rmrk_rpc::RmrkApi<1316 Block,1317 AccountId,1318 RmrkCollectionInfo<AccountId>,1319 RmrkInstanceInfo<AccountId>,1320 RmrkResourceInfo,1321 RmrkPropertyInfo,1322 RmrkBaseInfo<AccountId>,1323 RmrkPartType,1324 RmrkTheme1325 > for Runtime {1326 1327 1328 1329 13301331 1332 1333 13341335 1336 1337 13381339 1340 1341 13421343 1344 1345 13461347 1348 1349 13501351 1352 1353 13541355 1356 1357 13581359 1360 1361 13621363 1364 1365 13661367 1368 1369 13701371 1372 1373 13741375 1376 1377 1378 1379 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {1380 Ok(Default::default())1381 }13821383 fn collection_by_id(_collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {1384 Ok(Default::default())1385 }13861387 fn nft_by_id(_collection_id: RmrkCollectionId, _nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {1388 Ok(Default::default())1389 }13901391 fn account_tokens(_account_id: AccountId, _collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {1392 Ok(Default::default())1393 }13941395 fn nft_children(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {1396 Ok(Default::default())1397 }13981399 fn collection_properties(_collection_id: RmrkCollectionId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {1400 Ok(Default::default())1401 }14021403 fn nft_properties(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {1404 Ok(Default::default())1405 }14061407 fn nft_resources(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {1408 Ok(Default::default())1409 }14101411 fn nft_resource_priority(_collection_id: RmrkCollectionId, _nft_id: RmrkNftId, _resource_id: RmrkResourceId) -> Result<Option<u32>, DispatchError> {1412 Ok(Default::default())1413 }14141415 fn base(_base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {1416 Ok(Default::default())1417 }14181419 fn base_parts(_base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {1420 Ok(Default::default())1421 }14221423 fn theme_names(_base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {1424 Ok(Default::default())1425 }14261427 fn theme(_base_id: RmrkBaseId, _theme_name: RmrkThemeName, _filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {1428 Ok(Default::default())1429 }1430 1431 1432 }1433}14341435struct CheckInherents;14361437impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {1438 fn check_inherents(1439 block: &Block,1440 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,1441 ) -> sp_inherents::CheckInherentsResult {1442 let relay_chain_slot = relay_state_proof1443 .read_slot()1444 .expect("Could not read the relay chain slot from the proof");14451446 let inherent_data =1447 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(1448 relay_chain_slot,1449 sp_std::time::Duration::from_secs(6),1450 )1451 .create_inherent_data()1452 .expect("Could not create the timestamp inherent data");14531454 inherent_data.check_extrinsics(block)1455 }1456}14571458cumulus_pallet_parachain_system::register_validate_block!(1459 Runtime = Runtime,1460 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,1461 CheckInherents = CheckInherents,1462);