contracts_rococo_runtime/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17//! # Contracts Parachain
18//!
19//! A parachain for using FRAME's `pallet-contracts` and ink! contracts.
20
21#![cfg_attr(not(feature = "std"), no_std)]
22#![recursion_limit = "256"]
23
24// Make the WASM binary available.
25#[cfg(feature = "std")]
26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
27
28mod contracts;
29mod weights;
30pub mod xcm_config;
31
32extern crate alloc;
33
34use alloc::{vec, vec::Vec};
35use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
36use cumulus_primitives_core::{AggregateMessageOrigin, ClaimQueueOffset, CoreSelector};
37use sp_api::impl_runtime_apis;
38use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
39use sp_runtime::{
40	generic, impl_opaque_keys,
41	traits::Block as BlockT,
42	transaction_validity::{TransactionSource, TransactionValidity},
43	ApplyExtrinsicResult, Perbill,
44};
45
46#[cfg(feature = "std")]
47use sp_version::NativeVersion;
48use sp_version::RuntimeVersion;
49
50use frame_support::{
51	construct_runtime, derive_impl,
52	dispatch::DispatchClass,
53	genesis_builder_helper::{build_state, get_preset},
54	parameter_types,
55	traits::{ConstBool, ConstU32, ConstU64, ConstU8},
56	weights::{ConstantMultiplier, Weight, WeightToFee as _},
57	PalletId,
58};
59use frame_system::limits::{BlockLength, BlockWeights};
60pub use parachains_common as common;
61use parachains_common::{
62	impls::DealWithFees, message_queue::*, AccountId, BlockNumber, Hash, Header, Nonce, Signature,
63	AVERAGE_ON_INITIALIZE_RATIO, NORMAL_DISPATCH_RATIO,
64};
65pub use parachains_common::{AuraId, Balance};
66use testnet_parachains_constants::rococo::{consensus::*, currency::*, fee::WeightToFee, time::*};
67use xcm::{prelude::*, Version as XcmVersion};
68use xcm_config::CollatorSelectionUpdateOrigin;
69use xcm_runtime_apis::{
70	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
71	fees::Error as XcmPaymentApiError,
72};
73
74#[cfg(any(feature = "std", test))]
75pub use sp_runtime::BuildStorage;
76
77// Polkadot imports
78use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
79
80use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
81
82/// The address format for describing accounts.
83pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
84/// Block type as expected by this runtime.
85pub type Block = generic::Block<Header, UncheckedExtrinsic>;
86/// A Block signed with a Justification
87pub type SignedBlock = generic::SignedBlock<Block>;
88/// BlockId type as expected by this runtime.
89pub type BlockId = generic::BlockId<Block>;
90/// The extension to the basic transaction logic.
91pub type TxExtension = (
92	frame_system::CheckNonZeroSender<Runtime>,
93	frame_system::CheckSpecVersion<Runtime>,
94	frame_system::CheckTxVersion<Runtime>,
95	frame_system::CheckGenesis<Runtime>,
96	frame_system::CheckEra<Runtime>,
97	frame_system::CheckNonce<Runtime>,
98	frame_system::CheckWeight<Runtime>,
99	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
100	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
101);
102/// Unchecked extrinsic type as expected by this runtime.
103pub type UncheckedExtrinsic =
104	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
105
106/// Migrations to apply on runtime upgrade.
107pub type Migrations = (
108	pallet_collator_selection::migration::v1::MigrateToV1<Runtime>,
109	pallet_collator_selection::migration::v2::MigrationToV2<Runtime>,
110	cumulus_pallet_parachain_system::migration::Migration<Runtime>,
111	cumulus_pallet_xcmp_queue::migration::v2::MigrationToV2<Runtime>,
112	cumulus_pallet_xcmp_queue::migration::v3::MigrationToV3<Runtime>,
113	pallet_contracts::Migration<Runtime>,
114	// unreleased
115	cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
116	cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5<Runtime>,
117	// permanent
118	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
119);
120
121type EventRecord = frame_system::EventRecord<
122	<Runtime as frame_system::Config>::RuntimeEvent,
123	<Runtime as frame_system::Config>::Hash,
124>;
125
126/// Executive: handles dispatch to the various modules.
127pub type Executive = frame_executive::Executive<
128	Runtime,
129	Block,
130	frame_system::ChainContext<Runtime>,
131	Runtime,
132	AllPalletsWithSystem,
133	Migrations,
134>;
135
136impl_opaque_keys! {
137	pub struct SessionKeys {
138		pub aura: Aura,
139	}
140}
141
142#[sp_version::runtime_version]
143pub const VERSION: RuntimeVersion = RuntimeVersion {
144	spec_name: alloc::borrow::Cow::Borrowed("contracts-rococo"),
145	impl_name: alloc::borrow::Cow::Borrowed("contracts-rococo"),
146	authoring_version: 1,
147	spec_version: 1_017_001,
148	impl_version: 0,
149	apis: RUNTIME_API_VERSIONS,
150	transaction_version: 7,
151	system_version: 1,
152};
153
154/// The version information used to identify this runtime when compiled natively.
155#[cfg(feature = "std")]
156pub fn native_version() -> NativeVersion {
157	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
158}
159
160parameter_types! {
161	pub const Version: RuntimeVersion = VERSION;
162	pub RuntimeBlockLength: BlockLength =
163		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
164	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
165		.base_block(BlockExecutionWeight::get())
166		.for_class(DispatchClass::all(), |weights| {
167			weights.base_extrinsic = ExtrinsicBaseWeight::get();
168		})
169		.for_class(DispatchClass::Normal, |weights| {
170			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
171		})
172		.for_class(DispatchClass::Operational, |weights| {
173			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
174			// Operational transactions have some extra reserved space, so that they
175			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
176			weights.reserved = Some(
177				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
178			);
179		})
180		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
181		.build_or_panic();
182	pub const SS58Prefix: u8 = 42;
183}
184
185// Configure FRAME pallets to include in runtime.
186#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)]
187impl frame_system::Config for Runtime {
188	type BlockWeights = RuntimeBlockWeights;
189	type BlockLength = RuntimeBlockLength;
190	type AccountId = AccountId;
191	type Nonce = Nonce;
192	type Hash = Hash;
193	type Block = Block;
194	type BlockHashCount = BlockHashCount;
195	type DbWeight = RocksDbWeight;
196	type Version = Version;
197	type AccountData = pallet_balances::AccountData<Balance>;
198	type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
199	type SS58Prefix = SS58Prefix;
200	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
201	type MaxConsumers = ConstU32<16>;
202}
203
204impl pallet_timestamp::Config for Runtime {
205	/// A timestamp: milliseconds since the unix epoch.
206	type Moment = u64;
207	type OnTimestampSet = Aura;
208	type MinimumPeriod = ConstU64<0>;
209	type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
210}
211
212impl pallet_authorship::Config for Runtime {
213	type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
214	type EventHandler = (CollatorSelection,);
215}
216
217parameter_types! {
218	pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
219}
220
221impl pallet_balances::Config for Runtime {
222	type MaxLocks = ConstU32<50>;
223	/// The type for recording an account's balance.
224	type Balance = Balance;
225	/// The ubiquitous event type.
226	type RuntimeEvent = RuntimeEvent;
227	type DustRemoval = ();
228	type ExistentialDeposit = ExistentialDeposit;
229	type AccountStore = System;
230	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
231	type MaxReserves = ConstU32<50>;
232	type ReserveIdentifier = [u8; 8];
233	type RuntimeHoldReason = RuntimeHoldReason;
234	type RuntimeFreezeReason = RuntimeFreezeReason;
235	type FreezeIdentifier = ();
236	type MaxFreezes = ConstU32<0>;
237	type DoneSlashHandler = ();
238}
239
240parameter_types! {
241	pub const TransactionByteFee: Balance = MILLICENTS;
242}
243
244impl pallet_transaction_payment::Config for Runtime {
245	type RuntimeEvent = RuntimeEvent;
246	type OnChargeTransaction =
247		pallet_transaction_payment::FungibleAdapter<Balances, DealWithFees<Runtime>>;
248	type WeightToFee = WeightToFee;
249	/// Relay Chain `TransactionByteFee` / 10
250	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
251	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
252	type OperationalFeeMultiplier = ConstU8<5>;
253	type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
254}
255
256parameter_types! {
257	// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
258	pub const DepositBase: Balance = deposit(1, 88);
259	// Additional storage item size of 32 bytes.
260	pub const DepositFactor: Balance = deposit(0, 32);
261}
262
263impl pallet_multisig::Config for Runtime {
264	type RuntimeEvent = RuntimeEvent;
265	type RuntimeCall = RuntimeCall;
266	type Currency = Balances;
267	type DepositBase = DepositBase;
268	type DepositFactor = DepositFactor;
269	type MaxSignatories = ConstU32<100>;
270	type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
271}
272
273impl pallet_utility::Config for Runtime {
274	type RuntimeEvent = RuntimeEvent;
275	type RuntimeCall = RuntimeCall;
276	type PalletsOrigin = OriginCaller;
277	type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
278}
279
280parameter_types! {
281	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
282	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
283	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
284}
285
286impl cumulus_pallet_parachain_system::Config for Runtime {
287	type WeightInfo = ();
288	type RuntimeEvent = RuntimeEvent;
289	type OnSystemEvent = ();
290	type SelfParaId = parachain_info::Pallet<Runtime>;
291	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
292	type ReservedDmpWeight = ReservedDmpWeight;
293	type OutboundXcmpMessageSource = XcmpQueue;
294	type XcmpMessageHandler = XcmpQueue;
295	type ReservedXcmpWeight = ReservedXcmpWeight;
296	type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
297	type ConsensusHook = ConsensusHook;
298	type SelectCore = cumulus_pallet_parachain_system::DefaultCoreSelector<Runtime>;
299}
300
301type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
302	Runtime,
303	RELAY_CHAIN_SLOT_DURATION_MILLIS,
304	BLOCK_PROCESSING_VELOCITY,
305	UNINCLUDED_SEGMENT_CAPACITY,
306>;
307
308impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
309
310impl parachain_info::Config for Runtime {}
311
312parameter_types! {
313	pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
314}
315
316impl pallet_message_queue::Config for Runtime {
317	type RuntimeEvent = RuntimeEvent;
318	type WeightInfo = ();
319	#[cfg(feature = "runtime-benchmarks")]
320	type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor<
321		cumulus_primitives_core::AggregateMessageOrigin,
322	>;
323	#[cfg(not(feature = "runtime-benchmarks"))]
324	type MessageProcessor = xcm_builder::ProcessXcmMessage<
325		AggregateMessageOrigin,
326		xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
327		RuntimeCall,
328	>;
329	type Size = u32;
330	// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
331	type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
332	type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
333	type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>;
334	type MaxStale = sp_core::ConstU32<8>;
335	type ServiceWeight = MessageQueueServiceWeight;
336	type IdleMaxServiceWeight = MessageQueueServiceWeight;
337}
338
339impl cumulus_pallet_aura_ext::Config for Runtime {}
340
341parameter_types! {
342	pub const Period: u32 = 10 * MINUTES;
343	pub const Offset: u32 = 0;
344}
345
346impl pallet_session::Config for Runtime {
347	type RuntimeEvent = RuntimeEvent;
348	type ValidatorId = <Self as frame_system::Config>::AccountId;
349	// we don't have stash and controller, thus we don't need the convert as well.
350	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
351	type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
352	type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
353	type SessionManager = CollatorSelection;
354	// Essentially just Aura, but let's be pedantic.
355	type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
356	type Keys = SessionKeys;
357	type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
358}
359
360impl pallet_aura::Config for Runtime {
361	type AuthorityId = AuraId;
362	type DisabledValidators = ();
363	type MaxAuthorities = ConstU32<100_000>;
364	type AllowMultipleBlocksPerSlot = ConstBool<true>;
365	type SlotDuration = ConstU64<SLOT_DURATION>;
366}
367
368parameter_types! {
369	pub const PotId: PalletId = PalletId(*b"PotStake");
370}
371
372impl pallet_collator_selection::Config for Runtime {
373	type RuntimeEvent = RuntimeEvent;
374	type Currency = Balances;
375	type UpdateOrigin = CollatorSelectionUpdateOrigin;
376	type PotId = PotId;
377	type MaxCandidates = ConstU32<100>;
378	type MinEligibleCollators = ConstU32<1>;
379	type MaxInvulnerables = ConstU32<20>;
380	// should be a multiple of session or things will get inconsistent
381	type KickThreshold = Period;
382	type ValidatorId = <Self as frame_system::Config>::AccountId;
383	type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
384	type ValidatorRegistration = Session;
385	type WeightInfo = pallet_collator_selection::weights::SubstrateWeight<Runtime>;
386}
387
388impl pallet_sudo::Config for Runtime {
389	type RuntimeCall = RuntimeCall;
390	type RuntimeEvent = RuntimeEvent;
391	type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
392}
393
394// Create the runtime by composing the FRAME pallets that were previously configured.
395construct_runtime!(
396	pub enum Runtime
397	{
398		// System support stuff.
399		System: frame_system = 0,
400		ParachainSystem: cumulus_pallet_parachain_system = 1,
401		RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 2,
402		Timestamp: pallet_timestamp = 3,
403		ParachainInfo: parachain_info = 4,
404
405		// Monetary stuff.
406		Balances: pallet_balances = 10,
407		TransactionPayment: pallet_transaction_payment = 11,
408
409		// Collator support. The order of these 5 are important and shall not change.
410		Authorship: pallet_authorship = 20,
411		CollatorSelection: pallet_collator_selection = 21,
412		Session: pallet_session = 22,
413		Aura: pallet_aura = 23,
414		AuraExt: cumulus_pallet_aura_ext = 24,
415
416		// XCM helpers.
417		XcmpQueue: cumulus_pallet_xcmp_queue = 30,
418		PolkadotXcm: pallet_xcm = 31,
419		CumulusXcm: cumulus_pallet_xcm = 32,
420		MessageQueue: pallet_message_queue = 34,
421
422		// Smart Contracts.
423		Contracts: pallet_contracts = 40,
424
425		// Handy utilities.
426		Utility: pallet_utility = 50,
427		Multisig: pallet_multisig = 51,
428
429		// Sudo
430		Sudo: pallet_sudo = 100,
431	}
432);
433
434#[cfg(feature = "runtime-benchmarks")]
435mod benches {
436	frame_benchmarking::define_benchmarks!(
437		[frame_system, SystemBench::<Runtime>]
438		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
439		[pallet_balances, Balances]
440		[pallet_message_queue, MessageQueue]
441		[pallet_multisig, Multisig]
442		[pallet_session, SessionBench::<Runtime>]
443		[pallet_utility, Utility]
444		[pallet_sudo, Sudo]
445		[pallet_timestamp, Timestamp]
446		[pallet_collator_selection, CollatorSelection]
447		[cumulus_pallet_parachain_system, ParachainSystem]
448		[pallet_contracts, Contracts]
449		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
450	);
451}
452
453impl_runtime_apis! {
454	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
455		fn slot_duration() -> sp_consensus_aura::SlotDuration {
456			sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
457		}
458
459		fn authorities() -> Vec<AuraId> {
460			pallet_aura::Authorities::<Runtime>::get().into_inner()
461		}
462	}
463
464	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
465		fn can_build_upon(
466			included_hash: <Block as BlockT>::Hash,
467			slot: cumulus_primitives_aura::Slot,
468		) -> bool {
469			ConsensusHook::can_build_upon(included_hash, slot)
470		}
471	}
472
473	impl sp_api::Core<Block> for Runtime {
474		fn version() -> RuntimeVersion {
475			VERSION
476		}
477
478		fn execute_block(block: Block) {
479			Executive::execute_block(block)
480		}
481
482		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
483			Executive::initialize_block(header)
484		}
485	}
486
487	impl sp_api::Metadata<Block> for Runtime {
488		fn metadata() -> OpaqueMetadata {
489			OpaqueMetadata::new(Runtime::metadata().into())
490		}
491
492		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
493			Runtime::metadata_at_version(version)
494		}
495
496		fn metadata_versions() -> alloc::vec::Vec<u32> {
497			Runtime::metadata_versions()
498		}
499	}
500
501	impl sp_block_builder::BlockBuilder<Block> for Runtime {
502		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
503			Executive::apply_extrinsic(extrinsic)
504		}
505
506		fn finalize_block() -> <Block as BlockT>::Header {
507			Executive::finalize_block()
508		}
509
510		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
511			data.create_extrinsics()
512		}
513
514		fn check_inherents(
515			block: Block,
516			data: sp_inherents::InherentData,
517		) -> sp_inherents::CheckInherentsResult {
518			data.check_extrinsics(&block)
519		}
520	}
521
522	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
523		fn validate_transaction(
524			source: TransactionSource,
525			tx: <Block as BlockT>::Extrinsic,
526			block_hash: <Block as BlockT>::Hash,
527		) -> TransactionValidity {
528			Executive::validate_transaction(source, tx, block_hash)
529		}
530	}
531
532	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
533		fn offchain_worker(header: &<Block as BlockT>::Header) {
534			Executive::offchain_worker(header)
535		}
536	}
537
538	impl sp_session::SessionKeys<Block> for Runtime {
539		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
540			SessionKeys::generate(seed)
541		}
542
543		fn decode_session_keys(
544			encoded: Vec<u8>,
545		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
546			SessionKeys::decode_into_raw_public_keys(&encoded)
547		}
548	}
549
550	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
551		fn account_nonce(account: AccountId) -> Nonce {
552			System::account_nonce(account)
553		}
554	}
555
556	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
557		fn query_info(
558			uxt: <Block as BlockT>::Extrinsic,
559			len: u32,
560		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
561			TransactionPayment::query_info(uxt, len)
562		}
563		fn query_fee_details(
564			uxt: <Block as BlockT>::Extrinsic,
565			len: u32,
566		) -> pallet_transaction_payment::FeeDetails<Balance> {
567			TransactionPayment::query_fee_details(uxt, len)
568		}
569		fn query_weight_to_fee(weight: Weight) -> Balance {
570			TransactionPayment::weight_to_fee(weight)
571		}
572		fn query_length_to_fee(length: u32) -> Balance {
573			TransactionPayment::length_to_fee(length)
574		}
575	}
576
577	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
578		for Runtime
579	{
580		fn query_call_info(
581			call: RuntimeCall,
582			len: u32,
583		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
584			TransactionPayment::query_call_info(call, len)
585		}
586		fn query_call_fee_details(
587			call: RuntimeCall,
588			len: u32,
589		) -> pallet_transaction_payment::FeeDetails<Balance> {
590			TransactionPayment::query_call_fee_details(call, len)
591		}
592		fn query_weight_to_fee(weight: Weight) -> Balance {
593			TransactionPayment::weight_to_fee(weight)
594		}
595		fn query_length_to_fee(length: u32) -> Balance {
596			TransactionPayment::length_to_fee(length)
597		}
598	}
599
600	impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
601		fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
602			let acceptable_assets = vec![AssetId(xcm_config::RelayLocation::get())];
603			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
604		}
605
606		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
607			match asset.try_as::<AssetId>() {
608				Ok(asset_id) if asset_id.0 == xcm_config::RelayLocation::get() => {
609					// for native token
610					Ok(WeightToFee::weight_to_fee(&weight))
611				},
612				Ok(asset_id) => {
613					log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
614					Err(XcmPaymentApiError::AssetNotFound)
615				},
616				Err(_) => {
617					log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
618					Err(XcmPaymentApiError::VersionedConversionFailed)
619				}
620			}
621		}
622
623		fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
624			PolkadotXcm::query_xcm_weight(message)
625		}
626
627		fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
628			PolkadotXcm::query_delivery_fees(destination, message)
629		}
630	}
631
632	impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
633		fn dry_run_call(origin: OriginCaller, call: RuntimeCall, result_xcms_version: XcmVersion) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
634			PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call, result_xcms_version)
635		}
636
637		fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
638			PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
639		}
640	}
641
642	impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
643		fn convert_location(location: VersionedLocation) -> Result<
644			AccountId,
645			xcm_runtime_apis::conversions::Error
646		> {
647			xcm_runtime_apis::conversions::LocationToAccountHelper::<
648				AccountId,
649				xcm_config::LocationToAccountId
650			>::convert_location(location)
651		}
652	}
653
654	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
655		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
656			ParachainSystem::collect_collation_info(header)
657		}
658	}
659
660	impl cumulus_primitives_core::GetCoreSelectorApi<Block> for Runtime {
661		fn core_selector() -> (CoreSelector, ClaimQueueOffset) {
662			ParachainSystem::core_selector()
663		}
664	}
665
666	impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord> for Runtime {
667		fn call(
668			origin: AccountId,
669			dest: AccountId,
670			value: Balance,
671			gas_limit: Option<Weight>,
672			storage_deposit_limit: Option<Balance>,
673			input_data: Vec<u8>,
674		) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
675			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
676			Contracts::bare_call(
677				origin,
678				dest,
679				value,
680				gas_limit,
681				storage_deposit_limit,
682				input_data,
683				contracts::CONTRACTS_DEBUG_OUTPUT,
684				pallet_contracts::CollectEvents::UnsafeCollect,
685				pallet_contracts::Determinism::Enforced,
686			)
687		}
688
689		fn instantiate(
690			origin: AccountId,
691			value: Balance,
692			gas_limit: Option<Weight>,
693			storage_deposit_limit: Option<Balance>,
694			code: pallet_contracts::Code<Hash>,
695			data: Vec<u8>,
696			salt: Vec<u8>,
697		) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord> {
698			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
699			Contracts::bare_instantiate(
700				origin,
701				value,
702				gas_limit,
703				storage_deposit_limit,
704				code,
705				data,
706				salt,
707				contracts::CONTRACTS_DEBUG_OUTPUT,
708				pallet_contracts::CollectEvents::UnsafeCollect,
709			)
710		}
711
712		fn upload_code(
713			origin: AccountId,
714			code: Vec<u8>,
715			storage_deposit_limit: Option<Balance>,
716			determinism: pallet_contracts::Determinism,
717		) -> pallet_contracts::CodeUploadResult<Hash, Balance> {
718			Contracts::bare_upload_code(
719				origin,
720				code,
721				storage_deposit_limit,
722				determinism,
723			)
724		}
725
726		fn get_storage(
727			address: AccountId,
728			key: Vec<u8>,
729		) -> pallet_contracts::GetStorageResult {
730			Contracts::get_storage(address, key)
731		}
732	}
733
734	#[cfg(feature = "try-runtime")]
735	impl frame_try_runtime::TryRuntime<Block> for Runtime {
736		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
737			let weight = Executive::try_runtime_upgrade(checks).unwrap();
738			(weight, RuntimeBlockWeights::get().max_block)
739		}
740
741		fn execute_block(
742			block: Block,
743			state_root_check: bool,
744			signature_check: bool,
745			select: frame_try_runtime::TryStateSelect,
746		) -> Weight {
747			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
748			// have a backtrace here.
749			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
750		}
751	}
752
753	#[cfg(feature = "runtime-benchmarks")]
754	impl frame_benchmarking::Benchmark<Block> for Runtime {
755		fn benchmark_metadata(extra: bool) -> (
756			Vec<frame_benchmarking::BenchmarkList>,
757			Vec<frame_support::traits::StorageInfo>,
758		) {
759			use frame_benchmarking::{Benchmarking, BenchmarkList};
760			use frame_support::traits::StorageInfoTrait;
761			use frame_system_benchmarking::Pallet as SystemBench;
762			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
763			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
764			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
765
766			let mut list = Vec::<BenchmarkList>::new();
767			list_benchmarks!(list, extra);
768
769			let storage_info = AllPalletsWithSystem::storage_info();
770			(list, storage_info)
771		}
772
773		fn dispatch_benchmark(
774			config: frame_benchmarking::BenchmarkConfig
775		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
776			use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
777			use sp_storage::TrackedStorageKey;
778
779			use frame_system_benchmarking::Pallet as SystemBench;
780			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
781			impl frame_system_benchmarking::Config for Runtime {
782				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
783					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
784					Ok(())
785				}
786
787				fn verify_set_code() {
788					System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
789				}
790			}
791
792			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
793			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
794
795			parameter_types! {
796				pub ExistentialDepositAsset: Option<Asset> = Some((
797					xcm_config::RelayLocation::get(),
798					ExistentialDeposit::get()
799				).into());
800			}
801
802			use xcm::latest::prelude::*;
803			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
804			impl pallet_xcm::benchmarking::Config for Runtime {
805				type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
806					xcm_config::XcmConfig,
807					ExistentialDepositAsset,
808					xcm_config::PriceForParentDelivery,
809				>;
810
811				fn reachable_dest() -> Option<Location> {
812					Some(Parent.into())
813				}
814
815				fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
816					// Relay/native token can be teleported between Contracts-System-Para and Relay.
817					Some((
818						Asset {
819							fun: Fungible(ExistentialDeposit::get()),
820							id: AssetId(Parent.into())
821						},
822						Parent.into(),
823					))
824				}
825
826				fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
827					// Reserve transfers are disabled on Contracts-System-Para.
828					None
829				}
830
831				fn set_up_complex_asset_transfer(
832				) -> Option<(Assets, u32, Location, alloc::boxed::Box<dyn FnOnce()>)> {
833					// Contracts-System-Para only supports teleports to system parachain.
834					// Relay/native token can be teleported between Contracts-System-Para and Relay.
835					let native_location = Parent.into();
836					let dest = Parent.into();
837					pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
838						native_location,
839						dest
840					)
841				}
842
843				fn get_asset() -> Asset {
844					Asset {
845						id: AssetId(Location::parent()),
846						fun: Fungible(EXISTENTIAL_DEPOSIT),
847					}
848				}
849			}
850
851			let whitelist: Vec<TrackedStorageKey> = vec![
852				// Block Number
853				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
854				// Total Issuance
855				hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
856				// Execution Phase
857				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),
858				// Event Count
859				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),
860				// System Events
861				hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),
862			];
863
864			let mut batches = Vec::<BenchmarkBatch>::new();
865			let params = (&config, &whitelist);
866			add_benchmarks!(params, batches);
867
868			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
869			Ok(batches)
870		}
871	}
872
873	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
874		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
875			build_state::<RuntimeGenesisConfig>(config)
876		}
877
878		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
879			get_preset::<RuntimeGenesisConfig>(id, |_| None)
880		}
881
882		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
883			vec![]
884		}
885	}
886
887	impl xcm_runtime_apis::trusted_query::TrustedQueryApi<Block> for Runtime {
888		fn is_trusted_reserve(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
889			PolkadotXcm::is_trusted_reserve(asset, location)
890		}
891		fn is_trusted_teleporter(asset: VersionedAsset, location: VersionedLocation) -> xcm_runtime_apis::trusted_query::XcmTrustedQueryResult {
892			PolkadotXcm::is_trusted_teleporter(asset, location)
893		}
894	}
895}
896
897cumulus_pallet_parachain_system::register_validate_block! {
898	Runtime = Runtime,
899	BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
900}