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

difftreelog

source

runtime/src/lib.rs26.3 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.78#![cfg_attr(not(feature = "std"), no_std)]9// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.10#![recursion_limit = "256"]1112// Make the WASM binary available.13#[cfg(feature = "std")]14include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));1516use pallet_grandpa::fg_primitives;17use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};18use sp_api::impl_runtime_apis;19use sp_consensus_aura::sr25519::AuthorityId as AuraId;20use sp_core::{ crypto::KeyTypeId, crypto::Public, OpaqueMetadata };21use sp_runtime::{22    Permill, Perbill, Percent,23    ModuleId,24    create_runtime_str, generic, impl_opaque_keys,25    traits::{26        Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount, 27		IdentityLookup, NumberFor, Verify, AccountIdConversion,28    },29    transaction_validity::{TransactionSource, TransactionValidity},30    ApplyExtrinsicResult, MultiSignature,31};32#[cfg(feature = "std")]33use sp_version::NativeVersion;34use sp_version::RuntimeVersion;35pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, CurrencyAdapter, FeeDetails, RuntimeDispatchInfo};36// A few exports that help ease life for downstream crates.37pub use pallet_balances::Call as BalancesCall;38pub use pallet_contracts::{Schedule as ContractsSchedule };39pub use frame_support::{40    construct_runtime,41    dispatch::DispatchResult,42    parameter_types,43    StorageValue,44    traits::{45        Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness,46        LockIdentifier,47    },48    weights::{49        constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},50        DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight,51        WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients52    },53};54use pallet_nft_transaction_payment::*;55use pallet_nft_charge_transaction::*;56use nft_data_structs::*;57use pallet_contracts::weights::WeightInfo;58// #[cfg(any(feature = "std", test))]59use frame_system::{60    self as system,61    EnsureRoot, EnsureSigned,62	limits::{BlockWeights, BlockLength},63};64use sp_std::{prelude::*, marker::PhantomData};65use sp_arithmetic::{traits::{BaseArithmetic, Unsigned}};66use smallvec::smallvec;6768use sp_runtime::{69	traits::{ 70		Dispatchable,71	},72};73use pallet_contracts::chain_extension::UncheckedFrom;747576pub use pallet_timestamp::Call as TimestampCall;7778mod chain_extension;79use crate::chain_extension::{ NFTExtension, Imbalance };8081/// Struct that handles the conversion of Balance -> `u64`. This is used for82/// staking's election calculation.83pub struct CurrencyToVoteHandler;8485impl CurrencyToVoteHandler {86	fn factor() -> Balance {87		(Balances::total_issuance() / u64::max_value() as Balance).max(1)88	}89}9091impl Convert<Balance, u64> for CurrencyToVoteHandler {92	fn convert(x: Balance) -> u64 {93		(x / Self::factor()) as u6494	}95}9697impl Convert<u128, Balance> for CurrencyToVoteHandler {98	fn convert(x: u128) -> Balance {99		x * Self::factor()100	}101}102103/// Re-export a nft pallet104/// TODO: Check this re-export. Is this safe and good style?105extern crate pallet_nft;106pub use pallet_nft::*;107108/// An index to a block.109pub type BlockNumber = u32;110111/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.112pub type Signature = MultiSignature;113114/// Some way of identifying an account on the chain. We intentionally make it equivalent115/// to the public key of our transaction signing scheme.116pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;117118/// The type for looking up accounts. We don't expect more than 4 billion of them, but you119/// never know...120pub type AccountIndex = u32;121122/// Balance of an account.123pub type Balance = u128;124125/// Index of a transaction in the chain.126pub type Index = u32;127128/// A hash of some data used by the chain.129pub type Hash = sp_core::H256;130131/// Digest item type.132pub type DigestItem = generic::DigestItem<Hash>;133134mod nft_weights;135136/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know137/// the specifics of the runtime. They can then be made to be agnostic over specific formats138/// of data like extrinsics, allowing for them to continue syncing the network through upgrades139/// to even the core data structures.140pub mod opaque {141    use super::*;142143    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;144145    /// Opaque block header type.146    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;147    /// Opaque block type.148    pub type Block = generic::Block<Header, UncheckedExtrinsic>;149    /// Opaque block identifier type.150    pub type BlockId = generic::BlockId<Block>;151152    impl_opaque_keys! {153        pub struct SessionKeys {154            pub aura: Aura,155            pub grandpa: Grandpa,156        }157    }158}159160/// This runtime version.161pub const VERSION: RuntimeVersion = RuntimeVersion {162    spec_name: create_runtime_str!("nft"),163    impl_name: create_runtime_str!("nft"),164    authoring_version: 1,165    spec_version: 3,166    impl_version: 1,167    apis: RUNTIME_API_VERSIONS,168    transaction_version: 1,169};170171pub const MILLISECS_PER_BLOCK: u64 = 6000;172173pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;174175// These time units are defined in number of blocks.176pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);177pub const HOURS: BlockNumber = MINUTES * 60;178pub const DAYS: BlockNumber = HOURS * 24;179180/// The version information used to identify this runtime when compiled natively.181#[cfg(feature = "std")]182pub fn native_version() -> NativeVersion {183    NativeVersion {184        runtime_version: VERSION,185        can_author_with: Default::default(),186    }187}188189type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;190191pub struct DealWithFees;192impl OnUnbalanced<NegativeImbalance> for DealWithFees {193	fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item=NegativeImbalance>) {194		if let Some(fees) = fees_then_tips.next() {195			// for fees, 100% to treasury196			let mut split = fees.ration(100, 0);197			if let Some(tips) = fees_then_tips.next() {198				// for tips, if any, 100% to treasury199				tips.ration_merge_into(100, 0, &mut split);200			}201			Treasury::on_unbalanced(split.0);202			// Author::on_unbalanced(split.1);203		}204	}205}206207/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.208/// This is used to limit the maximal weight of a single extrinsic.209const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);210/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used211/// by  Operational  extrinsics.212const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);213/// We allow for 2 seconds of compute with a 6 second average block time.214const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND;215216parameter_types! {217    pub const BlockHashCount: BlockNumber = 2400;218	pub RuntimeBlockLength: BlockLength =219		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);220    pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);221    pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;222	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()223		.base_block(BlockExecutionWeight::get())224		.for_class(DispatchClass::all(), |weights| {225			weights.base_extrinsic = ExtrinsicBaseWeight::get();226		})227		.for_class(DispatchClass::Normal, |weights| {228			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);229		})230		.for_class(DispatchClass::Operational, |weights| {231			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);232			// Operational transactions have some extra reserved space, so that they233			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.234			weights.reserved = Some(235				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT236			);237		})238		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)239		.build_or_panic();240    pub const Version: RuntimeVersion = VERSION;241    pub const SS58Prefix: u8 = 42;242}243244impl system::Config for Runtime {245    /// The basic call filter to use in dispatchable.246    type BaseCallFilter = ();247    /// The identifier used to distinguish between accounts.248    type AccountId = AccountId;249    /// The aggregated dispatch type that is available for extrinsics.250    type Call = Call;251    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.252    type Lookup = IdentityLookup<AccountId>;253    /// The index type for storing how many extrinsics an account has signed.254    type Index = Index;255    /// The index type for blocks.256    type BlockNumber = BlockNumber;257    /// The type for hashing blocks and tries.258    type Hash = Hash;259    /// The hashing algorithm used.260    type Hashing = BlakeTwo256;261    /// The header type.262    type Header = generic::Header<BlockNumber, BlakeTwo256>;263    /// The ubiquitous event type.264    type Event = Event;265    /// The ubiquitous origin type.266    type Origin = Origin;267    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).268    type BlockHashCount = BlockHashCount;269    /// The weight of database operations that the runtime can invoke.270    type DbWeight = RocksDbWeight;271    /// The weight of the overhead invoked on the block import process, independent of the272    /// extrinsics included in that block.273	type BlockWeights = RuntimeBlockWeights;274    /// Version of the runtime.275    type Version = Version;276 	/// This type is being generated by `construct_runtime!`.277    type PalletInfo = PalletInfo;278    /// What to do if a new account is created.279    type OnNewAccount = ();280    /// What to do if an account is fully reaped from the system.281    type OnKilledAccount = ();282    /// The data to be stored in an account.283    type AccountData = pallet_balances::AccountData<Balance>;284	/// Weight information for the extrinsics of this pallet.285    type SystemWeightInfo = system::weights::SubstrateWeight<Runtime>;286    287	type BlockLength = RuntimeBlockLength;288	type SS58Prefix = SS58Prefix;289}290291impl pallet_aura::Config for Runtime {292    type AuthorityId = AuraId;293}294295impl pallet_grandpa::Config for Runtime {296	type Event = Event;297	type Call = Call;298299	type KeyOwnerProofSystem = ();300301	type KeyOwnerProof =302		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;303304	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(305		KeyTypeId,306		GrandpaId,307	)>>::IdentificationTuple;308309	type HandleEquivocation = ();310311	type WeightInfo = ();312}313314parameter_types! {315    pub const MinimumPeriod: u64 = SLOT_DURATION / 2;316}317318impl pallet_timestamp::Config for Runtime {319	/// A timestamp: milliseconds since the unix epoch.320	type Moment = u64;321	type OnTimestampSet = Aura;322	type MinimumPeriod = MinimumPeriod;323	type WeightInfo = ();324}325326parameter_types! {327    // pub const ExistentialDeposit: u128 = 500;328    pub const ExistentialDeposit: u128 = 0;329	pub const MaxLocks: u32 = 50;330}331332impl pallet_balances::Config for Runtime {333	type MaxLocks = MaxLocks;334	/// The type for recording an account's balance.335	type Balance = Balance;336	/// The ubiquitous event type.337	type Event = Event;338	type DustRemoval = Treasury;339	type ExistentialDeposit = ExistentialDeposit;340	type AccountStore = System;341	type WeightInfo = ();342}343344pub const MICROUNIQUE: Balance = 1_000_000_000;345pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE;346pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;347pub const UNIQUE: Balance      = 100 * CENTIUNIQUE;348349pub const fn deposit(items: u32, bytes: u32) -> Balance {350    items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE351}352353parameter_types! {354	pub const TombstoneDeposit: Balance = deposit(355		0,356		sp_std::mem::size_of::<pallet_contracts::ContractInfo<Runtime>>() as u32357	);358	pub const DepositPerContract: Balance = TombstoneDeposit::get();359	pub const DepositPerStorageByte: Balance = deposit(0, 1);360	pub const DepositPerStorageItem: Balance = deposit(1, 0);361	pub RentFraction: Perbill = Perbill::from_rational_approximation(1u32, 30 * DAYS);362	pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;363	pub const SignedClaimHandicap: u32 = 2;364	pub const MaxDepth: u32 = 32;365	pub const MaxValueSize: u32 = 16 * 1024;366	pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb 367	// The lazy deletion runs inside on_initialize.368	pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *369		RuntimeBlockWeights::get().max_block;370	// The weight needed for decoding the queue should be less or equal than a fifth371	// of the overall weight dedicated to the lazy deletion.372	pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (373			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -374			<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)375		)) / 5) as u32;376}377378379impl pallet_contracts::Config for Runtime {380	type Time = Timestamp;381	type Randomness = RandomnessCollectiveFlip;382	type Currency = Balances;383	type Event = Event;384	type RentPayment = ();385	type SignedClaimHandicap = SignedClaimHandicap;386	type TombstoneDeposit = TombstoneDeposit;387	type DepositPerContract = DepositPerContract;388	type DepositPerStorageByte = DepositPerStorageByte;389	type DepositPerStorageItem = DepositPerStorageItem;390	type RentFraction = RentFraction;391	type SurchargeReward = SurchargeReward;392	type MaxDepth = MaxDepth;393	type MaxValueSize = MaxValueSize;394	type WeightPrice = pallet_transaction_payment::Module<Self>;395	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;396	type ChainExtension = NFTExtension;397	type DeletionQueueDepth = DeletionQueueDepth;398	type DeletionWeightLimit = DeletionWeightLimit;399	type MaxCodeSize = MaxCodeSize;400}401402parameter_types! {403	pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer 404}405406/// Linear implementor of `WeightToFeePolynomial` 407pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);408409impl<T> WeightToFeePolynomial for LinearFee<T> where410	T: BaseArithmetic + From<u32> + Copy + Unsigned411{412	type Balance = T;413414	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {415		smallvec!(WeightToFeeCoefficient {416			coeff_integer: 146_700u32.into(), // Targeting 0.1 Unique per NFT transfer417			coeff_frac: Perbill::zero(),418			negative: false,419			degree: 1,420		})421	}422}423424impl pallet_transaction_payment::Config for Runtime {425	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;426	type TransactionByteFee = TransactionByteFee;427	type WeightToFee = LinearFee<Balance>;428	type FeeMultiplierUpdate = ();429}430431parameter_types! {432	pub const ProposalBond: Permill = Permill::from_percent(5);433	pub const ProposalBondMinimum: Balance = 1 * UNIQUE;434	pub const SpendPeriod: BlockNumber = 5 * MINUTES;435	pub const Burn: Permill = Permill::from_percent(0);436	pub const TipCountdown: BlockNumber = 1 * DAYS;437	pub const TipFindersFee: Percent = Percent::from_percent(20);438	pub const TipReportDepositBase: Balance = 1 * UNIQUE;439	pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;440	pub const BountyDepositBase: Balance = 1 * UNIQUE;441	pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;442	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");443	pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;444	pub const MaximumReasonLength: u32 = 16384;445	pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);446	pub const BountyValueMinimum: Balance = 5 * UNIQUE;447}448449impl pallet_treasury::Config for Runtime {450	type ModuleId = TreasuryModuleId;451	type Currency = Balances;452	type ApproveOrigin = EnsureRoot<AccountId>;453	type RejectOrigin = EnsureRoot<AccountId>;454	type Event = Event;455	type OnSlash = ();456	type ProposalBond = ProposalBond;457	type ProposalBondMinimum = ProposalBondMinimum;458	type SpendPeriod = SpendPeriod;459	type Burn = Burn;460	type BurnDestination = ();461	type SpendFunds = ();462	type WeightInfo = pallet_treasury::weights::SubstrateWeight<Runtime>;463}464465impl pallet_sudo::Config for Runtime {466    type Event = Event;467    type Call = Call;468}469470parameter_types! {471	pub const MinVestedTransfer: Balance = 10 * UNIQUE;472}473474impl pallet_vesting::Config for Runtime {475	type Event = Event;476	type Currency = Balances;477	type BlockNumberToBalance = ConvertInto;478	type MinVestedTransfer = MinVestedTransfer;479	type WeightInfo = ();480}481482parameter_types! {483	pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account();484	pub const CollectionCreationPrice: Balance = 100 * UNIQUE;485}486487/// Used for the pallet nft in `./nft.rs`488impl pallet_nft::Config for Runtime {489    type Event = Event;490    type WeightInfo = nft_weights::WeightInfo;491	type Currency = Balances;492	type CollectionCreationPrice = CollectionCreationPrice;493	type TreasuryAccountId = TreasuryAccountId;494}495496/// Reimport pallet inflation497extern crate pallet_inflation;498pub use pallet_inflation::*;499500parameter_types! {501	pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied502}503504/// Used for the pallet inflation505impl pallet_inflation::Config for Runtime {506	type Currency = Balances;507	type TreasuryAccountId = TreasuryAccountId;508	type InflationBlockInterval = InflationBlockInterval;509}510511512parameter_types! {513	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *514		RuntimeBlockWeights::get().max_block;515	pub const MaxScheduledPerBlock: u32 = 50;516}517518pub struct Sponsoring;519impl SponsoringResolve<AccountId, Call> for Sponsoring {520521	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId> 522	where 523		Call: Dispatchable<Info=DispatchInfo>,524		Call: IsSubType<pallet_nft::Call<Runtime>>, 525		Call: IsSubType<pallet_contracts::Call<Runtime>>,526		AccountId: AsRef<[u8]>,527		AccountId: UncheckedFrom<Hash>528	{529		pallet_nft_transaction_payment::Module::<Runtime>::withdraw_type(who, call)530	}531}532533impl pallet_scheduler::Config for Runtime {534	type Event = Event;535	type Origin = Origin;536	type PalletsOrigin = OriginCaller;537	type Call = Call;538	type MaximumWeight = MaximumSchedulerWeight;539	type ScheduleOrigin = EnsureSigned<AccountId>;540	type MaxScheduledPerBlock = MaxScheduledPerBlock;541	type Sponsoring = Sponsoring;542	type WeightInfo = ();543}544545impl pallet_nft_transaction_payment::Config for Runtime {546}547548impl pallet_nft_charge_transaction::Config for Runtime {549}550551construct_runtime!(552    pub enum Runtime where553        Block = Block,554        NodeBlock = opaque::Block,555        UncheckedExtrinsic = UncheckedExtrinsic556    {557        System: system::{Module, Call, Config, Storage, Event<T>},558        RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},559        Contracts: pallet_contracts::{Module, Call, Config<T>, Storage, Event<T>},560        Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},561        Aura: pallet_aura::{Module, Config<T> },562        Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},563        Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},564        TransactionPayment: pallet_transaction_payment::{Module, Storage},565        Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},566		Inflation: pallet_inflation::{Module, Call, Storage},567		Scheduler: pallet_scheduler::{Module, Call, Storage, Event<T>},568        Nft: pallet_nft::{Module, Call, Config<T>, Storage, Event<T>},569        Treasury: pallet_treasury::{Module, Call, Storage, Config, Event<T>},570		Vesting: pallet_vesting::{Module, Call, Config<T>, Storage, Event<T>},571		NftPayment: pallet_nft_transaction_payment::{Module, Call, Storage},572		Charging: pallet_nft_charge_transaction::{Module, Call, Storage },573    }574);575576/// The address format for describing accounts.577pub type Address = AccountId;578/// Block header type as expected by this runtime.579pub type Header = generic::Header<BlockNumber, BlakeTwo256>;580/// Block type as expected by this runtime.581pub type Block = generic::Block<Header, UncheckedExtrinsic>;582/// A Block signed with a Justification583pub type SignedBlock = generic::SignedBlock<Block>;584/// BlockId type as expected by this runtime.585pub type BlockId = generic::BlockId<Block>;586/// The SignedExtension to the basic transaction logic.587pub type SignedExtra = (588    system::CheckSpecVersion<Runtime>,589    system::CheckTxVersion<Runtime>,590    system::CheckGenesis<Runtime>,591    system::CheckEra<Runtime>,592    system::CheckNonce<Runtime>,593    system::CheckWeight<Runtime>,594    pallet_nft_charge_transaction::ChargeTransactionPayment<Runtime>,595);596/// Unchecked extrinsic type as expected by this runtime.597pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;598/// Extrinsic type that has already been checked.599pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;600/// Executive: handles dispatch to the various modules.601pub type Executive =602    frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;603604impl_runtime_apis! {605606	impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>607		for Runtime608	{609		fn call(610			origin: AccountId,611			dest: AccountId,612			value: Balance,613			gas_limit: u64,614			input_data: Vec<u8>,615		) -> pallet_contracts_primitives::ContractExecResult {616			Contracts::bare_call(origin, dest, value, gas_limit, input_data)617		}618619		fn get_storage(620			address: AccountId,621			key: [u8; 32],622		) -> pallet_contracts_primitives::GetStorageResult {623			Contracts::get_storage(address, key)624		}625626		fn rent_projection(627			address: AccountId,628		) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {629			Contracts::rent_projection(address)630		}631	}632633    impl sp_api::Core<Block> for Runtime {634        fn version() -> RuntimeVersion {635            VERSION636        }637638        fn execute_block(block: Block) {639            Executive::execute_block(block)640        }641642        fn initialize_block(header: &<Block as BlockT>::Header) {643            Executive::initialize_block(header)644        }645    }646647    impl sp_api::Metadata<Block> for Runtime {648        fn metadata() -> OpaqueMetadata {649            Runtime::metadata().into()650        }651    }652653    impl sp_block_builder::BlockBuilder<Block> for Runtime {654        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {655            Executive::apply_extrinsic(extrinsic)656        }657658        fn finalize_block() -> <Block as BlockT>::Header {659            Executive::finalize_block()660        }661662        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {663            data.create_extrinsics()664        }665666        fn check_inherents(667            block: Block,668            data: sp_inherents::InherentData,669        ) -> sp_inherents::CheckInherentsResult {670            data.check_extrinsics(&block)671        }672673        fn random_seed() -> <Block as BlockT>::Hash {674            RandomnessCollectiveFlip::random_seed()675        }676    }677678    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {679        fn validate_transaction(680            source: TransactionSource,681            tx: <Block as BlockT>::Extrinsic,682        ) -> TransactionValidity {683            Executive::validate_transaction(source, tx)684        }685    }686687    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {688        fn offchain_worker(header: &<Block as BlockT>::Header) {689            Executive::offchain_worker(header)690        }691    }692693    impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {694        fn slot_duration() -> u64 {695            Aura::slot_duration()696        }697698        fn authorities() -> Vec<AuraId> {699            Aura::authorities()700        }701    }702703    impl sp_session::SessionKeys<Block> for Runtime {704        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {705            opaque::SessionKeys::generate(seed)706        }707708        fn decode_session_keys(709            encoded: Vec<u8>,710        ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {711            opaque::SessionKeys::decode_into_raw_public_keys(&encoded)712        }713    }714715	impl fg_primitives::GrandpaApi<Block> for Runtime {716		fn grandpa_authorities() -> GrandpaAuthorityList {717			Grandpa::grandpa_authorities()718		}719720		fn submit_report_equivocation_unsigned_extrinsic(721			_equivocation_proof: fg_primitives::EquivocationProof<722				<Block as BlockT>::Hash,723				NumberFor<Block>,724			>,725			_key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,726		) -> Option<()> {727			None728		}729730		fn generate_key_ownership_proof(731			_set_id: fg_primitives::SetId,732			_authority_id: GrandpaId,733		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {734			// NOTE: this is the only implementation possible since we've735			// defined our key owner proof type as a bottom type (i.e. a type736			// with no values).737			None738		}739    }740    741	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {742		fn account_nonce(account: AccountId) -> Index {743			System::account_nonce(account)744		}745	}746747	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {748		fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {749			TransactionPayment::query_info(uxt, len)750		}751		fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {752			TransactionPayment::query_fee_details(uxt, len)753		}754	}755756    #[cfg(feature = "runtime-benchmarks")]757	impl frame_benchmarking::Benchmark<Block> for Runtime {758		fn dispatch_benchmark(759			config: frame_benchmarking::BenchmarkConfig760		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {761			use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};762763			let whitelist: Vec<TrackedStorageKey> = vec![764				// Alice account765				hex_literal::hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d").to_vec().into(),766				// // Total Issuance767				// hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),768				// // Execution Phase769				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),770				// // Event Count771				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),772				// // System Events773				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),774            ];775776			let mut batches = Vec::<BenchmarkBatch>::new();777			let params = (&config, &whitelist);778779			add_benchmark!(params, batches, pallet_nft, Nft);780			add_benchmark!(params, batches, pallet_inflation, Inflation);781782			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }783			Ok(batches)784		}785	}786}