referrerpolicy=no-referrer-when-downgrade

parachain_template_runtime/
apis.rs

1// This is free and unencumbered software released into the public domain.
2//
3// Anyone is free to copy, modify, publish, use, compile, sell, or
4// distribute this software, either in source code form or as a compiled
5// binary, for any purpose, commercial or non-commercial, and by any
6// means.
7//
8// In jurisdictions that recognize copyright laws, the author or authors
9// of this software dedicate any and all copyright interest in the
10// software to the public domain. We make this dedication for the benefit
11// of the public at large and to the detriment of our heirs and
12// successors. We intend this dedication to be an overt act of
13// relinquishment in perpetuity of all present and future rights to this
14// software under copyright law.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22// OTHER DEALINGS IN THE SOFTWARE.
23//
24// For more information, please refer to <http://unlicense.org>
25
26// External crates imports
27use alloc::vec::Vec;
28
29use polkadot_sdk::{staging_parachain_info as parachain_info, *};
30
31use cumulus_primitives_core::ParaId;
32use frame_support::{
33	genesis_builder_helper::{build_state, get_preset},
34	weights::Weight,
35};
36use pallet_aura::Authorities;
37use sp_api::impl_runtime_apis;
38use sp_consensus_aura::sr25519::AuthorityId as AuraId;
39use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
40use sp_runtime::{
41	traits::Block as BlockT,
42	transaction_validity::{TransactionSource, TransactionValidity},
43	ApplyExtrinsicResult,
44};
45use sp_version::RuntimeVersion;
46
47// Local module imports
48use super::{
49	AccountId, Balance, Block, ConsensusHook, Executive, InherentDataExt, Nonce, ParachainSystem,
50	Runtime, RuntimeCall, RuntimeGenesisConfig, SessionKeys, System, TransactionPayment,
51	SLOT_DURATION, VERSION,
52};
53
54// we move some impls outside so we can easily use them with `docify`.
55impl Runtime {
56	#[docify::export]
57	fn impl_slot_duration() -> sp_consensus_aura::SlotDuration {
58		sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
59	}
60
61	#[docify::export]
62	fn impl_can_build_upon(
63		included_hash: <Block as BlockT>::Hash,
64		slot: cumulus_primitives_aura::Slot,
65	) -> bool {
66		ConsensusHook::can_build_upon(included_hash, slot)
67	}
68}
69
70impl_runtime_apis! {
71	impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
72		fn slot_duration() -> sp_consensus_aura::SlotDuration {
73			Runtime::impl_slot_duration()
74		}
75
76		fn authorities() -> Vec<AuraId> {
77			Authorities::<Runtime>::get().into_inner()
78		}
79	}
80
81	impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
82		fn relay_parent_offset() -> u32 {
83			0
84		}
85	}
86
87	impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
88		fn can_build_upon(
89			included_hash: <Block as BlockT>::Hash,
90			slot: cumulus_primitives_aura::Slot,
91		) -> bool {
92			Runtime::impl_can_build_upon(included_hash, slot)
93		}
94	}
95
96	impl sp_api::Core<Block> for Runtime {
97		fn version() -> RuntimeVersion {
98			VERSION
99		}
100
101		fn execute_block(block: Block) {
102			Executive::execute_block(block)
103		}
104
105		fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
106			Executive::initialize_block(header)
107		}
108	}
109
110	impl sp_api::Metadata<Block> for Runtime {
111		fn metadata() -> OpaqueMetadata {
112			OpaqueMetadata::new(Runtime::metadata().into())
113		}
114
115		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
116			Runtime::metadata_at_version(version)
117		}
118
119		fn metadata_versions() -> Vec<u32> {
120			Runtime::metadata_versions()
121		}
122	}
123
124	impl frame_support::view_functions::runtime_api::RuntimeViewFunction<Block> for Runtime {
125		fn execute_view_function(id: frame_support::view_functions::ViewFunctionId, input: Vec<u8>) -> Result<Vec<u8>, frame_support::view_functions::ViewFunctionDispatchError> {
126			Runtime::execute_view_function(id, input)
127		}
128	}
129
130	impl sp_block_builder::BlockBuilder<Block> for Runtime {
131		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
132			Executive::apply_extrinsic(extrinsic)
133		}
134
135		fn finalize_block() -> <Block as BlockT>::Header {
136			Executive::finalize_block()
137		}
138
139		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
140			data.create_extrinsics()
141		}
142
143		fn check_inherents(
144			block: Block,
145			data: sp_inherents::InherentData,
146		) -> sp_inherents::CheckInherentsResult {
147			data.check_extrinsics(&block)
148		}
149	}
150
151	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
152		fn validate_transaction(
153			source: TransactionSource,
154			tx: <Block as BlockT>::Extrinsic,
155			block_hash: <Block as BlockT>::Hash,
156		) -> TransactionValidity {
157			Executive::validate_transaction(source, tx, block_hash)
158		}
159	}
160
161	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
162		fn offchain_worker(header: &<Block as BlockT>::Header) {
163			Executive::offchain_worker(header)
164		}
165	}
166
167	impl sp_session::SessionKeys<Block> for Runtime {
168		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
169			SessionKeys::generate(seed)
170		}
171
172		fn decode_session_keys(
173			encoded: Vec<u8>,
174		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
175			SessionKeys::decode_into_raw_public_keys(&encoded)
176		}
177	}
178
179	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
180		fn account_nonce(account: AccountId) -> Nonce {
181			System::account_nonce(account)
182		}
183	}
184
185	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
186		fn query_info(
187			uxt: <Block as BlockT>::Extrinsic,
188			len: u32,
189		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
190			TransactionPayment::query_info(uxt, len)
191		}
192		fn query_fee_details(
193			uxt: <Block as BlockT>::Extrinsic,
194			len: u32,
195		) -> pallet_transaction_payment::FeeDetails<Balance> {
196			TransactionPayment::query_fee_details(uxt, len)
197		}
198		fn query_weight_to_fee(weight: Weight) -> Balance {
199			TransactionPayment::weight_to_fee(weight)
200		}
201		fn query_length_to_fee(length: u32) -> Balance {
202			TransactionPayment::length_to_fee(length)
203		}
204	}
205
206	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
207		for Runtime
208	{
209		fn query_call_info(
210			call: RuntimeCall,
211			len: u32,
212		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
213			TransactionPayment::query_call_info(call, len)
214		}
215		fn query_call_fee_details(
216			call: RuntimeCall,
217			len: u32,
218		) -> pallet_transaction_payment::FeeDetails<Balance> {
219			TransactionPayment::query_call_fee_details(call, len)
220		}
221		fn query_weight_to_fee(weight: Weight) -> Balance {
222			TransactionPayment::weight_to_fee(weight)
223		}
224		fn query_length_to_fee(length: u32) -> Balance {
225			TransactionPayment::length_to_fee(length)
226		}
227	}
228
229	impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
230		fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
231			ParachainSystem::collect_collation_info(header)
232		}
233	}
234
235	#[cfg(feature = "try-runtime")]
236	impl frame_try_runtime::TryRuntime<Block> for Runtime {
237		fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
238			use super::configs::RuntimeBlockWeights;
239
240			let weight = Executive::try_runtime_upgrade(checks).unwrap();
241			(weight, RuntimeBlockWeights::get().max_block)
242		}
243
244		fn execute_block(
245			block: Block,
246			state_root_check: bool,
247			signature_check: bool,
248			select: frame_try_runtime::TryStateSelect,
249		) -> Weight {
250			// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
251			// have a backtrace here.
252			Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap()
253		}
254	}
255
256	#[cfg(feature = "runtime-benchmarks")]
257	impl frame_benchmarking::Benchmark<Block> for Runtime {
258		fn benchmark_metadata(extra: bool) -> (
259			Vec<frame_benchmarking::BenchmarkList>,
260			Vec<polkadot_sdk::frame_support::traits::StorageInfo>,
261		) {
262			use frame_benchmarking::BenchmarkList;
263			use polkadot_sdk::frame_support::traits::StorageInfoTrait;
264			use frame_system_benchmarking::Pallet as SystemBench;
265			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
266			use super::*;
267
268			let mut list = Vec::<BenchmarkList>::new();
269			list_benchmarks!(list, extra);
270
271			let storage_info = AllPalletsWithSystem::storage_info();
272			(list, storage_info)
273		}
274
275		#[allow(non_local_definitions)]
276		fn dispatch_benchmark(
277			config: frame_benchmarking::BenchmarkConfig
278		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
279			use frame_benchmarking::{BenchmarkError, BenchmarkBatch};
280			use super::*;
281
282			use frame_system_benchmarking::Pallet as SystemBench;
283			impl frame_system_benchmarking::Config for Runtime {
284				fn setup_set_code_requirements(code: &Vec<u8>) -> Result<(), BenchmarkError> {
285					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
286					Ok(())
287				}
288
289				fn verify_set_code() {
290					System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
291				}
292			}
293
294			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
295			impl cumulus_pallet_session_benchmarking::Config for Runtime {}
296
297			use polkadot_sdk::frame_support::traits::WhitelistedStorageKeys;
298			let whitelist = AllPalletsWithSystem::whitelisted_storage_keys();
299
300			let mut batches = Vec::<BenchmarkBatch>::new();
301			let params = (&config, &whitelist);
302			add_benchmarks!(params, batches);
303
304			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
305			Ok(batches)
306		}
307	}
308
309	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
310		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
311			build_state::<RuntimeGenesisConfig>(config)
312		}
313
314		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
315			get_preset::<RuntimeGenesisConfig>(id, crate::genesis_config_presets::get_preset)
316		}
317
318		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
319			crate::genesis_config_presets::preset_names()
320		}
321	}
322
323	impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
324		fn parachain_id() -> ParaId {
325			parachain_info::Pallet::<Runtime>::parachain_id()
326		}
327	}
328}