1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam 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
// Moonbeam 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 Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
#[macro_export]
18
macro_rules! impl_runtime_apis_plus_common {
19
	{$($custom:tt)*} => {
20

            
21
		#[cfg(feature = "evm-tracing")]
22
		// Helper function to replay the "on_idle" hook for all pallets, we need this for
23
		// evm-tracing because some ethereum-xcm transactions might be executed at on_idle.
24
		//
25
		// We need to make sure that we replay on_idle exactly the same way as the
26
		// original block execution, but unfortunatly frame executive diosn't provide a function
27
		// to replay only on_idle, so we need to copy here some code inside frame executive.
28
20
		fn replay_on_idle() {
29
			use frame_system::pallet_prelude::BlockNumberFor;
30
			use frame_support::traits::OnIdle;
31

            
32
20
			let weight = <frame_system::Pallet<Runtime>>::block_weight();
33
20
			let max_weight = <
34
20
					<Runtime as frame_system::Config>::BlockWeights as
35
20
					frame_support::traits::Get<_>
36
20
				>::get().max_block;
37
20
			let remaining_weight = max_weight.saturating_sub(weight.total());
38
20
			if remaining_weight.all_gt(Weight::zero()) {
39
20
				let _ = <AllPalletsWithSystem as OnIdle<BlockNumberFor<Runtime>>>::on_idle(
40
20
					<frame_system::Pallet<Runtime>>::block_number(),
41
20
					remaining_weight,
42
20
				);
43
20
			}
44
20
		}
45
20

            
46
389140
		impl_runtime_apis! {
47
389140
			$($custom)*
48
389140

            
49
389140
			impl sp_api::Core<Block> for Runtime {
50
389140
				fn version() -> RuntimeVersion {
51
					VERSION
52
				}
53
389140

            
54
389140
				fn execute_block(block: Block) {
55
					Executive::execute_block(block)
56
				}
57
389140

            
58
389140
				fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
59
					Executive::initialize_block(header)
60
				}
61
389140
			}
62
389140

            
63
389140
			impl sp_api::Metadata<Block> for Runtime {
64
389140
				fn metadata() -> OpaqueMetadata {
65
					OpaqueMetadata::new(Runtime::metadata().into())
66
				}
67
389140

            
68
389140
				fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
69
					Runtime::metadata_at_version(version)
70
				}
71
389140

            
72
389140
				fn metadata_versions() -> Vec<u32> {
73
					Runtime::metadata_versions()
74
				}
75
389140
			}
76
389140

            
77
389140
			impl sp_block_builder::BlockBuilder<Block> for Runtime {
78
389140
				fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
79
					Executive::apply_extrinsic(extrinsic)
80
				}
81
389140

            
82
389140
				fn finalize_block() -> <Block as BlockT>::Header {
83
					Executive::finalize_block()
84
				}
85
389140

            
86
389140
				fn inherent_extrinsics(
87
					data: sp_inherents::InherentData,
88
				) -> Vec<<Block as BlockT>::Extrinsic> {
89
					data.create_extrinsics()
90
				}
91
389140

            
92
389140
				fn check_inherents(
93
					block: Block,
94
					data: sp_inherents::InherentData,
95
				) -> sp_inherents::CheckInherentsResult {
96
					data.check_extrinsics(&block)
97
				}
98
389140
			}
99
389140

            
100
389140
			impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
101
389140
				fn offchain_worker(header: &<Block as BlockT>::Header) {
102
					Executive::offchain_worker(header)
103
				}
104
389140
			}
105
389140

            
106
389140
			impl sp_session::SessionKeys<Block> for Runtime {
107
389140
				fn decode_session_keys(
108
					encoded: Vec<u8>,
109
				) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
110
					opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
111
				}
112
389140

            
113
389140
				fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
114
					opaque::SessionKeys::generate(seed)
115
				}
116
389140
			}
117
389140

            
118
389140
			#[cfg(not(feature = "disable-genesis-builder"))]
119
389140
			impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
120
389140
				fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
121
					frame_support::genesis_builder_helper::build_state::<RuntimeGenesisConfig>(config)
122
				}
123
389140

            
124
389140
				fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
125
					frame_support::genesis_builder_helper::get_preset::<RuntimeGenesisConfig>(id, genesis_config_preset::get_preset)
126
				}
127
389140

            
128
389140
				fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
129
					genesis_config_preset::preset_names()
130
				}
131
389140
			}
132
389140

            
133
389140
			impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
134
389140
				fn account_nonce(account: AccountId) -> Index {
135
					System::account_nonce(account)
136
				}
137
389140
			}
138
389140

            
139
389140
			impl moonbeam_rpc_primitives_debug::DebugRuntimeApi<Block> for Runtime {
140
389140
				fn trace_transaction(
141
20
					extrinsics: Vec<<Block as BlockT>::Extrinsic>,
142
20
					traced_transaction: &EthereumTransaction,
143
20
					header: &<Block as BlockT>::Header,
144
20
				) -> Result<
145
20
					(),
146
20
					sp_runtime::DispatchError,
147
20
				> {
148
20
					#[cfg(feature = "evm-tracing")]
149
20
					{
150
20
						use moonbeam_evm_tracer::tracer::EvmTracer;
151
20
						use xcm_primitives::{
152
20
							ETHEREUM_XCM_TRACING_STORAGE_KEY,
153
20
							EthereumXcmTracingStatus
154
20
						};
155
20
						use frame_support::storage::unhashed;
156
20
						use frame_system::pallet_prelude::BlockNumberFor;
157
20

            
158
20
						// Tell the CallDispatcher we are tracing a specific Transaction.
159
20
						unhashed::put::<EthereumXcmTracingStatus>(
160
20
							ETHEREUM_XCM_TRACING_STORAGE_KEY,
161
20
							&EthereumXcmTracingStatus::Transaction(traced_transaction.hash()),
162
20
						);
163
20

            
164
20
						// Initialize block: calls the "on_initialize" hook on every pallet
165
20
						// in AllPalletsWithSystem.
166
20
						// After pallet message queue was introduced, this must be done only after
167
20
						// enabling XCM tracing by setting ETHEREUM_XCM_TRACING_STORAGE_KEY
168
20
						// in the storage
169
20
						Executive::initialize_block(header);
170
20

            
171
20
						// Apply the a subset of extrinsics: all the substrate-specific or ethereum
172
20
						// transactions that preceded the requested transaction.
173
40
						for ext in extrinsics.into_iter() {
174
20
							let _ = match &ext.0.function {
175
20
								RuntimeCall::Ethereum(transact { transaction }) => {
176
20

            
177
20
									// Reset the previously consumed weight when tracing ethereum transactions.
178
20
									// This is necessary because EVM tracing introduces additional
179
20
									// (ref_time) overhead, which differs from the production runtime behavior.
180
20
									// Without resetting the block weight, the extra tracing overhead could
181
20
									// leading to some transactions to incorrectly fail during tracing.
182
20
									frame_system::BlockWeight::<Runtime>::kill();
183
20

            
184
20
									if transaction == traced_transaction {
185
20
										EvmTracer::new().trace(|| Executive::apply_extrinsic(ext));
186
20
										return Ok(());
187
20
									} else {
188
20
										Executive::apply_extrinsic(ext)
189
20
									}
190
20
								}
191
20
								_ => Executive::apply_extrinsic(ext),
192
20
							};
193
20
							if let Some(EthereumXcmTracingStatus::TransactionExited) = unhashed::get(
194
20
								ETHEREUM_XCM_TRACING_STORAGE_KEY
195
20
							) {
196
20
								return Ok(());
197
20
							}
198
20
						}
199
20

            
200
20
						if let Some(EthereumXcmTracingStatus::Transaction(_)) = unhashed::get(
201
20
							ETHEREUM_XCM_TRACING_STORAGE_KEY
202
20
						) {
203
							// If the transaction was not found, it might be
204
							// an eth-xcm transaction that was executed at on_idle
205
							replay_on_idle();
206
20
						}
207
20

            
208
20
						if let Some(EthereumXcmTracingStatus::TransactionExited) = unhashed::get(
209
20
							ETHEREUM_XCM_TRACING_STORAGE_KEY
210
20
						) {
211
20
							// The transaction was found
212
20
							Ok(())
213
20
						} else {
214
20
							// The transaction was not-found
215
20
							Err(sp_runtime::DispatchError::Other(
216
								"Failed to find Ethereum transaction among the extrinsics.",
217
							))
218
20
						}
219
20
					}
220
20
					#[cfg(not(feature = "evm-tracing"))]
221
20
					Err(sp_runtime::DispatchError::Other(
222
20
						"Missing `evm-tracing` compile time feature flag.",
223
20
					))
224
20
				}
225
389140

            
226
389140
				fn trace_block(
227
20
					extrinsics: Vec<<Block as BlockT>::Extrinsic>,
228
20
					known_transactions: Vec<H256>,
229
20
					header: &<Block as BlockT>::Header,
230
20
				) -> Result<
231
20
					(),
232
20
					sp_runtime::DispatchError,
233
20
				> {
234
20
					#[cfg(feature = "evm-tracing")]
235
20
					{
236
20
						use moonbeam_evm_tracer::tracer::EvmTracer;
237
20
						use frame_system::pallet_prelude::BlockNumberFor;
238
20
						use xcm_primitives::EthereumXcmTracingStatus;
239
20

            
240
20
						// Tell the CallDispatcher we are tracing a full Block.
241
20
						frame_support::storage::unhashed::put::<EthereumXcmTracingStatus>(
242
20
							xcm_primitives::ETHEREUM_XCM_TRACING_STORAGE_KEY,
243
20
							&EthereumXcmTracingStatus::Block,
244
20
						);
245
20

            
246
20
						let mut config = <Runtime as pallet_evm::Config>::config().clone();
247
20
						config.estimate = true;
248
20

            
249
20
						// Initialize block: calls the "on_initialize" hook on every pallet
250
20
						// in AllPalletsWithSystem.
251
20
						// After pallet message queue was introduced, this must be done only after
252
20
						// enabling XCM tracing by setting ETHEREUM_XCM_TRACING_STORAGE_KEY
253
20
						// in the storage
254
20
						Executive::initialize_block(header);
255
20

            
256
20
						// Apply all extrinsics. Ethereum extrinsics are traced.
257
80
						for ext in extrinsics.into_iter() {
258
40
							match &ext.0.function {
259
40
								RuntimeCall::Ethereum(transact { transaction }) => {
260
40

            
261
40
									// Reset the previously consumed weight when tracing multiple transactions.
262
40
									// This is necessary because EVM tracing introduces additional
263
40
									// (ref_time) overhead, which differs from the production runtime behavior.
264
40
									// Without resetting the block weight, the extra tracing overhead could
265
40
									// leading to some transactions to incorrectly fail during tracing.
266
40
									frame_system::BlockWeight::<Runtime>::kill();
267
40

            
268
40
									let tx_hash = &transaction.hash();
269
40
									if known_transactions.contains(&tx_hash) {
270
40
										// Each known extrinsic is a new call stack.
271
40
										EvmTracer::emit_new();
272
40
										EvmTracer::new().trace(|| {
273
40
											if let Err(err) = Executive::apply_extrinsic(ext) {
274
40
												log::debug!(
275
20
													target: "tracing",
276
													"Could not trace eth transaction (hash: {}): {:?}",
277
													&tx_hash,
278
20
													err
279
20
												);
280
20
											}
281
40
										});
282
40
									} else {
283
20
										if let Err(err) = Executive::apply_extrinsic(ext) {
284
20
											log::debug!(
285
20
												target: "tracing",
286
												"Failed to apply eth extrinsic (hash: {}): {:?}",
287
												&tx_hash,
288
20
												err
289
20
											);
290
20
										}
291
20
									}
292
20
								}
293
20
								_ => {
294
40
									if let Err(err) = Executive::apply_extrinsic(ext) {
295
20
										log::debug!(
296
20
											target: "tracing",
297
											"Failed to apply non-eth extrinsic: {:?}",
298
20
											err
299
20
										);
300
20
									}
301
20
								}
302
20
							};
303
20
						}
304
20

            
305
20
						// Replay on_idle
306
20
						// Some XCM messages with eth-xcm transaction might be executed at on_idle
307
20
						replay_on_idle();
308
20

            
309
20
						Ok(())
310
20
					}
311
20
					#[cfg(not(feature = "evm-tracing"))]
312
20
					Err(sp_runtime::DispatchError::Other(
313
20
						"Missing `evm-tracing` compile time feature flag.",
314
20
					))
315
20
				}
316
389140

            
317
389140
				fn trace_call(
318
20
					header: &<Block as BlockT>::Header,
319
20
					from: H160,
320
20
					to: H160,
321
20
					data: Vec<u8>,
322
20
					value: U256,
323
20
					gas_limit: U256,
324
20
					max_fee_per_gas: Option<U256>,
325
20
					max_priority_fee_per_gas: Option<U256>,
326
20
					nonce: Option<U256>,
327
20
					access_list: Option<Vec<(H160, Vec<H256>)>>,
328
20
				) -> Result<(), sp_runtime::DispatchError> {
329
20
					#[cfg(feature = "evm-tracing")]
330
20
					{
331
20
						use moonbeam_evm_tracer::tracer::EvmTracer;
332
20

            
333
20
						// Initialize block: calls the "on_initialize" hook on every pallet
334
20
						// in AllPalletsWithSystem.
335
20
						Executive::initialize_block(header);
336
20

            
337
20
						EvmTracer::new().trace(|| {
338
20
							let is_transactional = false;
339
20
							let validate = true;
340
20

            
341
20
							let transaction_data = pallet_ethereum::TransactionData::new(
342
20
								pallet_ethereum::TransactionAction::Call(to),
343
20
								data.clone(),
344
20
								nonce.unwrap_or_default(),
345
20
								gas_limit,
346
20
								None,
347
20
								max_fee_per_gas.or(Some(U256::default())),
348
20
								max_priority_fee_per_gas.or(Some(U256::default())),
349
20
								value,
350
20
								Some(<Runtime as pallet_evm::Config>::ChainId::get()),
351
20
								access_list.clone().unwrap_or_default(),
352
20
							);
353
20

            
354
20
							let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
355
20

            
356
20
							let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::<Runtime>::transaction_weight(&transaction_data);
357
20

            
358
20
							let _ = <Runtime as pallet_evm::Config>::Runner::call(
359
20
								from,
360
20
								to,
361
20
								data,
362
20
								value,
363
20
								gas_limit,
364
20
								max_fee_per_gas,
365
20
								max_priority_fee_per_gas,
366
20
								nonce,
367
20
								access_list.unwrap_or_default(),
368
20
								is_transactional,
369
20
								validate,
370
20
								weight_limit,
371
20
								proof_size_base_cost,
372
20
								<Runtime as pallet_evm::Config>::config(),
373
20
							);
374
20
						});
375
20
						Ok(())
376
20
					}
377
20
					#[cfg(not(feature = "evm-tracing"))]
378
20
					Err(sp_runtime::DispatchError::Other(
379
20
						"Missing `evm-tracing` compile time feature flag.",
380
20
					))
381
20
				}
382
389140
			}
383
389140

            
384
389140
			impl moonbeam_rpc_primitives_txpool::TxPoolRuntimeApi<Block> for Runtime {
385
389140
				fn extrinsic_filter(
386
20
					xts_ready: Vec<<Block as BlockT>::Extrinsic>,
387
20
					xts_future: Vec<<Block as BlockT>::Extrinsic>,
388
20
				) -> TxPoolResponse {
389
20
					TxPoolResponse {
390
20
						ready: xts_ready
391
20
							.into_iter()
392
389140
							.filter_map(|xt| match xt.0.function {
393
389140
								RuntimeCall::Ethereum(transact { transaction }) => Some(transaction),
394
389140
								_ => None,
395
389140
							})
396
20
							.collect(),
397
20
						future: xts_future
398
20
							.into_iter()
399
389140
							.filter_map(|xt| match xt.0.function {
400
389140
								RuntimeCall::Ethereum(transact { transaction }) => Some(transaction),
401
389140
								_ => None,
402
389140
							})
403
20
							.collect(),
404
20
					}
405
20
				}
406
389140
			}
407
389140

            
408
389140
			impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {
409
389140
				fn chain_id() -> u64 {
410
20
					<Runtime as pallet_evm::Config>::ChainId::get()
411
20
				}
412
389140

            
413
389140
				fn account_basic(address: H160) -> EVMAccount {
414
20
					let (account, _) = EVM::account_basic(&address);
415
20
					account
416
20
				}
417
389140

            
418
389140
				fn gas_price() -> U256 {
419
20
					let (gas_price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();
420
20
					gas_price
421
20
				}
422
389140

            
423
389140
				fn account_code_at(address: H160) -> Vec<u8> {
424
20
					pallet_evm::AccountCodes::<Runtime>::get(address)
425
20
				}
426
389140

            
427
389140
				fn author() -> H160 {
428
20
					<pallet_evm::Pallet<Runtime>>::find_author()
429
20
				}
430
389140

            
431
389140
				fn storage_at(address: H160, index: U256) -> H256 {
432
20
					let tmp: [u8; 32] = index.to_big_endian();
433
20
					pallet_evm::AccountStorages::<Runtime>::get(address, H256::from_slice(&tmp[..]))
434
20
				}
435
389140

            
436
389140
				fn call(
437
20
					from: H160,
438
20
					to: H160,
439
20
					data: Vec<u8>,
440
20
					value: U256,
441
20
					gas_limit: U256,
442
20
					max_fee_per_gas: Option<U256>,
443
20
					max_priority_fee_per_gas: Option<U256>,
444
20
					nonce: Option<U256>,
445
20
					estimate: bool,
446
20
					access_list: Option<Vec<(H160, Vec<H256>)>>,
447
20
				) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {
448
389140
					let config = if estimate {
449
389140
						let mut config = <Runtime as pallet_evm::Config>::config().clone();
450
						config.estimate = true;
451
						Some(config)
452
389140
					} else {
453
389140
						None
454
389140
					};
455
389140
					let is_transactional = false;
456
20
					let validate = true;
457
20

            
458
20
					let transaction_data = pallet_ethereum::TransactionData::new(
459
20
						pallet_ethereum::TransactionAction::Call(to),
460
20
						data.clone(),
461
20
						nonce.unwrap_or_default(),
462
20
						gas_limit,
463
20
						None,
464
20
						max_fee_per_gas.or(Some(U256::default())),
465
20
						max_priority_fee_per_gas.or(Some(U256::default())),
466
20
						value,
467
20
						Some(<Runtime as pallet_evm::Config>::ChainId::get()),
468
20
						access_list.clone().unwrap_or_default(),
469
20
					);
470
20

            
471
20
					let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
472
20

            
473
20
					let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::<Runtime>::transaction_weight(&transaction_data);
474
20

            
475
20
					<Runtime as pallet_evm::Config>::Runner::call(
476
20
						from,
477
20
						to,
478
20
						data,
479
20
						value,
480
20
						gas_limit,
481
20
						max_fee_per_gas,
482
20
						max_priority_fee_per_gas,
483
20
						nonce,
484
20
						access_list.unwrap_or_default(),
485
20
						is_transactional,
486
20
						validate,
487
20
						weight_limit,
488
20
						proof_size_base_cost,
489
20
						config.as_ref().unwrap_or(<Runtime as pallet_evm::Config>::config()),
490
20
					).map_err(|err| err.error.into())
491
20
				}
492
389140

            
493
389140
				fn create(
494
20
					from: H160,
495
20
					data: Vec<u8>,
496
20
					value: U256,
497
20
					gas_limit: U256,
498
20
					max_fee_per_gas: Option<U256>,
499
20
					max_priority_fee_per_gas: Option<U256>,
500
20
					nonce: Option<U256>,
501
20
					estimate: bool,
502
20
					access_list: Option<Vec<(H160, Vec<H256>)>>,
503
20
				) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {
504
389140
					let config = if estimate {
505
389140
						let mut config = <Runtime as pallet_evm::Config>::config().clone();
506
						config.estimate = true;
507
						Some(config)
508
389140
					} else {
509
389140
						None
510
389140
					};
511
389140
					let is_transactional = false;
512
20
					let validate = true;
513
20

            
514
20
					let transaction_data = pallet_ethereum::TransactionData::new(
515
20
						pallet_ethereum::TransactionAction::Create,
516
20
						data.clone(),
517
20
						nonce.unwrap_or_default(),
518
20
						gas_limit,
519
20
						None,
520
20
						max_fee_per_gas.or(Some(U256::default())),
521
20
						max_priority_fee_per_gas.or(Some(U256::default())),
522
20
						value,
523
20
						Some(<Runtime as pallet_evm::Config>::ChainId::get()),
524
20
						access_list.clone().unwrap_or_default(),
525
20
					);
526
20

            
527
20
					let gas_limit = gas_limit.min(u64::MAX.into()).low_u64();
528
20

            
529
20
					let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::<Runtime>::transaction_weight(&transaction_data);
530
20

            
531
20
					#[allow(clippy::or_fun_call)] // suggestion not helpful here
532
20
					<Runtime as pallet_evm::Config>::Runner::create(
533
20
						from,
534
20
						data,
535
20
						value,
536
20
						gas_limit,
537
20
						max_fee_per_gas,
538
20
						max_priority_fee_per_gas,
539
20
						nonce,
540
20
						access_list.unwrap_or_default(),
541
20
						is_transactional,
542
20
						validate,
543
20
						weight_limit,
544
20
						proof_size_base_cost,
545
20
						config.as_ref().unwrap_or(<Runtime as pallet_evm::Config>::config()),
546
20
					).map_err(|err| err.error.into())
547
20
				}
548
389140

            
549
389140
				fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {
550
20
					pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
551
20
				}
552
389140

            
553
389140
				fn current_block() -> Option<pallet_ethereum::Block> {
554
20
					pallet_ethereum::CurrentBlock::<Runtime>::get()
555
20
				}
556
389140

            
557
389140
				fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {
558
20
					pallet_ethereum::CurrentReceipts::<Runtime>::get()
559
20
				}
560
389140

            
561
389140
				fn current_all() -> (
562
					Option<pallet_ethereum::Block>,
563
					Option<Vec<pallet_ethereum::Receipt>>,
564
					Option<Vec<TransactionStatus>>,
565
				) {
566
					(
567
						pallet_ethereum::CurrentBlock::<Runtime>::get(),
568
						pallet_ethereum::CurrentReceipts::<Runtime>::get(),
569
						pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get(),
570
					)
571
				}
572
389140

            
573
389140
				fn extrinsic_filter(
574
					xts: Vec<<Block as BlockT>::Extrinsic>,
575
				) -> Vec<EthereumTransaction> {
576
389140
					xts.into_iter().filter_map(|xt| match xt.0.function {
577
389140
						RuntimeCall::Ethereum(transact { transaction }) => Some(transaction),
578
389140
						_ => None
579
389140
					}).collect::<Vec<EthereumTransaction>>()
580
				}
581
389140

            
582
389140
				fn elasticity() -> Option<Permill> {
583
					None
584
				}
585
389140

            
586
389140
				fn gas_limit_multiplier_support() {}
587
389140

            
588
389140
				fn pending_block(
589
					xts: Vec<<Block as sp_runtime::traits::Block>::Extrinsic>
590
				) -> (
591
					Option<pallet_ethereum::Block>, Option<sp_std::prelude::Vec<TransactionStatus>>
592
				) {
593
389140
					for ext in xts.into_iter() {
594
						let _ = Executive::apply_extrinsic(ext);
595
					}
596
389140

            
597
389140
					Ethereum::on_finalize(System::block_number() + 1);
598

            
599
					(
600
						pallet_ethereum::CurrentBlock::<Runtime>::get(),
601
						pallet_ethereum::CurrentTransactionStatuses::<Runtime>::get()
602
					)
603
				 }
604
389140

            
605
389140
				fn initialize_pending_block(header: &<Block as BlockT>::Header) {
606
					pallet_randomness::vrf::using_fake_vrf(|| {
607
						let _ = Executive::initialize_block(header);
608
					})
609
				}
610
389140
			}
611
389140

            
612
389140
			impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {
613
389140
				fn convert_transaction(
614
					transaction: pallet_ethereum::Transaction
615
				) -> <Block as BlockT>::Extrinsic {
616
					UncheckedExtrinsic::new_bare(
617
						pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
618
					)
619
				}
620
389140
			}
621
389140

            
622
389140
			impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
623
389140
			for Runtime {
624
389140
				fn query_info(
625
					uxt: <Block as BlockT>::Extrinsic,
626
					len: u32,
627
				) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
628
					TransactionPayment::query_info(uxt, len)
629
				}
630
389140

            
631
389140
				fn query_fee_details(
632
					uxt: <Block as BlockT>::Extrinsic,
633
					len: u32,
634
				) -> pallet_transaction_payment::FeeDetails<Balance> {
635
					TransactionPayment::query_fee_details(uxt, len)
636
				}
637
389140

            
638
389140
				fn query_weight_to_fee(weight: Weight) -> Balance {
639
					TransactionPayment::weight_to_fee(weight)
640
				}
641
389140

            
642
389140
				fn query_length_to_fee(length: u32) -> Balance {
643
					TransactionPayment::length_to_fee(length)
644
				}
645
389140
			}
646
389140

            
647
389140
			impl nimbus_primitives::NimbusApi<Block> for Runtime {
648
389180
				fn can_author(
649
60
					author: nimbus_primitives::NimbusId,
650
60
					slot: u32,
651
60
					parent_header: &<Block as BlockT>::Header
652
60
				) -> bool {
653
389140
					use pallet_parachain_staking::Config as PalletParachainStakingConfig;
654
389140

            
655
389180
					let block_number = parent_header.number + 1;
656
389140

            
657
389140
					// The Moonbeam runtimes use an entropy source that needs to do some accounting
658
389140
					// work during block initialization. Therefore we initialize it here to match
659
389140
					// the state it will be in when the next block is being executed.
660
389140
					use frame_support::traits::OnInitialize;
661
389180
					System::initialize(
662
60
						&block_number,
663
60
						&parent_header.hash(),
664
60
						&parent_header.digest,
665
60
					);
666
60

            
667
60
					// Because the staking solution calculates the next staking set at the beginning
668
60
					// of the first block in the new round, the only way to accurately predict the
669
60
					// authors is to compute the selection during prediction.
670
60
					if pallet_parachain_staking::Pallet::<Self>::round()
671
60
						.should_update(block_number) {
672
389140
						// get author account id
673
389140
						use nimbus_primitives::AccountLookup;
674
389140
						let author_account_id = if let Some(account) =
675
389140
							pallet_author_mapping::Pallet::<Self>::lookup_account(&author) {
676
389140
							account
677
389140
						} else {
678
389140
							// return false if author mapping not registered like in can_author impl
679
389140
							return false
680
389140
						};
681
389140
						let candidates = pallet_parachain_staking::Pallet::<Self>::compute_top_candidates();
682
						if candidates.is_empty() {
683
389140
							// If there are zero selected candidates, we use the same eligibility
684
389140
							// as the previous round
685
389140
							return AuthorInherent::can_author(&author, &slot);
686
389140
						}
687

            
688
						// predict eligibility post-selection by computing selection results now
689
						let (eligible, _) =
690
							pallet_author_slot_filter::compute_pseudo_random_subset::<Self>(
691
								candidates,
692
								&slot
693
							);
694
						eligible.contains(&author_account_id)
695
389140
					} else {
696
389180
						AuthorInherent::can_author(&author, &slot)
697
389140
					}
698
389140
				}
699
389140
			}
700
389140

            
701
389140
			impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
702
389140
				fn collect_collation_info(
703
					header: &<Block as BlockT>::Header
704
				) -> cumulus_primitives_core::CollationInfo {
705
					ParachainSystem::collect_collation_info(header)
706
				}
707
389140
			}
708
389140

            
709
389140
			impl session_keys_primitives::VrfApi<Block> for Runtime {
710
389140
				fn get_last_vrf_output() -> Option<<Block as BlockT>::Hash> {
711
					// TODO: remove in future runtime upgrade along with storage item
712
					if pallet_randomness::Pallet::<Self>::not_first_block().is_none() {
713
389140
						return None;
714
389140
					}
715
					pallet_randomness::Pallet::<Self>::local_vrf_output()
716
389140
				}
717
389140
				fn vrf_key_lookup(
718
					nimbus_id: nimbus_primitives::NimbusId
719
				) -> Option<session_keys_primitives::VrfId> {
720
389140
					use session_keys_primitives::KeysLookup;
721
389140
					AuthorMapping::lookup_keys(&nimbus_id)
722
				}
723
389140
			}
724
389140

            
725
389140
			impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
726
389140
				fn query_acceptable_payment_assets(
727
					xcm_version: xcm::Version
728
				) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
729
					XcmWeightTrader::query_acceptable_payment_assets(xcm_version)
730
				}
731
389140

            
732
389140
				fn query_weight_to_asset_fee(
733
					weight: Weight, asset: VersionedAssetId
734
				) -> Result<u128, XcmPaymentApiError> {
735
					XcmWeightTrader::query_weight_to_asset_fee(weight, asset)
736
				}
737
389140

            
738
389140
				fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
739
					PolkadotXcm::query_xcm_weight(message)
740
				}
741
389140

            
742
389140
				fn query_delivery_fees(
743
					destination: VersionedLocation, message: VersionedXcm<()>
744
				) -> Result<VersionedAssets, XcmPaymentApiError> {
745
					PolkadotXcm::query_delivery_fees(destination, message)
746
				}
747
389140
			}
748
389140

            
749
389140
			impl xcm_runtime_apis::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller>
750
389140
				for Runtime {
751
389140
					fn dry_run_call(
752
						origin: OriginCaller,
753
						call: RuntimeCall,
754
						result_xcms_version: XcmVersion
755
					) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
756
						PolkadotXcm::dry_run_call::<
757
							Runtime,
758
							xcm_config::XcmRouter,
759
							OriginCaller,
760
							RuntimeCall>(origin, call, result_xcms_version)
761
					}
762
389140

            
763
389140
					fn dry_run_xcm(
764
						origin_location: VersionedLocation,
765
						xcm: VersionedXcm<RuntimeCall>
766
					) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
767
						PolkadotXcm::dry_run_xcm::<
768
							Runtime,
769
							xcm_config::XcmRouter,
770
							RuntimeCall,
771
							xcm_config::XcmExecutorConfig>(origin_location, xcm)
772
					}
773
389140
				}
774
389140

            
775
389140
			impl xcm_runtime_apis::conversions::LocationToAccountApi<Block, AccountId> for Runtime {
776
389140
				fn convert_location(location: VersionedLocation) -> Result<
777
					AccountId,
778
					xcm_runtime_apis::conversions::Error
779
				> {
780
					xcm_runtime_apis::conversions::LocationToAccountHelper::<
781
						AccountId,
782
						xcm_config::LocationToAccountId,
783
					>::convert_location(location)
784
				}
785
389140
			}
786
389140

            
787
389140
			#[cfg(feature = "runtime-benchmarks")]
788
389140
			impl frame_benchmarking::Benchmark<Block> for Runtime {
789
389140

            
790
389140
				fn benchmark_metadata(extra: bool) -> (
791
389140
					Vec<frame_benchmarking::BenchmarkList>,
792
389140
					Vec<frame_support::traits::StorageInfo>,
793
389140
				) {
794
389140
					use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};
795
389140
					use frame_system_benchmarking::Pallet as SystemBench;
796
389140
					use moonbeam_xcm_benchmarks::generic::benchmarking as MoonbeamXcmBenchmarks;
797
389140
					use frame_support::traits::StorageInfoTrait;
798
389140
					use MoonbeamXcmBenchmarks::XcmGenericBenchmarks as MoonbeamXcmGenericBench;
799
389140

            
800
389140
					use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
801
389140
					use pallet_transaction_payment::benchmarking::Pallet as PalletTransactionPaymentBenchmark;
802
389140

            
803
389140
					let mut list = Vec::<BenchmarkList>::new();
804
389140
					list_benchmarks!(list, extra);
805
389140

            
806
389140
					let storage_info = AllPalletsWithSystem::storage_info();
807
389140

            
808
389140
					return (list, storage_info)
809
389140
				}
810
389140

            
811
389140
				fn dispatch_benchmark(
812
389140
					config: frame_benchmarking::BenchmarkConfig,
813
389140
				) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
814
389140
					use frame_benchmarking::{add_benchmark, BenchmarkBatch, Benchmarking};
815
389140
					use frame_support::traits::TrackedStorageKey;
816
389140
					use cumulus_primitives_core::ParaId;
817
389140

            
818
389140
					use xcm::latest::prelude::{
819
389140
						GeneralIndex, Junction, Junctions, Location, Response, NetworkId, AssetId,
820
389140
						Assets as XcmAssets, Fungible, Asset, ParentThen, Parachain, Parent
821
389140
					};
822
389140
					use xcm_config::SelfReserve;
823
389140
					use frame_benchmarking::BenchmarkError;
824
389140

            
825
389140
					use frame_system_benchmarking::Pallet as SystemBench;
826
389140
					// Needed to run `set_code` and `apply_authorized_upgrade` frame_system benchmarks
827
389140
					// https://github.com/paritytech/cumulus/pull/2766
828
389140
					impl frame_system_benchmarking::Config for Runtime {
829
389140
						fn setup_set_code_requirements(code: &Vec<u8>) -> Result<(), BenchmarkError> {
830
389140
							ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
831
389140
							Ok(())
832
389140
						}
833
389140

            
834
389140
						fn verify_set_code() {
835
389140
							System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
836
389140
						}
837
389140
					}
838
389140

            
839
389140
					impl moonbeam_xcm_benchmarks::Config for Runtime {}
840
389140
					impl moonbeam_xcm_benchmarks::generic::Config for Runtime {}
841
389140

            
842
389140
					use pallet_asset_manager::Config as PalletAssetManagerConfig;
843
389140

            
844
389140
					use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
845
389140
					parameter_types! {
846
389140
						pub const RandomParaId: ParaId = ParaId::new(43211234);
847
389140
					}
848
389140

            
849
389140
					pub struct TestDeliveryHelper;
850
389140
					impl xcm_builder::EnsureDelivery for TestDeliveryHelper {
851
389140
						fn ensure_successful_delivery(
852
389140
							origin_ref: &Location,
853
389140
							_dest: &Location,
854
389140
							_fee_reason: xcm_executor::traits::FeeReason,
855
389140
						) -> (Option<xcm_executor::FeesMode>, Option<XcmAssets>) {
856
389140
							use xcm_executor::traits::ConvertLocation;
857
389140
							let account = xcm_config::LocationToH160::convert_location(origin_ref)
858
389140
								.expect("Invalid location");
859
389140
							// Give the existential deposit at least
860
389140
							let balance = ExistentialDeposit::get();
861
389140
							let _ = <Balances as frame_support::traits::Currency<_>>::
862
389140
								make_free_balance_be(&account.into(), balance);
863
389140

            
864
389140
							(None, None)
865
389140
						}
866
389140
					}
867
389140

            
868
389140
					use pallet_transaction_payment::benchmarking::Pallet as PalletTransactionPaymentBenchmark;
869
389140
					impl pallet_transaction_payment::benchmarking::Config for Runtime {
870
389140
						fn setup_benchmark_environment() {
871
389140
							let alice = AccountId::from(sp_core::hex2array!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"));
872
389140
							pallet_author_inherent::Author::<Runtime>::put(&alice);
873
389140
						}
874
389140
					}
875
389140

            
876
389140
					impl pallet_xcm::benchmarking::Config for Runtime {
877
389140
				        type DeliveryHelper = TestDeliveryHelper;
878
389140

            
879
389140
						fn get_asset() -> Asset {
880
389140
							Asset {
881
389140
								id: AssetId(SelfReserve::get()),
882
389140
								fun: Fungible(ExistentialDeposit::get()),
883
389140
							}
884
389140
						}
885
389140

            
886
389140
						fn reachable_dest() -> Option<Location> {
887
389140
							Some(Parent.into())
888
389140
						}
889
389140

            
890
389140
						fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
891
389140
							None
892
389140
						}
893
389140

            
894
389140
						fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
895
389140
							use xcm_config::SelfReserve;
896
389140

            
897
389140
							ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
898
389140
								RandomParaId::get().into()
899
389140
							);
900
389140

            
901
389140
							Some((
902
389140
								Asset {
903
389140
									fun: Fungible(ExistentialDeposit::get()),
904
389140
									id: AssetId(SelfReserve::get().into())
905
389140
								},
906
389140
								// Moonbeam can reserve transfer native token to
907
389140
								// some random parachain.
908
389140
								ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
909
389140
							))
910
389140
						}
911
389140

            
912
389140
						fn set_up_complex_asset_transfer(
913
389140
						) -> Option<(XcmAssets, u32, Location, Box<dyn FnOnce()>)> {
914
389140
							use xcm_config::SelfReserve;
915
389140

            
916
389140
							let destination: xcm::v5::Location = Parent.into();
917
389140

            
918
389140
							let fee_amount: u128 = <Runtime as pallet_balances::Config>::ExistentialDeposit::get();
919
389140
							let fee_asset: Asset = (SelfReserve::get(), fee_amount).into();
920
389140

            
921
389140
							// Give some multiple of transferred amount
922
389140
							let balance = fee_amount * 1000;
923
389140
							let who = frame_benchmarking::whitelisted_caller();
924
389140
							let _ =
925
389140
								<Balances as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);
926
389140

            
927
389140
							// verify initial balance
928
389140
							assert_eq!(Balances::free_balance(&who), balance);
929
389140

            
930
389140
							// set up local asset
931
389140
							let asset_amount: u128 = 10u128;
932
389140
							let initial_asset_amount: u128 = asset_amount * 10;
933
389140

            
934
389140
							let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
935
389140
								Runtime,
936
389140
								()
937
389140
							>(true, initial_asset_amount);
938
389140
							let transfer_asset: Asset = (SelfReserve::get(), asset_amount).into();
939
389140

            
940
389140
							let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into();
941
389140
							let fee_index: u32 = 0;
942
389140

            
943
389140
							let verify: Box<dyn FnOnce()> = Box::new(move || {
944
389140
								// verify balance after transfer, decreased by
945
389140
								// transferred amount (and delivery fees)
946
389140
								assert!(Balances::free_balance(&who) <= balance - fee_amount);
947
389140
							});
948
389140

            
949
389140
							Some((assets, fee_index, destination, verify))
950
389140
						}
951
389140
					}
952
389140

            
953
389140
					impl pallet_xcm_benchmarks::Config for Runtime {
954
389140
						type XcmConfig = xcm_config::XcmExecutorConfig;
955
389140
						type AccountIdConverter = xcm_config::LocationToAccountId;
956
389140
						type DeliveryHelper = ();
957
389140
						fn valid_destination() -> Result<Location, BenchmarkError> {
958
389140
							Ok(Location::parent())
959
389140
						}
960
389140
						fn worst_case_holding(_depositable_count: u32) -> XcmAssets {
961
389140
						// 100 fungibles
962
389140
							const HOLDING_FUNGIBLES: u32 = 100;
963
389140
							let fungibles_amount: u128 = 100;
964
389140
							let assets = (0..HOLDING_FUNGIBLES).map(|i| {
965
389140
								let location: Location = GeneralIndex(i as u128).into();
966
389140
								Asset {
967
389140
									id: AssetId(location),
968
389140
									fun: Fungible(fungibles_amount * i as u128),
969
389140
								}
970
389140
								.into()
971
389140
							})
972
389140
							.chain(
973
389140
								core::iter::once(
974
389140
									Asset {
975
389140
										id: AssetId(Location::parent()),
976
389140
										fun: Fungible(u128::MAX)
977
389140
									}
978
389140
								)
979
389140
							)
980
389140
							.collect::<Vec<_>>();
981
389140

            
982
389140

            
983
389140
							for (i, asset) in assets.iter().enumerate() {
984
389140
								if let Asset {
985
389140
									id: AssetId(location),
986
389140
									fun: Fungible(_)
987
389140
								} = asset {
988
389140
									EvmForeignAssets::set_asset(
989
389140
										location.clone(),
990
389140
										i as u128
991
389140
									);
992
389140
									XcmWeightTrader::set_asset_price(
993
389140
										location.clone(),
994
389140
										1u128.pow(18)
995
389140
									);
996
389140
								}
997
389140
							}
998
389140
							assets.into()
999
389140
						}
389140
					}
389140

            
389140
					impl pallet_xcm_benchmarks::generic::Config for Runtime {
389140
						type RuntimeCall = RuntimeCall;
389140
						type TransactAsset = Balances;
389140

            
389140
						fn worst_case_response() -> (u64, Response) {
389140
							(0u64, Response::Version(Default::default()))
389140
						}
389140

            
389140
						fn worst_case_asset_exchange()
389140
							-> Result<(XcmAssets, XcmAssets), BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140

            
389140
						fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140

            
389140
						fn export_message_origin_and_destination()
389140
							-> Result<(Location, NetworkId, Junctions), BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140

            
389140
						fn transact_origin_and_runtime_call()
389140
							-> Result<(Location, RuntimeCall), BenchmarkError> {
389140
							Ok((Location::parent(), frame_system::Call::remark_with_event {
389140
								remark: vec![]
389140
							}.into()))
389140
						}
389140

            
389140
						fn subscribe_origin() -> Result<Location, BenchmarkError> {
389140
							Ok(Location::parent())
389140
						}
389140

            
389140
						fn claimable_asset()
389140
							-> Result<(Location, Location, XcmAssets), BenchmarkError> {
389140
							let origin = Location::parent();
389140
							let assets: XcmAssets = (AssetId(Location::parent()), 1_000u128)
389140
								.into();
389140
							let ticket = Location { parents: 0, interior: [].into() /* Here */ };
389140
							Ok((origin, ticket, assets))
389140
						}
389140

            
389140
						fn fee_asset() -> Result<Asset, BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140

            
389140
						fn unlockable_asset()
389140
							-> Result<(Location, Location, Asset), BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140

            
389140
						fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
389140
							Err(BenchmarkError::Skip)
389140
						}
389140
					}
389140

            
389140
					let whitelist: Vec<TrackedStorageKey> = vec![
389140
						// Block Number
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"02a5c1b19ab7a04f536c519aca4983ac")
389140
							.to_vec().into(),
389140
						// Total Issuance
389140
						hex_literal::hex!(  "c2261276cc9d1f8598ea4b6a74b15c2f"
389140
											"57c875e4cff74148e4628f264b974c80")
389140
							.to_vec().into(),
389140
						// Execution Phase
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"ff553b5a9862a516939d82b3d3d8661a")
389140
							.to_vec().into(),
389140
						// Event Count
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"0a98fdbe9ce6c55837576c60c7af3850")
389140
							.to_vec().into(),
389140
						// System Events
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"80d41e5e16056765bc8461851072c9d7")
389140
							.to_vec().into(),
389140
						// System BlockWeight
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"34abf5cb34d6244378cddbf18e849d96")
389140
							.to_vec().into(),
389140
						// ParachainStaking Round
389140
						hex_literal::hex!(  "a686a3043d0adcf2fa655e57bc595a78"
389140
											"13792e785168f725b60e2969c7fc2552")
389140
							.to_vec().into(),
389140
						// Treasury Account (py/trsry)
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"b99d880ec681799c0cf30e8886371da9"
389140
											"7be2919ac397ba499ea5e57132180ec6"
389140
											"6d6f646c70792f747273727900000000"
389140
											"00000000"
389140
						).to_vec().into(),
389140
						// Treasury Account (pc/trsry)
389140
						hex_literal::hex!(  "26aa394eea5630e07c48ae0c9558cef7"
389140
											"b99d880ec681799c0cf30e8886371da9"
389140
											"7be2919ac397ba499ea5e57132180ec6"
389140
											"6d6f646c70632f747273727900000000"
389140
											"00000000"
389140
						).to_vec().into(),
389140
						// ParachainInfo ParachainId
389140
						hex_literal::hex!(  "0d715f2646c8f85767b5d2764bb27826"
389140
											"04a74d81251e398fd8a0a4d55023bb3f")
389140
							.to_vec().into(),
389140
						// Parameters Parameters
389140
						hex_literal::hex!(  "c63bdd4a39095ccf55623a6f2872bf8a" // Pallet: "Parameters"
389140
											"c63bdd4a39095ccf55623a6f2872bf8a" // Storage Prefix: "Parameters"
389140
											// MoonbaseRuntimeRuntimeParamsRuntimeParametersKey(FeesTreasuryProportion)
389140
											"71d0aacb690b61280d0c97c6b6a666640000"
389140
										)
389140
							.to_vec().into(),
389140

            
389140
					];
389140

            
389140
					let mut batches = Vec::<BenchmarkBatch>::new();
389140
					let params = (&config, &whitelist);
389140

            
389140
					add_benchmarks!(params, batches);
389140

            
389140
					if batches.is_empty() {
389140
						return Err("Benchmark not found for this pallet.".into());
389140
					}
389140
					Ok(batches)
389140
				}
389140
			}
389140

            
389140
			#[cfg(feature = "try-runtime")]
389140
			impl frame_try_runtime::TryRuntime<Block> for Runtime {
389140
				fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) {
389140
					log::info!("try-runtime::on_runtime_upgrade()");
389140
					// NOTE: intentional expect: we don't want to propagate the error backwards,
389140
					// and want to have a backtrace here. If any of the pre/post migration checks
389140
					// fail, we shall stop right here and right now.
389140
					let weight = Executive::try_runtime_upgrade(checks)
389140
						.expect("runtime upgrade logic *must* be infallible");
389140
					(weight, RuntimeBlockWeights::get().max_block)
389140
				}
389140

            
389140
				fn execute_block(
389140
					block: Block,
389140
					state_root_check: bool,
389140
					signature_check: bool,
389140
					select: frame_try_runtime::TryStateSelect
389140
				) -> Weight {
389140
					log::info!(
389140
						"try-runtime: executing block {:?} / root checks: {:?} / try-state-select: {:?}",
389140
						block.header.hash(),
389140
						state_root_check,
389140
						select,
389140
					);
389140
					// NOTE: intentional unwrap: we don't want to propagate the error backwards,
389140
					// and want to have a backtrace here.
389140
					Executive::try_execute_block(
389140
						block,
389140
						state_root_check,
389140
						signature_check,
389140
						select,
389140
					).expect("execute-block failed")
389140
				}
389140
			}
389140
		}
	};
}