git.delta.rocks / unique-network / refs/commits / db76f2017ca8

difftreelog

source

runtime/src/lib.rs54.3 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.1819#![cfg_attr(not(feature = "std"), no_std)]20// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.21#![recursion_limit = "1024"]22#![allow(clippy::from_over_into, clippy::identity_op)]23#![allow(clippy::fn_to_numeric_cast_with_truncation)]24// Make the WASM binary available.25#[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;31// #[cfg(any(feature = "std", test))]32// pub use sp_runtime::BuildStorage;3334use sp_runtime::{35	Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,36	traits::{37		AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify,38		AccountIdConversion, Zero,39	},40	transaction_validity::{TransactionSource, TransactionValidity},41	ApplyExtrinsicResult, MultiSignature, RuntimeAppPublic,42};4344use sp_std::prelude::*;4546#[cfg(feature = "std")]47use sp_version::NativeVersion;48use sp_version::RuntimeVersion;49pub use pallet_transaction_payment::{50	Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,51};52// A few exports that help ease life for downstream crates.53pub use pallet_balances::Call as BalancesCall;54pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner};55pub use frame_support::{56	construct_runtime, match_type,57	dispatch::DispatchResult,58	PalletId, parameter_types, StorageValue, ConsensusEngineId,59	traits::{60		tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,61		Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,62		OnUnbalanced, Randomness, FindAuthor,63	},64	weights::{65		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},66		DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,67		WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,68	},69};70use up_data_structs::*;71// use pallet_contracts::weights::WeightInfo;72// #[cfg(any(feature = "std", test))]73use frame_system::{74	self as frame_system, EnsureRoot, EnsureSigned,75	limits::{BlockWeights, BlockLength},76};77use sp_arithmetic::{78	traits::{BaseArithmetic, Unsigned},79};80use smallvec::smallvec;81use codec::{Encode, Decode};82use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall};83use fp_rpc::TransactionStatus;84use sp_runtime::{85	traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating},86	transaction_validity::TransactionValidityError,87	SaturatedConversion,88};8990// pub use pallet_timestamp::Call as TimestampCall;91pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;9293// Polkadot imports94use pallet_xcm::XcmPassthrough;95use polkadot_parachain::primitives::Sibling;96use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};97use xcm_builder::{98	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,99	EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,100	RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,101	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,102	ParentIsPreset,103};104use xcm_executor::{Config, XcmExecutor, Assets};105use sp_std::{marker::PhantomData};106107use xcm::latest::{108	//	Xcm,109	AssetId::{Concrete},110	Fungibility::Fungible as XcmFungible,111	MultiAsset,112	Error as XcmError,113};114use xcm_executor::traits::{MatchesFungible, WeightTrader};115//use xcm_executor::traits::MatchesFungible;116use sp_runtime::traits::CheckedConversion;117118// mod chain_extension;119// use crate::chain_extension::{NFTExtension, Imbalance};120121/// An index to a block.122pub type BlockNumber = u32;123124/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.125pub type Signature = MultiSignature;126127/// Some way of identifying an account on the chain. We intentionally make it equivalent128/// to the public key of our transaction signing scheme.129pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;130131pub type CrossAccountId = pallet_common::account::BasicCrossAccountId<Runtime>;132133/// The type for looking up accounts. We don't expect more than 4 billion of them, but you134/// never know...135pub type AccountIndex = u32;136137/// Balance of an account.138pub type Balance = u128;139140/// Index of a transaction in the chain.141pub type Index = u32;142143/// A hash of some data used by the chain.144pub type Hash = sp_core::H256;145146/// Digest item type.147pub type DigestItem = generic::DigestItem;148149/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know150/// the specifics of the runtime. They can then be made to be agnostic over specific formats151/// of data like extrinsics, allowing for them to continue syncing the network through upgrades152/// to even the core data structures.153pub mod opaque {154	use super::*;155156	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;157158	/// Opaque block type.159	pub type Block = generic::Block<Header, UncheckedExtrinsic>;160161	pub type SessionHandlers = ();162163	impl_opaque_keys! {164		pub struct SessionKeys {165			pub aura: Aura,166		}167	}168}169170/// This runtime version.171pub const VERSION: RuntimeVersion = RuntimeVersion {172	spec_name: create_runtime_str!("quartz"),173	impl_name: create_runtime_str!("quartz"),174	authoring_version: 1,175	spec_version: 917004,176	impl_version: 0,177	apis: RUNTIME_API_VERSIONS,178	transaction_version: 1,179	state_version: 0,180};181182pub const MILLISECS_PER_BLOCK: u64 = 12000;183184pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;185186// These time units are defined in number of blocks.187pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);188pub const HOURS: BlockNumber = MINUTES * 60;189pub const DAYS: BlockNumber = HOURS * 24;190191parameter_types! {192	pub const DefaultSponsoringRateLimit: BlockNumber = 1 * DAYS;193}194195#[derive(codec::Encode, codec::Decode)]196pub enum XCMPMessage<XAccountId, XBalance> {197	/// Transfer tokens to the given account from the Parachain account.198	TransferToken(XAccountId, XBalance),199}200201/// The version information used to identify this runtime when compiled natively.202#[cfg(feature = "std")]203pub fn native_version() -> NativeVersion {204	NativeVersion {205		runtime_version: VERSION,206		can_author_with: Default::default(),207	}208}209210type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;211212pub struct DealWithFees;213impl OnUnbalanced<NegativeImbalance> for DealWithFees {214	fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {215		if let Some(fees) = fees_then_tips.next() {216			// for fees, 100% to treasury217			let mut split = fees.ration(100, 0);218			if let Some(tips) = fees_then_tips.next() {219				// for tips, if any, 100% to treasury220				tips.ration_merge_into(100, 0, &mut split);221			}222			Treasury::on_unbalanced(split.0);223			// Author::on_unbalanced(split.1);224		}225	}226}227228/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.229/// This is used to limit the maximal weight of a single extrinsic.230const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);231/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used232/// by  Operational  extrinsics.233const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);234/// We allow for 2 seconds of compute with a 6 second average block time.235const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2;236237parameter_types! {238	pub const BlockHashCount: BlockNumber = 2400;239	pub RuntimeBlockLength: BlockLength =240		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);241	pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);242	pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;243	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()244		.base_block(BlockExecutionWeight::get())245		.for_class(DispatchClass::all(), |weights| {246			weights.base_extrinsic = ExtrinsicBaseWeight::get();247		})248		.for_class(DispatchClass::Normal, |weights| {249			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);250		})251		.for_class(DispatchClass::Operational, |weights| {252			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);253			// Operational transactions have some extra reserved space, so that they254			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.255			weights.reserved = Some(256				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT257			);258		})259		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)260		.build_or_panic();261	pub const Version: RuntimeVersion = VERSION;262	/*263	255 - Quartz264	42 - Opal265	*/266	pub const SS58Prefix: u8 = 255;267}268269/*2708880 - Unique2718881 - Quartz2728882 - Opal273*/274parameter_types! {275	pub const ChainId: u64 = 8881;276}277278pub struct FixedFee;279impl FeeCalculator for FixedFee {280	fn min_gas_price() -> U256 {281		// Targeting 0.15 UNQ per transfer282		1_018_751_825_264u64.into()283	}284}285286// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case287// (contract, which only writes a lot of data),288// approximating on top of our real store write weight289parameter_types! {290	pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;291	pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;292	pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();293}294295/// Limiting EVM execution to 50% of block for substrate users and management tasks296/// EVM transaction consumes more weight than substrate's, so we can't rely on them being297/// scheduled fairly298const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);299parameter_types! {300	pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());301}302303pub enum FixedGasWeightMapping {}304impl GasWeightMapping for FixedGasWeightMapping {305	fn gas_to_weight(gas: u64) -> Weight {306		gas.saturating_mul(WeightPerGas::get())307	}308	fn weight_to_gas(weight: Weight) -> u64 {309		weight / WeightPerGas::get()310	}311}312313impl pallet_evm::Config for Runtime {314	type BlockGasLimit = BlockGasLimit;315	type FeeCalculator = FixedFee;316	type GasWeightMapping = FixedGasWeightMapping;317	type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;318	type CallOrigin = EnsureAddressTruncated;319	type WithdrawOrigin = EnsureAddressTruncated;320	type AddressMapping = HashedAddressMapping<Self::Hashing>;321	type PrecompilesType = ();322	type PrecompilesValue = ();323	type Currency = Balances;324	type Event = Event;325	type OnMethodCall = (326		pallet_evm_migration::OnMethodCall<Self>,327		pallet_unique::UniqueErcSupport<Self>,328		pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,329	);330	type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;331	type ChainId = ChainId;332	type Runner = pallet_evm::runner::stack::Runner<Self>;333	type OnChargeTransaction = pallet_evm_transaction_payment::OnChargeTransaction<Self>;334	type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;335	type FindAuthor = EthereumFindAuthor<Aura>;336}337338impl pallet_evm_migration::Config for Runtime {339	type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;340}341342pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);343impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {344	fn find_author<'a, I>(digests: I) -> Option<H160>345	where346		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,347	{348		if let Some(author_index) = F::find_author(digests) {349			let authority_id = Aura::authorities()[author_index as usize].clone();350			return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));351		}352		None353	}354}355356impl pallet_ethereum::Config for Runtime {357	type Event = Event;358	type StateRoot = pallet_ethereum::IntermediateStateRoot;359}360361impl pallet_randomness_collective_flip::Config for Runtime {}362363impl frame_system::Config for Runtime {364	/// The data to be stored in an account.365	type AccountData = pallet_balances::AccountData<Balance>;366	/// The identifier used to distinguish between accounts.367	type AccountId = AccountId;368	/// The basic call filter to use in dispatchable.369	type BaseCallFilter = Everything;370	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).371	type BlockHashCount = BlockHashCount;372	/// The maximum length of a block (in bytes).373	type BlockLength = RuntimeBlockLength;374	/// The index type for blocks.375	type BlockNumber = BlockNumber;376	/// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.377	type BlockWeights = RuntimeBlockWeights;378	/// The aggregated dispatch type that is available for extrinsics.379	type Call = Call;380	/// The weight of database operations that the runtime can invoke.381	type DbWeight = RocksDbWeight;382	/// The ubiquitous event type.383	type Event = Event;384	/// The type for hashing blocks and tries.385	type Hash = Hash;386	/// The hashing algorithm used.387	type Hashing = BlakeTwo256;388	/// The header type.389	type Header = generic::Header<BlockNumber, BlakeTwo256>;390	/// The index type for storing how many extrinsics an account has signed.391	type Index = Index;392	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.393	type Lookup = AccountIdLookup<AccountId, ()>;394	/// What to do if an account is fully reaped from the system.395	type OnKilledAccount = ();396	/// What to do if a new account is created.397	type OnNewAccount = ();398	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;399	/// The ubiquitous origin type.400	type Origin = Origin;401	/// This type is being generated by `construct_runtime!`.402	type PalletInfo = PalletInfo;403	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.404	type SS58Prefix = SS58Prefix;405	/// Weight information for the extrinsics of this pallet.406	type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;407	/// Version of the runtime.408	type Version = Version;409	type MaxConsumers = ConstU32<16>;410}411412parameter_types! {413	pub const MinimumPeriod: u64 = SLOT_DURATION / 2;414}415416impl pallet_timestamp::Config for Runtime {417	/// A timestamp: milliseconds since the unix epoch.418	type Moment = u64;419	type OnTimestampSet = ();420	type MinimumPeriod = MinimumPeriod;421	type WeightInfo = ();422}423424parameter_types! {425	// pub const ExistentialDeposit: u128 = 500;426	pub const ExistentialDeposit: u128 = 0;427	pub const MaxLocks: u32 = 50;428}429430impl pallet_balances::Config for Runtime {431	type MaxLocks = MaxLocks;432	type MaxReserves = ();433	type ReserveIdentifier = [u8; 8];434	/// The type for recording an account's balance.435	type Balance = Balance;436	/// The ubiquitous event type.437	type Event = Event;438	type DustRemoval = Treasury;439	type ExistentialDeposit = ExistentialDeposit;440	type AccountStore = System;441	type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;442}443444pub const MICROUNIQUE: Balance = 1_000_000_000_000;445pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE;446pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;447pub const UNIQUE: Balance = 100 * CENTIUNIQUE;448449pub const fn deposit(items: u32, bytes: u32) -> Balance {450	items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE451}452453/*454parameter_types! {455	pub TombstoneDeposit: Balance = deposit(456		1,457		sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,458	);459	pub DepositPerContract: Balance = TombstoneDeposit::get();460	pub const DepositPerStorageByte: Balance = deposit(0, 1);461	pub const DepositPerStorageItem: Balance = deposit(1, 0);462	pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);463	pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;464	pub const SignedClaimHandicap: u32 = 2;465	pub const MaxDepth: u32 = 32;466	pub const MaxValueSize: u32 = 16 * 1024;467	pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb468	// The lazy deletion runs inside on_initialize.469	pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *470		RuntimeBlockWeights::get().max_block;471	// The weight needed for decoding the queue should be less or equal than a fifth472	// of the overall weight dedicated to the lazy deletion.473	pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (474			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -475			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)476		)) / 5) as u32;477	pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();478}479480impl pallet_contracts::Config for Runtime {481	type Time = Timestamp;482	type Randomness = RandomnessCollectiveFlip;483	type Currency = Balances;484	type Event = Event;485	type RentPayment = ();486	type SignedClaimHandicap = SignedClaimHandicap;487	type TombstoneDeposit = TombstoneDeposit;488	type DepositPerContract = DepositPerContract;489	type DepositPerStorageByte = DepositPerStorageByte;490	type DepositPerStorageItem = DepositPerStorageItem;491	type RentFraction = RentFraction;492	type SurchargeReward = SurchargeReward;493	type WeightPrice = pallet_transaction_payment::Pallet<Self>;494	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;495	type ChainExtension = NFTExtension;496	type DeletionQueueDepth = DeletionQueueDepth;497	type DeletionWeightLimit = DeletionWeightLimit;498	type Schedule = Schedule;499	type CallStack = [pallet_contracts::Frame<Self>; 31];500}501*/502503parameter_types! {504	pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer505	/// This value increases the priority of `Operational` transactions by adding506	/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.507	pub const OperationalFeeMultiplier: u8 = 5;508}509510/// Linear implementor of `WeightToFeePolynomial`511pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);512513impl<T> WeightToFeePolynomial for LinearFee<T>514where515	T: BaseArithmetic + From<u32> + Copy + Unsigned,516{517	type Balance = T;518519	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {520		smallvec!(WeightToFeeCoefficient {521			// Targeting 0.1 Unique per NFT transfer522			coeff_integer: 142_688_000u32.into(),523			coeff_frac: Perbill::zero(),524			negative: false,525			degree: 1,526		})527	}528}529530impl pallet_transaction_payment::Config for Runtime {531	type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;532	type TransactionByteFee = TransactionByteFee;533	type OperationalFeeMultiplier = OperationalFeeMultiplier;534	type WeightToFee = LinearFee<Balance>;535	type FeeMultiplierUpdate = ();536}537538parameter_types! {539	pub const ProposalBond: Permill = Permill::from_percent(5);540	pub const ProposalBondMinimum: Balance = 1 * UNIQUE;541	pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;542	pub const SpendPeriod: BlockNumber = 5 * MINUTES;543	pub const Burn: Permill = Permill::from_percent(0);544	pub const TipCountdown: BlockNumber = 1 * DAYS;545	pub const TipFindersFee: Percent = Percent::from_percent(20);546	pub const TipReportDepositBase: Balance = 1 * UNIQUE;547	pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;548	pub const BountyDepositBase: Balance = 1 * UNIQUE;549	pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;550	pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");551	pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;552	pub const MaximumReasonLength: u32 = 16384;553	pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);554	pub const BountyValueMinimum: Balance = 5 * UNIQUE;555	pub const MaxApprovals: u32 = 100;556}557558impl pallet_treasury::Config for Runtime {559	type PalletId = TreasuryModuleId;560	type Currency = Balances;561	type ApproveOrigin = EnsureRoot<AccountId>;562	type RejectOrigin = EnsureRoot<AccountId>;563	type Event = Event;564	type OnSlash = ();565	type ProposalBond = ProposalBond;566	type ProposalBondMinimum = ProposalBondMinimum;567	type ProposalBondMaximum = ProposalBondMaximum;568	type SpendPeriod = SpendPeriod;569	type Burn = Burn;570	type BurnDestination = ();571	type SpendFunds = ();572	type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;573	type MaxApprovals = MaxApprovals;574}575576impl pallet_sudo::Config for Runtime {577	type Event = Event;578	type Call = Call;579}580581pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);582583impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider584	for RelayChainBlockNumberProvider<T>585{586	type BlockNumber = BlockNumber;587588	fn current_block_number() -> Self::BlockNumber {589		cumulus_pallet_parachain_system::Pallet::<T>::validation_data()590			.map(|d| d.relay_parent_number)591			.unwrap_or_default()592	}593}594595parameter_types! {596	pub const MinVestedTransfer: Balance = 10 * UNIQUE;597	pub const MaxVestingSchedules: u32 = 28;598}599600impl orml_vesting::Config for Runtime {601	type Event = Event;602	type Currency = pallet_balances::Pallet<Runtime>;603	type MinVestedTransfer = MinVestedTransfer;604	type VestedTransferOrigin = EnsureSigned<AccountId>;605	type WeightInfo = ();606	type MaxVestingSchedules = MaxVestingSchedules;607	type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;608}609610parameter_types! {611	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;612	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;613}614615impl cumulus_pallet_parachain_system::Config for Runtime {616	type Event = Event;617	type SelfParaId = parachain_info::Pallet<Self>;618	type OnSystemEvent = ();619	// type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<620	// 	MaxDownwardMessageWeight,621	// 	XcmExecutor<XcmConfig>,622	// 	Call,623	// >;624	type OutboundXcmpMessageSource = XcmpQueue;625	type DmpMessageHandler = DmpQueue;626	type ReservedDmpWeight = ReservedDmpWeight;627	type ReservedXcmpWeight = ReservedXcmpWeight;628	type XcmpMessageHandler = XcmpQueue;629}630631impl parachain_info::Config for Runtime {}632633impl cumulus_pallet_aura_ext::Config for Runtime {}634635parameter_types! {636	pub const RelayLocation: MultiLocation = MultiLocation::parent();637	pub const RelayNetwork: NetworkId = NetworkId::Polkadot;638	pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();639	pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();640}641642/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used643/// when determining ownership of accounts for asset transacting and when attempting to use XCM644/// `Transact` in order to determine the dispatch Origin.645pub type LocationToAccountId = (646	// The parent (Relay-chain) origin converts to the default `AccountId`.647	ParentIsPreset<AccountId>,648	// Sibling parachain origins convert to AccountId via the `ParaId::into`.649	SiblingParachainConvertsVia<Sibling, AccountId>,650	// Straight up local `AccountId32` origins just alias directly to `AccountId`.651	AccountId32Aliases<RelayNetwork, AccountId>,652);653654pub struct OnlySelfCurrency;655impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {656	fn matches_fungible(a: &MultiAsset) -> Option<B> {657		match (&a.id, &a.fun) {658			(Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),659			_ => None,660		}661	}662}663664/// Means for transacting assets on this chain.665pub type LocalAssetTransactor = CurrencyAdapter<666	// Use this currency:667	Balances,668	// Use this currency when it is a fungible asset matching the given location or name:669	OnlySelfCurrency,670	// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:671	LocationToAccountId,672	// Our chain's account ID type (we can't get away without mentioning it explicitly):673	AccountId,674	// We don't track any teleports.675	(),676>;677678/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,679/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can680/// biases the kind of local `Origin` it will become.681pub type XcmOriginToTransactDispatchOrigin = (682	// Sovereign account converter; this attempts to derive an `AccountId` from the origin location683	// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for684	// foreign chains who want to have a local sovereign account on this chain which they control.685	SovereignSignedViaLocation<LocationToAccountId, Origin>,686	// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when687	// recognised.688	RelayChainAsNative<RelayOrigin, Origin>,689	// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when690	// recognised.691	SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,692	// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a693	// transaction from the Root origin.694	ParentAsSuperuser<Origin>,695	// Native signed account converter; this just converts an `AccountId32` origin into a normal696	// `Origin::Signed` origin of the same 32-byte value.697	SignedAccountId32AsNative<RelayNetwork, Origin>,698	// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.699	XcmPassthrough<Origin>,700);701702parameter_types! {703	// One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.704	pub UnitWeightCost: Weight = 1_000_000;705	// 1200 UNIQUEs buy 1 second of weight.706	pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);707	pub const MaxInstructions: u32 = 100;708	pub const MaxAuthorities: u32 = 100_000;709}710711match_type! {712	pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {713		MultiLocation { parents: 1, interior: Here } |714		MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }715	};716}717718pub type Barrier = (719	TakeWeightCredit,720	AllowTopLevelPaidExecutionFrom<Everything>,721	AllowUnpaidExecutionFrom<ParentOrParentsUnitPlurality>,722	// ^^^ Parent & its unit plurality gets free execution723);724725pub struct UsingOnlySelfCurrencyComponents<726	WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,727	AssetId: Get<MultiLocation>,728	AccountId,729	Currency: CurrencyT<AccountId>,730	OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,731>(732	Weight,733	Currency::Balance,734	PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,735);736impl<737		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,738		AssetId: Get<MultiLocation>,739		AccountId,740		Currency: CurrencyT<AccountId>,741		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,742	> WeightTrader743	for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>744{745	fn new() -> Self {746		Self(0, Zero::zero(), PhantomData)747	}748749	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {750		let amount = WeightToFee::calc(&weight);751		let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;752753		// location to this parachain through relay chain754		let option1: xcm::v1::AssetId = Concrete(MultiLocation {755			parents: 1,756			interior: X1(Parachain(ParachainInfo::parachain_id().into())),757		});758		// direct location759		let option2: xcm::v1::AssetId = Concrete(MultiLocation {760			parents: 0,761			interior: Here,762		});763764		let required = if payment.fungible.contains_key(&option1) {765			(option1, u128_amount).into()766		} else if payment.fungible.contains_key(&option2) {767			(option2, u128_amount).into()768		} else {769			(Concrete(MultiLocation::default()), u128_amount).into()770		};771772		let unused = payment773			.checked_sub(required)774			.map_err(|_| XcmError::TooExpensive)?;775		self.0 = self.0.saturating_add(weight);776		self.1 = self.1.saturating_add(amount);777		Ok(unused)778	}779780	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {781		let weight = weight.min(self.0);782		let amount = WeightToFee::calc(&weight);783		self.0 -= weight;784		self.1 = self.1.saturating_sub(amount);785		let amount: u128 = amount.saturated_into();786		if amount > 0 {787			Some((AssetId::get(), amount).into())788		} else {789			None790		}791	}792}793impl<794		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,795		AssetId: Get<MultiLocation>,796		AccountId,797		Currency: CurrencyT<AccountId>,798		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,799	> Drop800	for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>801{802	fn drop(&mut self) {803		OnUnbalanced::on_unbalanced(Currency::issue(self.1));804	}805}806807pub struct XcmConfig;808impl Config for XcmConfig {809	type Call = Call;810	type XcmSender = XcmRouter;811	// How to withdraw and deposit an asset.812	type AssetTransactor = LocalAssetTransactor;813	type OriginConverter = XcmOriginToTransactDispatchOrigin;814	type IsReserve = NativeAsset;815	type IsTeleporter = (); // Teleportation is disabled816	type LocationInverter = LocationInverter<Ancestry>;817	type Barrier = Barrier;818	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;819	type Trader = UsingOnlySelfCurrencyComponents<820		IdentityFee<Balance>,821		RelayLocation,822		AccountId,823		Balances,824		(),825	>;826	type ResponseHandler = (); // Don't handle responses for now.827	type SubscriptionService = PolkadotXcm;828829	type AssetTrap = PolkadotXcm;830	type AssetClaims = PolkadotXcm;831}832833// parameter_types! {834// 	pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;835// }836837/// No local origins on this chain are allowed to dispatch XCM sends/executions.838pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);839840/// The means for routing XCM messages which are not for local execution into the right message841/// queues.842pub type XcmRouter = (843	// Two routers - use UMP to communicate with the relay chain:844	cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,845	// ..and XCMP to communicate with the sibling chains.846	XcmpQueue,847);848849impl pallet_evm_coder_substrate::Config for Runtime {850	type EthereumTransactionSender = pallet_ethereum::Pallet<Self>;851	type GasWeightMapping = FixedGasWeightMapping;852}853854impl pallet_xcm::Config for Runtime {855	type Event = Event;856	type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;857	type XcmRouter = XcmRouter;858	type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;859	type XcmExecuteFilter = Everything;860	type XcmExecutor = XcmExecutor<XcmConfig>;861	type XcmTeleportFilter = Everything;862	type XcmReserveTransferFilter = Everything;863	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;864	type LocationInverter = LocationInverter<Ancestry>;865	type Origin = Origin;866	type Call = Call;867	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;868	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;869}870871impl cumulus_pallet_xcm::Config for Runtime {872	type Event = Event;873	type XcmExecutor = XcmExecutor<XcmConfig>;874}875876impl cumulus_pallet_xcmp_queue::Config for Runtime {877	type Event = Event;878	type XcmExecutor = XcmExecutor<XcmConfig>;879	type ChannelInfo = ParachainSystem;880	type VersionWrapper = ();881	type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;882	type ControllerOrigin = EnsureRoot<AccountId>;883	type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;884}885886impl cumulus_pallet_dmp_queue::Config for Runtime {887	type Event = Event;888	type XcmExecutor = XcmExecutor<XcmConfig>;889	type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;890}891892impl pallet_aura::Config for Runtime {893	type AuthorityId = AuraId;894	type DisabledValidators = ();895	type MaxAuthorities = MaxAuthorities;896}897898parameter_types! {899	pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account();900	pub const CollectionCreationPrice: Balance = 2 * UNIQUE;901}902903impl pallet_common::Config for Runtime {904	type Event = Event;905	type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated;906	type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;907	type CrossAccountId = pallet_common::account::BasicCrossAccountId<Self>;908909	type Currency = Balances;910	type CollectionCreationPrice = CollectionCreationPrice;911	type TreasuryAccountId = TreasuryAccountId;912}913914impl pallet_fungible::Config for Runtime {915	type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;916}917impl pallet_refungible::Config for Runtime {918	type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;919}920impl pallet_nonfungible::Config for Runtime {921	type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;922}923924impl pallet_unique::Config for Runtime {925	type Event = Event;926	type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;927}928929parameter_types! {930	pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied931}932933/// Used for the pallet inflation934impl pallet_inflation::Config for Runtime {935	type Currency = Balances;936	type TreasuryAccountId = TreasuryAccountId;937	type InflationBlockInterval = InflationBlockInterval;938	type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;939}940941// parameter_types! {942// 	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *943// 		RuntimeBlockWeights::get().max_block;944// 	pub const MaxScheduledPerBlock: u32 = 50;945// }946947type EvmSponsorshipHandler = (948	pallet_unique::UniqueEthSponsorshipHandler<Runtime>,949	pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,950);951type SponsorshipHandler = (952	pallet_unique::UniqueSponsorshipHandler<Runtime>,953	//pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,954	pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,955);956957// impl pallet_unq_scheduler::Config for Runtime {958// 	type Event = Event;959// 	type Origin = Origin;960// 	type PalletsOrigin = OriginCaller;961// 	type Call = Call;962// 	type MaximumWeight = MaximumSchedulerWeight;963// 	type ScheduleOrigin = EnsureSigned<AccountId>;964// 	type MaxScheduledPerBlock = MaxScheduledPerBlock;965// 	type SponsorshipHandler = SponsorshipHandler;966// 	type WeightInfo = ();967// }968969impl pallet_evm_transaction_payment::Config for Runtime {970	type EvmSponsorshipHandler = EvmSponsorshipHandler;971	type Currency = Balances;972	type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;973	type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated;974}975976impl pallet_charge_transaction::Config for Runtime {977	type SponsorshipHandler = SponsorshipHandler;978}979980// impl pallet_contract_helpers::Config for Runtime {981//	 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;982// }983984parameter_types! {985	// 0x842899ECF380553E8a4de75bF534cdf6fBF64049986	pub const HelpersContractAddress: H160 = H160([987		0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,988	]);989}990991impl pallet_evm_contract_helpers::Config for Runtime {992	type ContractAddress = HelpersContractAddress;993	type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;994}995996construct_runtime!(997	pub enum Runtime where998		Block = Block,999		NodeBlock = opaque::Block,1000		UncheckedExtrinsic = UncheckedExtrinsic1001	{1002		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,1003		ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,10041005		Aura: pallet_aura::{Pallet, Config<T>} = 22,1006		AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,10071008		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,1009		RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,1010		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,1011		TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,1012		Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,1013		Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,1014		System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,1015		Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,1016		// Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,1017		// Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,10181019		// XCM helpers.1020		XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,1021		PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,1022		CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,1023		DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,10241025		// Unique Pallets1026		Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,1027		Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,1028		// Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event<T>} = 62,1029		// free = 631030		Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,1031		// ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,1032		Common: pallet_common::{Pallet, Storage, Event<T>} = 66,1033		Fungible: pallet_fungible::{Pallet, Storage} = 67,1034		Refungible: pallet_refungible::{Pallet, Storage} = 68,1035		Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,10361037		// Frontier1038		EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,1039		Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,10401041		EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,1042		EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1043		EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1044		EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1045	}1046);10471048pub struct TransactionConverter;10491050impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {1051	fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {1052		UncheckedExtrinsic::new_unsigned(1053			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1054		)1055	}1056}10571058impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {1059	fn convert_transaction(1060		&self,1061		transaction: pallet_ethereum::Transaction,1062	) -> opaque::UncheckedExtrinsic {1063		let extrinsic = UncheckedExtrinsic::new_unsigned(1064			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1065		);1066		let encoded = extrinsic.encode();1067		opaque::UncheckedExtrinsic::decode(&mut &encoded[..])1068			.expect("Encoded extrinsic is always valid")1069	}1070}10711072/// The address format for describing accounts.1073pub type Address = sp_runtime::MultiAddress<AccountId, ()>;1074/// Block header type as expected by this runtime.1075pub type Header = generic::Header<BlockNumber, BlakeTwo256>;1076/// Block type as expected by this runtime.1077pub type Block = generic::Block<Header, UncheckedExtrinsic>;1078/// A Block signed with a Justification1079pub type SignedBlock = generic::SignedBlock<Block>;1080/// BlockId type as expected by this runtime.1081pub type BlockId = generic::BlockId<Block>;1082/// The SignedExtension to the basic transaction logic.1083pub type SignedExtra = (1084	frame_system::CheckSpecVersion<Runtime>,1085	// system::CheckTxVersion<Runtime>,1086	frame_system::CheckGenesis<Runtime>,1087	frame_system::CheckEra<Runtime>,1088	frame_system::CheckNonce<Runtime>,1089	frame_system::CheckWeight<Runtime>,1090	pallet_charge_transaction::ChargeTransactionPayment<Runtime>,1091	//pallet_contract_helpers::ContractHelpersExtension<Runtime>,1092);1093/// Unchecked extrinsic type as expected by this runtime.1094pub type UncheckedExtrinsic =1095	fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;1096/// Extrinsic type that has already been checked.1097pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;1098/// Executive: handles dispatch to the various modules.1099pub type Executive = frame_executive::Executive<1100	Runtime,1101	Block,1102	frame_system::ChainContext<Runtime>,1103	Runtime,1104	AllPalletsReversedWithSystemFirst,1105>;11061107impl_opaque_keys! {1108	pub struct SessionKeys {1109		pub aura: Aura,1110	}1111}11121113impl fp_self_contained::SelfContainedCall for Call {1114	type SignedInfo = H160;11151116	fn is_self_contained(&self) -> bool {1117		match self {1118			Call::Ethereum(call) => call.is_self_contained(),1119			_ => false,1120		}1121	}11221123	fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {1124		match self {1125			Call::Ethereum(call) => call.check_self_contained(),1126			_ => None,1127		}1128	}11291130	fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option<TransactionValidity> {1131		match self {1132			Call::Ethereum(call) => call.validate_self_contained(info),1133			_ => None,1134		}1135	}11361137	fn pre_dispatch_self_contained(1138		&self,1139		info: &Self::SignedInfo,1140	) -> Option<Result<(), TransactionValidityError>> {1141		match self {1142			Call::Ethereum(call) => call.pre_dispatch_self_contained(info),1143			_ => None,1144		}1145	}11461147	fn apply_self_contained(1148		self,1149		info: Self::SignedInfo,1150	) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {1151		match self {1152			call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(1153				Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),1154			)),1155			_ => None,1156		}1157	}1158}11591160macro_rules! dispatch_unique_runtime {1161	($collection:ident.$method:ident($($name:ident),*)) => {{1162		use pallet_unique::dispatch::Dispatched;11631164		let collection = Dispatched::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1165		let dispatch = collection.as_dyn();11661167		Ok(dispatch.$method($($name),*))1168	}};1169}1170impl_runtime_apis! {1171	impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId>1172		for Runtime1173	{1174		fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {1175			dispatch_unique_runtime!(collection.account_tokens(account))1176		}1177		fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {1178			dispatch_unique_runtime!(collection.token_exists(token))1179		}11801181		fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {1182			dispatch_unique_runtime!(collection.token_owner(token))1183		}1184		fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {1185			dispatch_unique_runtime!(collection.const_metadata(token))1186		}1187		fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {1188			dispatch_unique_runtime!(collection.variable_metadata(token))1189		}11901191		fn collection_tokens(collection: CollectionId) -> Result<u32, DispatchError> {1192			dispatch_unique_runtime!(collection.collection_tokens())1193		}1194		fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {1195			dispatch_unique_runtime!(collection.account_balance(account))1196		}1197		fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {1198			dispatch_unique_runtime!(collection.balance(account, token))1199		}1200		fn allowance(1201			collection: CollectionId,1202			sender: CrossAccountId,1203			spender: CrossAccountId,1204			token: TokenId,1205		) -> Result<u128, DispatchError> {1206			dispatch_unique_runtime!(collection.allowance(sender, spender, token))1207		}12081209		fn eth_contract_code(account: H160) -> Option<Vec<u8>> {1210			<pallet_unique::UniqueErcSupport<Runtime>>::get_code(&account)1211				.or_else(|| <pallet_evm_migration::OnMethodCall<Runtime>>::get_code(&account))1212				.or_else(|| <pallet_evm_contract_helpers::HelpersOnMethodCall<Self>>::get_code(&account))1213		}1214		fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {1215			Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))1216		}1217		fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {1218			Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))1219		}1220		fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {1221			Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))1222		}1223		fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {1224			dispatch_unique_runtime!(collection.last_token_id())1225		}1226		fn collection_by_id(collection: CollectionId) -> Result<Option<Collection<AccountId>>, DispatchError> {1227			Ok(<pallet_common::CollectionById<Runtime>>::get(collection))1228		}1229		fn collection_stats() -> Result<CollectionStats, DispatchError> {1230			Ok(<pallet_common::Pallet<Runtime>>::collection_stats())1231		}1232	}12331234	impl sp_api::Core<Block> for Runtime {1235		fn version() -> RuntimeVersion {1236			VERSION1237		}12381239		fn execute_block(block: Block) {1240			Executive::execute_block(block)1241		}12421243		fn initialize_block(header: &<Block as BlockT>::Header) {1244			Executive::initialize_block(header)1245		}1246	}12471248	impl sp_api::Metadata<Block> for Runtime {1249		fn metadata() -> OpaqueMetadata {1250			OpaqueMetadata::new(Runtime::metadata().into())1251		}1252	}12531254	impl sp_block_builder::BlockBuilder<Block> for Runtime {1255		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {1256			Executive::apply_extrinsic(extrinsic)1257		}12581259		fn finalize_block() -> <Block as BlockT>::Header {1260			Executive::finalize_block()1261		}12621263		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {1264			data.create_extrinsics()1265		}12661267		fn check_inherents(1268			block: Block,1269			data: sp_inherents::InherentData,1270		) -> sp_inherents::CheckInherentsResult {1271			data.check_extrinsics(&block)1272		}12731274		// fn random_seed() -> <Block as BlockT>::Hash {1275		//     RandomnessCollectiveFlip::random_seed().01276		// }1277	}12781279	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {1280		fn validate_transaction(1281			source: TransactionSource,1282			tx: <Block as BlockT>::Extrinsic,1283			hash: <Block as BlockT>::Hash,1284		) -> TransactionValidity {1285			Executive::validate_transaction(source, tx, hash)1286		}1287	}12881289	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {1290		fn offchain_worker(header: &<Block as BlockT>::Header) {1291			Executive::offchain_worker(header)1292		}1293	}12941295	impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {1296		fn chain_id() -> u64 {1297			<Runtime as pallet_evm::Config>::ChainId::get()1298		}12991300		fn account_basic(address: H160) -> EVMAccount {1301			EVM::account_basic(&address)1302		}13031304		fn gas_price() -> U256 {1305			<Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price()1306		}13071308		fn account_code_at(address: H160) -> Vec<u8> {1309			EVM::account_codes(address)1310		}13111312		fn author() -> H160 {1313			<pallet_evm::Pallet<Runtime>>::find_author()1314		}13151316		fn storage_at(address: H160, index: U256) -> H256 {1317			let mut tmp = [0u8; 32];1318			index.to_big_endian(&mut tmp);1319			EVM::account_storages(address, H256::from_slice(&tmp[..]))1320		}13211322		#[allow(clippy::redundant_closure)]1323		fn call(1324			from: H160,1325			to: H160,1326			data: Vec<u8>,1327			value: U256,1328			gas_limit: U256,1329			max_fee_per_gas: Option<U256>,1330			max_priority_fee_per_gas: Option<U256>,1331			nonce: Option<U256>,1332			estimate: bool,1333			access_list: Option<Vec<(H160, Vec<H256>)>>,1334		) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {1335			let config = if estimate {1336				let mut config = <Runtime as pallet_evm::Config>::config().clone();1337				config.estimate = true;1338				Some(config)1339			} else {1340				None1341			};13421343			<Runtime as pallet_evm::Config>::Runner::call(1344				from,1345				to,1346				data,1347				value,1348				gas_limit.low_u64(),1349				max_fee_per_gas,1350				max_priority_fee_per_gas,1351				nonce,1352				access_list.unwrap_or_default(),1353				config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),1354			).map_err(|err| err.into())1355		}13561357		#[allow(clippy::redundant_closure)]1358		fn create(1359			from: H160,1360			data: Vec<u8>,1361			value: U256,1362			gas_limit: U256,1363			max_fee_per_gas: Option<U256>,1364			max_priority_fee_per_gas: Option<U256>,1365			nonce: Option<U256>,1366			estimate: bool,1367			access_list: Option<Vec<(H160, Vec<H256>)>>,1368		) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {1369			let config = if estimate {1370				let mut config = <Runtime as pallet_evm::Config>::config().clone();1371				config.estimate = true;1372				Some(config)1373			} else {1374				None1375			};13761377			<Runtime as pallet_evm::Config>::Runner::create(1378				from,1379				data,1380				value,1381				gas_limit.low_u64(),1382				max_fee_per_gas,1383				max_priority_fee_per_gas,1384				nonce,1385				access_list.unwrap_or_default(),1386				config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),1387			).map_err(|err| err.into())1388		}13891390		fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {1391			Ethereum::current_transaction_statuses()1392		}13931394		fn current_block() -> Option<pallet_ethereum::Block> {1395			Ethereum::current_block()1396		}13971398		fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {1399			Ethereum::current_receipts()1400		}14011402		fn current_all() -> (1403			Option<pallet_ethereum::Block>,1404			Option<Vec<pallet_ethereum::Receipt>>,1405			Option<Vec<TransactionStatus>>1406		) {1407			(1408				Ethereum::current_block(),1409				Ethereum::current_receipts(),1410				Ethereum::current_transaction_statuses()1411			)1412		}14131414		fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {1415			xts.into_iter().filter_map(|xt| match xt.0.function {1416				Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),1417				_ => None1418			}).collect()1419		}14201421		fn elasticity() -> Option<Permill> {1422			None1423		}1424	}14251426	impl sp_session::SessionKeys<Block> for Runtime {1427		fn decode_session_keys(1428			encoded: Vec<u8>,1429		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {1430			SessionKeys::decode_into_raw_public_keys(&encoded)1431		}14321433		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {1434			SessionKeys::generate(seed)1435		}1436	}14371438	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {1439		fn slot_duration() -> sp_consensus_aura::SlotDuration {1440			sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())1441		}14421443		fn authorities() -> Vec<AuraId> {1444			Aura::authorities().to_vec()1445		}1446	}14471448	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {1449		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {1450			ParachainSystem::collect_collation_info(header)1451		}1452	}14531454	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {1455		fn account_nonce(account: AccountId) -> Index {1456			System::account_nonce(account)1457		}1458	}14591460	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {1461		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {1462			TransactionPayment::query_info(uxt, len)1463		}1464		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {1465			TransactionPayment::query_fee_details(uxt, len)1466		}1467	}14681469	/*1470	impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>1471		for Runtime1472	{1473		fn call(1474			origin: AccountId,1475			dest: AccountId,1476			value: Balance,1477			gas_limit: u64,1478			input_data: Vec<u8>,1479		) -> pallet_contracts_primitives::ContractExecResult {1480			Contracts::bare_call(origin, dest, value, gas_limit, input_data, false)1481		}14821483		fn instantiate(1484			origin: AccountId,1485			endowment: Balance,1486			gas_limit: u64,1487			code: pallet_contracts_primitives::Code<Hash>,1488			data: Vec<u8>,1489			salt: Vec<u8>,1490		) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>1491		{1492			Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false)1493		}14941495		fn get_storage(1496			address: AccountId,1497			key: [u8; 32],1498		) -> pallet_contracts_primitives::GetStorageResult {1499			Contracts::get_storage(address, key)1500		}15011502		fn rent_projection(1503			address: AccountId,1504		) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {1505			Contracts::rent_projection(address)1506		}1507	}1508	*/15091510	#[cfg(feature = "runtime-benchmarks")]1511	impl frame_benchmarking::Benchmark<Block> for Runtime {1512		fn benchmark_metadata(extra: bool) -> (1513			Vec<frame_benchmarking::BenchmarkList>,1514			Vec<frame_support::traits::StorageInfo>,1515		) {1516			use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};1517			use frame_support::traits::StorageInfoTrait;15181519			let mut list = Vec::<BenchmarkList>::new();15201521			list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);1522			list_benchmark!(list, extra, pallet_unique, Unique);1523			list_benchmark!(list, extra, pallet_inflation, Inflation);1524			list_benchmark!(list, extra, pallet_fungible, Fungible);1525			list_benchmark!(list, extra, pallet_refungible, Refungible);1526			list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);1527			// list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);15281529			let storage_info = AllPalletsReversedWithSystemFirst::storage_info();15301531			return (list, storage_info)1532		}15331534		fn dispatch_benchmark(1535			config: frame_benchmarking::BenchmarkConfig1536		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {1537			use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};15381539			let allowlist: Vec<TrackedStorageKey> = vec![1540				// Block Number1541				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),1542				// Total Issuance1543				hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),1544				// Execution Phase1545				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),1546				// Event Count1547				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),1548				// System Events1549				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),1550			];15511552			let mut batches = Vec::<BenchmarkBatch>::new();1553			let params = (&config, &allowlist);15541555			add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);1556			add_benchmark!(params, batches, pallet_unique, Unique);1557			add_benchmark!(params, batches, pallet_inflation, Inflation);1558			add_benchmark!(params, batches, pallet_fungible, Fungible);1559			add_benchmark!(params, batches, pallet_refungible, Refungible);1560			add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);1561			// add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);15621563			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }1564			Ok(batches)1565		}1566	}1567}15681569struct CheckInherents;15701571impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {1572	fn check_inherents(1573		block: &Block,1574		relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,1575	) -> sp_inherents::CheckInherentsResult {1576		let relay_chain_slot = relay_state_proof1577			.read_slot()1578			.expect("Could not read the relay chain slot from the proof");15791580		let inherent_data =1581			cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(1582				relay_chain_slot,1583				sp_std::time::Duration::from_secs(6),1584			)1585			.create_inherent_data()1586			.expect("Could not create the timestamp inherent data");15871588		inherent_data.check_extrinsics(block)1589	}1590}15911592cumulus_pallet_parachain_system::register_validate_block!(1593	Runtime = Runtime,1594	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,1595	CheckInherents = CheckInherents,1596);