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::*;32use sp_runtime::traits::{Member};33343536use sp_runtime::{37 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,38 traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion, Zero},39 transaction_validity::{TransactionSource, TransactionValidity},40 ApplyExtrinsicResult, RuntimeAppPublic,41};4243use sp_std::prelude::*;4445#[cfg(feature = "std")]46use sp_version::NativeVersion;47use sp_version::RuntimeVersion;48pub use pallet_transaction_payment::{49 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,50};5152pub use pallet_balances::Call as BalancesCall;53pub use pallet_evm::{54 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _,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, 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 },70};71use pallet_unq_scheduler::DispatchCall;72use up_data_structs::*;737475use frame_system::{76 self as frame_system, EnsureRoot, EnsureSigned,77 limits::{BlockWeights, BlockLength},78};79use sp_arithmetic::{80 traits::{BaseArithmetic, Unsigned},81};82use smallvec::smallvec;8384use codec::{Encode, Decode};85use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping};86use fp_rpc::TransactionStatus;87use sp_runtime::{88 traits::{89 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating,90 CheckedConversion,91 },92 generic::Era,93 transaction_validity::TransactionValidityError,94 DispatchErrorWithPostInfo, SaturatedConversion,95};969798pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;99100101use pallet_xcm::XcmPassthrough;102use polkadot_parachain::primitives::Sibling;103use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};104use xcm_builder::{105 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,106 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,107 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,108 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,109 ParentIsPreset,110};111use xcm_executor::{Config, XcmExecutor, Assets};112use sp_std::{cmp::Ordering, marker::PhantomData};113114use xcm::latest::{115 116 AssetId::{Concrete},117 Fungibility::Fungible as XcmFungible,118 MultiAsset,119 Error as XcmError,120};121use xcm_executor::traits::{MatchesFungible, WeightTrader};122123124use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*};125126pub const RUNTIME_NAME: &str = "opal";127pub const TOKEN_SYMBOL: &str = "OPL";128129type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;130131impl RuntimeInstance for Runtime {132 type CrossAccountId = self::CrossAccountId;133 type TransactionConverter = self::TransactionConverter;134135 fn get_transaction_converter() -> TransactionConverter {136 TransactionConverter137 }138}139140141142pub type AccountIndex = u32;143144145pub type Balance = u128;146147148pub type Index = u32;149150151pub type Hash = sp_core::H256;152153154pub type DigestItem = generic::DigestItem;155156157158159160pub mod opaque {161 use sp_std::prelude::*;162 use sp_runtime::impl_opaque_keys;163 use super::Aura;164165 pub use unique_runtime_common::types::*;166167 impl_opaque_keys! {168 pub struct SessionKeys {169 pub aura: Aura,170 }171 }172}173174175pub const VERSION: RuntimeVersion = RuntimeVersion {176 spec_name: create_runtime_str!(RUNTIME_NAME),177 impl_name: create_runtime_str!(RUNTIME_NAME),178 authoring_version: 1,179 spec_version: 921000,180 impl_version: 0,181 apis: RUNTIME_API_VERSIONS,182 transaction_version: 1,183 state_version: 0,184};185186#[derive(codec::Encode, codec::Decode)]187pub enum XCMPMessage<XAccountId, XBalance> {188 189 TransferToken(XAccountId, XBalance),190}191192193#[cfg(feature = "std")]194pub fn native_version() -> NativeVersion {195 NativeVersion {196 runtime_version: VERSION,197 can_author_with: Default::default(),198 }199}200201type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;202203pub struct DealWithFees;204impl OnUnbalanced<NegativeImbalance> for DealWithFees {205 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {206 if let Some(fees) = fees_then_tips.next() {207 208 let mut split = fees.ration(100, 0);209 if let Some(tips) = fees_then_tips.next() {210 211 tips.ration_merge_into(100, 0, &mut split);212 }213 Treasury::on_unbalanced(split.0);214 215 }216 }217}218219parameter_types! {220 pub const BlockHashCount: BlockNumber = 2400;221 pub RuntimeBlockLength: BlockLength =222 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);223 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);224 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;225 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()226 .base_block(BlockExecutionWeight::get())227 .for_class(DispatchClass::all(), |weights| {228 weights.base_extrinsic = ExtrinsicBaseWeight::get();229 })230 .for_class(DispatchClass::Normal, |weights| {231 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);232 })233 .for_class(DispatchClass::Operational, |weights| {234 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);235 236 237 weights.reserved = Some(238 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT239 );240 })241 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)242 .build_or_panic();243 pub const Version: RuntimeVersion = VERSION;244 pub const SS58Prefix: u8 = 42;245}246247parameter_types! {248 pub const ChainId: u64 = 8882;249}250251pub struct FixedFee;252impl FeeCalculator for FixedFee {253 fn min_gas_price() -> U256 {254 MIN_GAS_PRICE.into()255 }256}257258259260261parameter_types! {262 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;263 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;264 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();265}266267268269270const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);271parameter_types! {272 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());273}274275pub enum FixedGasWeightMapping {}276impl GasWeightMapping for FixedGasWeightMapping {277 fn gas_to_weight(gas: u64) -> Weight {278 gas.saturating_mul(WeightPerGas::get())279 }280 fn weight_to_gas(weight: Weight) -> u64 {281 weight / WeightPerGas::get()282 }283}284285impl pallet_evm::account::Config for Runtime {286 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;287 type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;288 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;289}290291impl pallet_evm::Config for Runtime {292 type BlockGasLimit = BlockGasLimit;293 type FeeCalculator = FixedFee;294 type GasWeightMapping = FixedGasWeightMapping;295 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;296 type CallOrigin = EnsureAddressTruncated<Self>;297 type WithdrawOrigin = EnsureAddressTruncated<Self>;298 type AddressMapping = HashedAddressMapping<Self::Hashing>;299 type PrecompilesType = ();300 type PrecompilesValue = ();301 type Currency = Balances;302 type Event = Event;303 type OnMethodCall = (304 pallet_evm_migration::OnMethodCall<Self>,305 pallet_unique::UniqueErcSupport<Self>,306 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,307 );308 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;309 type ChainId = ChainId;310 type Runner = pallet_evm::runner::stack::Runner<Self>;311 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;312 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;313 type FindAuthor = EthereumFindAuthor<Aura>;314}315316impl pallet_evm_migration::Config for Runtime {317 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;318}319320pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);321impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {322 fn find_author<'a, I>(digests: I) -> Option<H160>323 where324 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,325 {326 if let Some(author_index) = F::find_author(digests) {327 let authority_id = Aura::authorities()[author_index as usize].clone();328 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));329 }330 None331 }332}333334impl pallet_ethereum::Config for Runtime {335 type Event = Event;336 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;337}338339impl pallet_randomness_collective_flip::Config for Runtime {}340341impl frame_system::Config for Runtime {342 343 type AccountData = pallet_balances::AccountData<Balance>;344 345 type AccountId = AccountId;346 347 type BaseCallFilter = Everything;348 349 type BlockHashCount = BlockHashCount;350 351 type BlockLength = RuntimeBlockLength;352 353 type BlockNumber = BlockNumber;354 355 type BlockWeights = RuntimeBlockWeights;356 357 type Call = Call;358 359 type DbWeight = RocksDbWeight;360 361 type Event = Event;362 363 type Hash = Hash;364 365 type Hashing = BlakeTwo256;366 367 type Header = generic::Header<BlockNumber, BlakeTwo256>;368 369 type Index = Index;370 371 type Lookup = AccountIdLookup<AccountId, ()>;372 373 type OnKilledAccount = ();374 375 type OnNewAccount = ();376 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;377 378 type Origin = Origin;379 380 type PalletInfo = PalletInfo;381 382 type SS58Prefix = SS58Prefix;383 384 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;385 386 type Version = Version;387 type MaxConsumers = ConstU32<16>;388}389390parameter_types! {391 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;392}393394impl pallet_timestamp::Config for Runtime {395 396 type Moment = u64;397 type OnTimestampSet = ();398 type MinimumPeriod = MinimumPeriod;399 type WeightInfo = ();400}401402parameter_types! {403 404 pub const ExistentialDeposit: u128 = 0;405 pub const MaxLocks: u32 = 50;406 pub const MaxReserves: u32 = 50;407}408409impl pallet_balances::Config for Runtime {410 type MaxLocks = MaxLocks;411 type MaxReserves = MaxReserves;412 type ReserveIdentifier = [u8; 16];413 414 type Balance = Balance;415 416 type Event = Event;417 type DustRemoval = Treasury;418 type ExistentialDeposit = ExistentialDeposit;419 type AccountStore = System;420 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;421}422423pub const fn deposit(items: u32, bytes: u32) -> Balance {424 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE425}426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477parameter_types! {478 479 480 pub const OperationalFeeMultiplier: u8 = 5;481}482483484pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);485486impl<T> WeightToFeePolynomial for LinearFee<T>487where488 T: BaseArithmetic + From<u32> + Copy + Unsigned,489{490 type Balance = T;491492 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {493 smallvec!(WeightToFeeCoefficient {494 495 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),496 coeff_frac: Perbill::zero(),497 negative: false,498 degree: 1,499 })500 }501}502503impl pallet_transaction_payment::Config for Runtime {504 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;505 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;506 type OperationalFeeMultiplier = OperationalFeeMultiplier;507 type WeightToFee = LinearFee<Balance>;508 type FeeMultiplierUpdate = ();509}510511parameter_types! {512 pub const ProposalBond: Permill = Permill::from_percent(5);513 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;514 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;515 pub const SpendPeriod: BlockNumber = 5 * MINUTES;516 pub const Burn: Permill = Permill::from_percent(0);517 pub const TipCountdown: BlockNumber = 1 * DAYS;518 pub const TipFindersFee: Percent = Percent::from_percent(20);519 pub const TipReportDepositBase: Balance = 1 * UNIQUE;520 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;521 pub const BountyDepositBase: Balance = 1 * UNIQUE;522 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;523 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");524 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;525 pub const MaximumReasonLength: u32 = 16384;526 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);527 pub const BountyValueMinimum: Balance = 5 * UNIQUE;528 pub const MaxApprovals: u32 = 100;529}530531impl pallet_treasury::Config for Runtime {532 type PalletId = TreasuryModuleId;533 type Currency = Balances;534 type ApproveOrigin = EnsureRoot<AccountId>;535 type RejectOrigin = EnsureRoot<AccountId>;536 type Event = Event;537 type OnSlash = ();538 type ProposalBond = ProposalBond;539 type ProposalBondMinimum = ProposalBondMinimum;540 type ProposalBondMaximum = ProposalBondMaximum;541 type SpendPeriod = SpendPeriod;542 type Burn = Burn;543 type BurnDestination = ();544 type SpendFunds = ();545 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;546 type MaxApprovals = MaxApprovals;547}548549impl pallet_sudo::Config for Runtime {550 type Event = Event;551 type Call = Call;552}553554pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);555556impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider557 for RelayChainBlockNumberProvider<T>558{559 type BlockNumber = BlockNumber;560561 fn current_block_number() -> Self::BlockNumber {562 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()563 .map(|d| d.relay_parent_number)564 .unwrap_or_default()565 }566}567568parameter_types! {569 pub const MinVestedTransfer: Balance = 10 * UNIQUE;570 pub const MaxVestingSchedules: u32 = 28;571}572573impl orml_vesting::Config for Runtime {574 type Event = Event;575 type Currency = pallet_balances::Pallet<Runtime>;576 type MinVestedTransfer = MinVestedTransfer;577 type VestedTransferOrigin = EnsureSigned<AccountId>;578 type WeightInfo = ();579 type MaxVestingSchedules = MaxVestingSchedules;580 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;581}582583parameter_types! {584 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;585 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;586}587588impl cumulus_pallet_parachain_system::Config for Runtime {589 type Event = Event;590 type SelfParaId = parachain_info::Pallet<Self>;591 type OnSystemEvent = ();592 593 594 595 596 597 type OutboundXcmpMessageSource = XcmpQueue;598 type DmpMessageHandler = DmpQueue;599 type ReservedDmpWeight = ReservedDmpWeight;600 type ReservedXcmpWeight = ReservedXcmpWeight;601 type XcmpMessageHandler = XcmpQueue;602}603604impl parachain_info::Config for Runtime {}605606impl cumulus_pallet_aura_ext::Config for Runtime {}607608parameter_types! {609 pub const RelayLocation: MultiLocation = MultiLocation::parent();610 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;611 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();612 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();613}614615616617618pub type LocationToAccountId = (619 620 ParentIsPreset<AccountId>,621 622 SiblingParachainConvertsVia<Sibling, AccountId>,623 624 AccountId32Aliases<RelayNetwork, AccountId>,625);626627pub struct OnlySelfCurrency;628impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {629 fn matches_fungible(a: &MultiAsset) -> Option<B> {630 match (&a.id, &a.fun) {631 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),632 _ => None,633 }634 }635}636637638pub type LocalAssetTransactor = CurrencyAdapter<639 640 Balances,641 642 OnlySelfCurrency,643 644 LocationToAccountId,645 646 AccountId,647 648 (),649>;650651652653654pub type XcmOriginToTransactDispatchOrigin = (655 656 657 658 SovereignSignedViaLocation<LocationToAccountId, Origin>,659 660 661 RelayChainAsNative<RelayOrigin, Origin>,662 663 664 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,665 666 667 ParentAsSuperuser<Origin>,668 669 670 SignedAccountId32AsNative<RelayNetwork, Origin>,671 672 XcmPassthrough<Origin>,673);674675parameter_types! {676 677 pub UnitWeightCost: Weight = 1_000_000;678 679 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);680 pub const MaxInstructions: u32 = 100;681 pub const MaxAuthorities: u32 = 100_000;682}683684match_types! {685 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {686 MultiLocation { parents: 1, interior: Here } |687 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }688 };689}690691pub type Barrier = (692 TakeWeightCredit,693 AllowTopLevelPaidExecutionFrom<Everything>,694 AllowUnpaidExecutionFrom<ParentOrParentsUnitPlurality>,695 696);697698pub struct UsingOnlySelfCurrencyComponents<699 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,700 AssetId: Get<MultiLocation>,701 AccountId,702 Currency: CurrencyT<AccountId>,703 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,704>(705 Weight,706 Currency::Balance,707 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,708);709impl<710 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,711 AssetId: Get<MultiLocation>,712 AccountId,713 Currency: CurrencyT<AccountId>,714 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,715 > WeightTrader716 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>717{718 fn new() -> Self {719 Self(0, Zero::zero(), PhantomData)720 }721722 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {723 let amount = WeightToFee::calc(&weight);724 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;725726 727 let option1: xcm::v1::AssetId = Concrete(MultiLocation {728 parents: 1,729 interior: X1(Parachain(ParachainInfo::parachain_id().into())),730 });731 732 let option2: xcm::v1::AssetId = Concrete(MultiLocation {733 parents: 0,734 interior: Here,735 });736737 let required = if payment.fungible.contains_key(&option1) {738 (option1, u128_amount).into()739 } else if payment.fungible.contains_key(&option2) {740 (option2, u128_amount).into()741 } else {742 (Concrete(MultiLocation::default()), u128_amount).into()743 };744745 let unused = payment746 .checked_sub(required)747 .map_err(|_| XcmError::TooExpensive)?;748 self.0 = self.0.saturating_add(weight);749 self.1 = self.1.saturating_add(amount);750 Ok(unused)751 }752753 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {754 let weight = weight.min(self.0);755 let amount = WeightToFee::calc(&weight);756 self.0 -= weight;757 self.1 = self.1.saturating_sub(amount);758 let amount: u128 = amount.saturated_into();759 if amount > 0 {760 Some((AssetId::get(), amount).into())761 } else {762 None763 }764 }765}766impl<767 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,768 AssetId: Get<MultiLocation>,769 AccountId,770 Currency: CurrencyT<AccountId>,771 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,772 > Drop773 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>774{775 fn drop(&mut self) {776 OnUnbalanced::on_unbalanced(Currency::issue(self.1));777 }778}779780pub struct XcmConfig;781impl Config for XcmConfig {782 type Call = Call;783 type XcmSender = XcmRouter;784 785 type AssetTransactor = LocalAssetTransactor;786 type OriginConverter = XcmOriginToTransactDispatchOrigin;787 type IsReserve = NativeAsset;788 type IsTeleporter = (); 789 type LocationInverter = LocationInverter<Ancestry>;790 type Barrier = Barrier;791 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;792 type Trader = UsingOnlySelfCurrencyComponents<793 IdentityFee<Balance>,794 RelayLocation,795 AccountId,796 Balances,797 (),798 >;799 type ResponseHandler = (); 800 type SubscriptionService = PolkadotXcm;801802 type AssetTrap = PolkadotXcm;803 type AssetClaims = PolkadotXcm;804}805806807808809810811pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);812813814815pub type XcmRouter = (816 817 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,818 819 XcmpQueue,820);821822impl pallet_evm_coder_substrate::Config for Runtime {823 type EthereumTransactionSender = pallet_ethereum::Pallet<Self>;824 type GasWeightMapping = FixedGasWeightMapping;825}826827impl pallet_xcm::Config for Runtime {828 type Event = Event;829 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;830 type XcmRouter = XcmRouter;831 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;832 type XcmExecuteFilter = Everything;833 type XcmExecutor = XcmExecutor<XcmConfig>;834 type XcmTeleportFilter = Everything;835 type XcmReserveTransferFilter = Everything;836 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;837 type LocationInverter = LocationInverter<Ancestry>;838 type Origin = Origin;839 type Call = Call;840 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;841 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;842}843844impl cumulus_pallet_xcm::Config for Runtime {845 type Event = Event;846 type XcmExecutor = XcmExecutor<XcmConfig>;847}848849impl cumulus_pallet_xcmp_queue::Config for Runtime {850 type WeightInfo = ();851 type Event = Event;852 type XcmExecutor = XcmExecutor<XcmConfig>;853 type ChannelInfo = ParachainSystem;854 type VersionWrapper = ();855 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;856 type ControllerOrigin = EnsureRoot<AccountId>;857 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;858}859860impl cumulus_pallet_dmp_queue::Config for Runtime {861 type Event = Event;862 type XcmExecutor = XcmExecutor<XcmConfig>;863 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;864}865866impl pallet_aura::Config for Runtime {867 type AuthorityId = AuraId;868 type DisabledValidators = ();869 type MaxAuthorities = MaxAuthorities;870}871872parameter_types! {873 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account();874 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;875}876877impl pallet_common::Config for Runtime {878 type Event = Event;879 type Currency = Balances;880 type CollectionCreationPrice = CollectionCreationPrice;881 type TreasuryAccountId = TreasuryAccountId;882}883884impl pallet_fungible::Config for Runtime {885 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;886}887impl pallet_refungible::Config for Runtime {888 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;889}890impl pallet_nonfungible::Config for Runtime {891 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;892}893894impl pallet_unique::Config for Runtime {895 type Event = Event;896 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;897}898899parameter_types! {900 pub const InflationBlockInterval: BlockNumber = 100; 901}902903904impl pallet_inflation::Config for Runtime {905 type Currency = Balances;906 type TreasuryAccountId = TreasuryAccountId;907 type InflationBlockInterval = InflationBlockInterval;908 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;909}910911parameter_types! {912 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *913 RuntimeBlockWeights::get().max_block;914 pub const MaxScheduledPerBlock: u32 = 50;915}916917type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;918use frame_support::traits::NamedReservableCurrency;919920fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {921 (922 frame_system::CheckSpecVersion::<Runtime>::new(),923 frame_system::CheckGenesis::<Runtime>::new(),924 frame_system::CheckEra::<Runtime>::from(Era::Immortal),925 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(926 from,927 )),928 frame_system::CheckWeight::<Runtime>::new(),929 930 931 )932}933934pub struct SchedulerPaymentExecutor;935impl<T: frame_system::Config + pallet_unq_scheduler::Config, SelfContainedSignedInfo>936 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor937where938 <T as frame_system::Config>::Call: Member939 + Dispatchable<Origin = Origin, Info = DispatchInfo>940 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>941 + GetDispatchInfo942 + From<frame_system::Call<Runtime>>,943 SelfContainedSignedInfo: Send + Sync + 'static,944 Call: From<<T as frame_system::Config>::Call>945 + From<<T as pallet_unq_scheduler::Config>::Call>946 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,947 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,948{949 fn dispatch_call(950 signer: <T as frame_system::Config>::AccountId,951 call: <T as pallet_unq_scheduler::Config>::Call,952 ) -> Result<953 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,954 TransactionValidityError,955 > {956 let dispatch_info = call.get_dispatch_info();957 let extrinsic = fp_self_contained::CheckedExtrinsic::<958 AccountId,959 Call,960 SignedExtraScheduler,961 SelfContainedSignedInfo,962 > {963 signed:964 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(965 signer.clone().into(),966 get_signed_extras(signer.into()),967 ),968 function: call.into(),969 };970971 extrinsic.apply::<Runtime>(&dispatch_info, 0)972 }973974 fn reserve_balance(975 id: [u8; 16],976 sponsor: <T as frame_system::Config>::AccountId,977 call: <T as pallet_unq_scheduler::Config>::Call,978 count: u32,979 ) -> Result<(), DispatchError> {980 let dispatch_info = call.get_dispatch_info();981 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)982 .saturating_mul(count.into());983984 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(985 &id,986 &(sponsor.into()),987 weight,988 )989 }990991 fn pay_for_call(992 id: [u8; 16],993 sponsor: <T as frame_system::Config>::AccountId,994 call: <T as pallet_unq_scheduler::Config>::Call,995 ) -> Result<u128, DispatchError> {996 let dispatch_info = call.get_dispatch_info();997 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);998 Ok(999 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1000 &id,1001 &(sponsor.into()),1002 weight,1003 ),1004 )1005 }10061007 fn cancel_reserve(1008 id: [u8; 16],1009 sponsor: <T as frame_system::Config>::AccountId,1010 ) -> Result<u128, DispatchError> {1011 Ok(1012 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1013 &id,1014 &(sponsor.into()),1015 u128::MAX,1016 ),1017 )1018 }1019}10201021parameter_types! {1022 pub const NoPreimagePostponement: Option<u32> = Some(10);1023 pub const Preimage: Option<u32> = Some(10);1024}102510261027pub struct OriginPrivilegeCmp;10281029impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {1030 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {1031 Some(Ordering::Equal)1032 }1033}10341035impl pallet_unq_scheduler::Config for Runtime {1036 type Event = Event;1037 type Origin = Origin;1038 type Currency = Balances;1039 type PalletsOrigin = OriginCaller;1040 type Call = Call;1041 type MaximumWeight = MaximumSchedulerWeight;1042 type ScheduleOrigin = EnsureSigned<AccountId>;1043 type MaxScheduledPerBlock = MaxScheduledPerBlock;1044 type WeightInfo = ();1045 type CallExecutor = SchedulerPaymentExecutor;1046 type OriginPrivilegeCmp = OriginPrivilegeCmp;1047 type PreimageProvider = ();1048 type NoPreimagePostponement = NoPreimagePostponement;1049}10501051type EvmSponsorshipHandler = (1052 pallet_unique::UniqueEthSponsorshipHandler<Runtime>,1053 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,1054);10551056type SponsorshipHandler = (1057 pallet_unique::UniqueSponsorshipHandler<Runtime>,1058 1059 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,1060);10611062impl pallet_evm_transaction_payment::Config for Runtime {1063 type EvmSponsorshipHandler = EvmSponsorshipHandler;1064 type Currency = Balances;1065}10661067impl pallet_charge_transaction::Config for Runtime {1068 type SponsorshipHandler = SponsorshipHandler;1069}107010711072107310741075parameter_types! {1076 1077 pub const HelpersContractAddress: H160 = H160([1078 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,1079 ]);1080}10811082impl pallet_evm_contract_helpers::Config for Runtime {1083 type ContractAddress = HelpersContractAddress;1084 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1085}10861087construct_runtime!(1088 pub enum Runtime where1089 Block = Block,1090 NodeBlock = opaque::Block,1091 UncheckedExtrinsic = UncheckedExtrinsic1092 {1093 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,1094 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,10951096 Aura: pallet_aura::{Pallet, Config<T>} = 22,1097 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,10981099 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,1100 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,1101 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,1102 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,1103 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,1104 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,1105 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,1106 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,1107 1108 11091110 1111 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,1112 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,1113 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,1114 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,11151116 1117 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,1118 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,1119 Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event<T>} = 62,1120 1121 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,1122 1123 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,1124 Fungible: pallet_fungible::{Pallet, Storage} = 67,1125 Refungible: pallet_refungible::{Pallet, Storage} = 68,1126 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,11271128 1129 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,1130 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,11311132 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,1133 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1134 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1135 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1136 }1137);11381139pub struct TransactionConverter;11401141impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {1142 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {1143 UncheckedExtrinsic::new_unsigned(1144 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1145 )1146 }1147}11481149impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {1150 fn convert_transaction(1151 &self,1152 transaction: pallet_ethereum::Transaction,1153 ) -> opaque::UncheckedExtrinsic {1154 let extrinsic = UncheckedExtrinsic::new_unsigned(1155 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1156 );1157 let encoded = extrinsic.encode();1158 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])1159 .expect("Encoded extrinsic is always valid")1160 }1161}116211631164pub type Address = sp_runtime::MultiAddress<AccountId, ()>;11651166pub type Header = generic::Header<BlockNumber, BlakeTwo256>;11671168pub type Block = generic::Block<Header, UncheckedExtrinsic>;11691170pub type SignedBlock = generic::SignedBlock<Block>;11711172pub type BlockId = generic::BlockId<Block>;11731174pub type SignedExtra = (1175 frame_system::CheckSpecVersion<Runtime>,1176 1177 frame_system::CheckGenesis<Runtime>,1178 frame_system::CheckEra<Runtime>,1179 frame_system::CheckNonce<Runtime>,1180 frame_system::CheckWeight<Runtime>,1181 ChargeTransactionPayment,1182 1183);1184pub type SignedExtraScheduler = (1185 frame_system::CheckSpecVersion<Runtime>,1186 frame_system::CheckGenesis<Runtime>,1187 frame_system::CheckEra<Runtime>,1188 frame_system::CheckNonce<Runtime>,1189 frame_system::CheckWeight<Runtime>,1190);11911192pub type UncheckedExtrinsic =1193 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;11941195pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;11961197pub type Executive = frame_executive::Executive<1198 Runtime,1199 Block,1200 frame_system::ChainContext<Runtime>,1201 Runtime,1202 AllPalletsReversedWithSystemFirst,1203>;12041205impl_opaque_keys! {1206 pub struct SessionKeys {1207 pub aura: Aura,1208 }1209}12101211impl fp_self_contained::SelfContainedCall for Call {1212 type SignedInfo = H160;12131214 fn is_self_contained(&self) -> bool {1215 match self {1216 Call::Ethereum(call) => call.is_self_contained(),1217 _ => false,1218 }1219 }12201221 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {1222 match self {1223 Call::Ethereum(call) => call.check_self_contained(),1224 _ => None,1225 }1226 }12271228 fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option<TransactionValidity> {1229 match self {1230 Call::Ethereum(call) => call.validate_self_contained(info),1231 _ => None,1232 }1233 }12341235 fn pre_dispatch_self_contained(1236 &self,1237 info: &Self::SignedInfo,1238 ) -> Option<Result<(), TransactionValidityError>> {1239 match self {1240 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),1241 _ => None,1242 }1243 }12441245 fn apply_self_contained(1246 self,1247 info: Self::SignedInfo,1248 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {1249 match self {1250 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(1251 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),1252 )),1253 _ => None,1254 }1255 }1256}12571258macro_rules! dispatch_unique_runtime {1259 ($collection:ident.$method:ident($($name:ident),*)) => {{1260 use pallet_unique::dispatch::Dispatched;12611262 let collection = Dispatched::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1263 let dispatch = collection.as_dyn();12641265 Ok(dispatch.$method($($name),*))1266 }};1267}12681269impl_common_runtime_apis!();12701271struct CheckInherents;12721273impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {1274 fn check_inherents(1275 block: &Block,1276 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,1277 ) -> sp_inherents::CheckInherentsResult {1278 let relay_chain_slot = relay_state_proof1279 .read_slot()1280 .expect("Could not read the relay chain slot from the proof");12811282 let inherent_data =1283 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(1284 relay_chain_slot,1285 sp_std::time::Duration::from_secs(6),1286 )1287 .create_inherent_data()1288 .expect("Could not create the timestamp inherent data");12891290 inherent_data.check_extrinsics(block)1291 }1292}12931294cumulus_pallet_parachain_system::register_validate_block!(1295 Runtime = Runtime,1296 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,1297 CheckInherents = CheckInherents,1298);