moonbeam_runtime/
lib.rs

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//! The Moonbeam Runtime.
18//!
19//! Primary features of this runtime include:
20//! * Ethereum compatibility
21//! * Moonbeam tokenomics
22
23#![cfg_attr(not(feature = "std"), no_std)]
24// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 512.
25#![recursion_limit = "512"]
26
27// Make the WASM binary available.
28#[cfg(feature = "std")]
29include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
30
31extern crate alloc;
32extern crate core;
33
34use account::AccountId20;
35use alloc::borrow::Cow;
36use cumulus_pallet_parachain_system::{
37	RelayChainStateProof, RelayStateProof, RelaychainDataProvider, ValidationData,
38};
39use fp_rpc::TransactionStatus;
40
41use bp_moonbeam::bp_kusama;
42use cumulus_primitives_core::{relay_chain, AggregateMessageOrigin};
43#[cfg(feature = "std")]
44pub use fp_evm::GenesisAccount;
45pub use frame_support::traits::Get;
46use frame_support::{
47	construct_runtime,
48	dispatch::{DispatchClass, GetDispatchInfo, PostDispatchInfo},
49	ensure,
50	pallet_prelude::DispatchResult,
51	parameter_types,
52	traits::{
53		fungible::{Balanced, Credit, HoldConsideration, Inspect, NativeOrWithId},
54		ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EitherOf,
55		EitherOfDiverse, EqualPrivilegeOnly, InstanceFilter, LinearStoragePrice, OnFinalize,
56		OnUnbalanced, VariantCountOf,
57	},
58	weights::{
59		constants::WEIGHT_REF_TIME_PER_SECOND, Weight, WeightToFeeCoefficient,
60		WeightToFeeCoefficients, WeightToFeePolynomial,
61	},
62	PalletId,
63};
64use frame_system::{EnsureRoot, EnsureSigned};
65pub use moonbeam_core_primitives::{
66	AccountId, AccountIndex, Address, AssetId, Balance, BlockNumber, DigestItem, Hash, Header,
67	Index, Signature,
68};
69use moonbeam_rpc_primitives_txpool::TxPoolResponse;
70use moonbeam_runtime_common::{
71	deal_with_fees::{
72		DealWithEthereumBaseFees, DealWithEthereumPriorityFees, DealWithSubstrateFeesAndTip,
73		ProofSizeToFee, RefTimeToFee, WeightToFee,
74	},
75	impl_asset_conversion::AssetRateConverter,
76	impl_multiasset_paymaster::MultiAssetPaymaster,
77	TX_MAX_GAS_LIMIT,
78};
79pub use pallet_author_slot_filter::EligibilityValue;
80use pallet_ethereum::Call::transact;
81use pallet_ethereum::{PostLogContent, Transaction as EthereumTransaction};
82use pallet_evm::{
83	Account as EVMAccount, EVMFungibleAdapter, EnsureAddressNever, EnsureAddressRoot,
84	FeeCalculator, FrameSystemAccountProvider, GasWeightMapping, IdentityAddressMapping,
85	OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
86};
87pub use pallet_parachain_staking::{weights::WeightInfo, InflationInfo, Range};
88use pallet_transaction_payment::{FungibleAdapter, Multiplier, TargetedFeeAdjustment};
89use parity_scale_codec as codec;
90use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
91use scale_info::TypeInfo;
92use serde::{Deserialize, Serialize};
93use smallvec::smallvec;
94use sp_api::impl_runtime_apis;
95use sp_consensus_slots::Slot;
96use sp_core::{OpaqueMetadata, H160, H256, U256};
97use sp_runtime::generic::Preamble;
98use sp_runtime::{
99	generic, impl_opaque_keys,
100	traits::{
101		BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, IdentityLookup,
102		PostDispatchInfoOf, UniqueSaturatedInto, Zero,
103	},
104	transaction_validity::{
105		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
106	},
107	ApplyExtrinsicResult, DispatchErrorWithPostInfo, FixedPointNumber, Perbill, Permill,
108	Perquintill, SaturatedConversion,
109};
110use sp_std::{convert::TryFrom, prelude::*};
111use xcm::{
112	Version as XcmVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
113};
114use xcm_runtime_apis::{
115	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
116	fees::Error as XcmPaymentApiError,
117};
118
119use runtime_params::*;
120
121#[cfg(feature = "std")]
122use sp_version::NativeVersion;
123use sp_version::RuntimeVersion;
124
125use nimbus_primitives::CanAuthor;
126
127mod migrations;
128mod precompiles;
129pub use precompiles::{
130	MoonbeamPrecompiles, PrecompileName, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
131};
132
133#[cfg(any(feature = "std", test))]
134pub use sp_runtime::BuildStorage;
135
136pub type Precompiles = MoonbeamPrecompiles<Runtime>;
137
138pub mod asset_config;
139pub mod bridge_config;
140#[cfg(not(feature = "disable-genesis-builder"))]
141pub mod genesis_config_preset;
142pub mod governance;
143pub mod runtime_params;
144mod weights;
145pub mod xcm_config;
146
147use governance::councils::*;
148pub(crate) use weights as moonbeam_weights;
149pub use weights::xcm as moonbeam_xcm_weights;
150
151/// GLMR, the native token, uses 18 decimals of precision.
152pub mod currency {
153	use super::Balance;
154
155	// Provide a common factor between runtimes based on a supply of 10_000_000 tokens.
156	pub const SUPPLY_FACTOR: Balance = 100;
157
158	pub const WEI: Balance = 1;
159	pub const KILOWEI: Balance = 1_000;
160	pub const MEGAWEI: Balance = 1_000_000;
161	pub const GIGAWEI: Balance = 1_000_000_000;
162	pub const MICROGLMR: Balance = 1_000_000_000_000;
163	pub const MILLIGLMR: Balance = 1_000_000_000_000_000;
164	pub const GLMR: Balance = 1_000_000_000_000_000_000;
165	pub const KILOGLMR: Balance = 1_000_000_000_000_000_000_000;
166
167	pub const TRANSACTION_BYTE_FEE: Balance = 1 * GIGAWEI * SUPPLY_FACTOR;
168	pub const STORAGE_BYTE_FEE: Balance = 100 * MICROGLMR * SUPPLY_FACTOR;
169	pub const WEIGHT_FEE: Balance = 50 * KILOWEI * SUPPLY_FACTOR / 4;
170
171	pub const fn deposit(items: u32, bytes: u32) -> Balance {
172		items as Balance * 100 * MILLIGLMR * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
173	}
174}
175
176/// Maximum PoV size we support right now.
177// Reference: https://github.com/polkadot-fellows/runtimes/pull/553
178pub const MAX_POV_SIZE: u32 = 10 * 1024 * 1024;
179
180/// Maximum weight per block
181pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
182	WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2),
183	MAX_POV_SIZE as u64,
184);
185
186pub const MILLISECS_PER_BLOCK: u64 = 6_000;
187pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
188pub const HOURS: BlockNumber = MINUTES * 60;
189pub const DAYS: BlockNumber = HOURS * 24;
190pub const WEEKS: BlockNumber = DAYS * 7;
191pub const MONTHS: BlockNumber = DAYS * 30;
192/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
193/// the specifics of the runtime. They can then be made to be agnostic over specific formats
194/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
195/// to even the core datastructures.
196pub mod opaque {
197	use super::*;
198
199	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
200	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
201
202	impl_opaque_keys! {
203		pub struct SessionKeys {
204			pub nimbus: AuthorInherent,
205			pub vrf: session_keys_primitives::VrfSessionKey,
206		}
207	}
208}
209
210/// This runtime version.
211/// The spec_version is composed of 2x2 digits. The first 2 digits represent major changes
212/// that can't be skipped, such as data migration upgrades. The last 2 digits represent minor
213/// changes which can be skipped.
214#[sp_version::runtime_version]
215pub const VERSION: RuntimeVersion = RuntimeVersion {
216	spec_name: Cow::Borrowed("moonbeam"),
217	impl_name: Cow::Borrowed("moonbeam"),
218	authoring_version: 3,
219	spec_version: 4300,
220	impl_version: 0,
221	apis: RUNTIME_API_VERSIONS,
222	transaction_version: 3,
223	system_version: 1,
224};
225
226/// The version information used to identify this runtime when compiled natively.
227#[cfg(feature = "std")]
228pub fn native_version() -> NativeVersion {
229	NativeVersion {
230		runtime_version: VERSION,
231		can_author_with: Default::default(),
232	}
233}
234
235const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
236pub const NORMAL_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).saturating_div(4);
237// Here we assume Ethereum's base fee of 21000 gas and convert to weight, but we
238// subtract roughly the cost of a balance transfer from it (about 1/3 the cost)
239// and some cost to account for per-byte-fee.
240// TODO: we should use benchmarking's overhead feature to measure this
241pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
242
243pub struct RuntimeBlockWeights;
244impl Get<frame_system::limits::BlockWeights> for RuntimeBlockWeights {
245	fn get() -> frame_system::limits::BlockWeights {
246		frame_system::limits::BlockWeights::builder()
247			.for_class(DispatchClass::Normal, |weights| {
248				weights.base_extrinsic = EXTRINSIC_BASE_WEIGHT;
249				weights.max_total = NORMAL_WEIGHT.into();
250			})
251			.for_class(DispatchClass::Operational, |weights| {
252				weights.max_total = MAXIMUM_BLOCK_WEIGHT.into();
253				weights.reserved = (MAXIMUM_BLOCK_WEIGHT - NORMAL_WEIGHT).into();
254			})
255			.avg_block_initialization(Perbill::from_percent(10))
256			.build()
257			.expect("Provided BlockWeight definitions are valid, qed")
258	}
259}
260
261parameter_types! {
262	pub const Version: RuntimeVersion = VERSION;
263	/// We allow for 5 MB blocks.
264	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
265		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
266}
267
268impl frame_system::Config for Runtime {
269	/// The identifier used to distinguish between accounts.
270	type AccountId = AccountId;
271	/// The aggregated dispatch type that is available for extrinsics.
272	type RuntimeCall = RuntimeCall;
273	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
274	type Lookup = IdentityLookup<AccountId>;
275	/// The index type for storing how many extrinsics an account has signed.
276	type Nonce = Index;
277	/// The index type for blocks.
278	type Block = Block;
279	/// The type for hashing blocks and tries.
280	type Hash = Hash;
281	/// The hashing algorithm used.
282	type Hashing = BlakeTwo256;
283	/// The ubiquitous event type.
284	type RuntimeEvent = RuntimeEvent;
285	/// The ubiquitous origin type.
286	type RuntimeOrigin = RuntimeOrigin;
287	/// The aggregated RuntimeTask type.
288	type RuntimeTask = RuntimeTask;
289	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
290	type BlockHashCount = ConstU32<256>;
291	/// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
292	type BlockWeights = RuntimeBlockWeights;
293	/// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
294	type BlockLength = BlockLength;
295	/// Runtime version.
296	type Version = Version;
297	type PalletInfo = PalletInfo;
298	type AccountData = pallet_balances::AccountData<Balance>;
299	type OnNewAccount = ();
300	type OnKilledAccount = ();
301	type DbWeight = moonbeam_weights::db::rocksdb::constants::RocksDbWeight;
302	type BaseCallFilter = MaintenanceMode;
303	type SystemWeightInfo = moonbeam_weights::frame_system::WeightInfo<Runtime>;
304	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
305	type SS58Prefix = ConstU16<1284>;
306	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
307	type MaxConsumers = frame_support::traits::ConstU32<16>;
308	type SingleBlockMigrations = migrations::SingleBlockMigrations<Runtime>;
309	type MultiBlockMigrator = MultiBlockMigrations;
310	type PreInherents = ();
311	type PostInherents = (
312		// Validate timestamp provided by the consensus client
313		AsyncBacking,
314	);
315	type PostTransactions = ();
316	type ExtensionsWeightInfo = moonbeam_weights::frame_system_extensions::WeightInfo<Runtime>;
317}
318
319impl pallet_utility::Config for Runtime {
320	type RuntimeEvent = RuntimeEvent;
321	type RuntimeCall = RuntimeCall;
322	type PalletsOrigin = OriginCaller;
323	type WeightInfo = moonbeam_weights::pallet_utility::WeightInfo<Runtime>;
324}
325
326impl pallet_timestamp::Config for Runtime {
327	/// A timestamp: milliseconds since the unix epoch.
328	type Moment = u64;
329	type OnTimestampSet = ();
330	type MinimumPeriod = ConstU64<{ RELAY_CHAIN_SLOT_DURATION_MILLIS as u64 / 2 }>;
331	type WeightInfo = moonbeam_weights::pallet_timestamp::WeightInfo<Runtime>;
332}
333
334#[cfg(not(feature = "runtime-benchmarks"))]
335parameter_types! {
336	pub const ExistentialDeposit: Balance = 0;
337}
338
339#[cfg(feature = "runtime-benchmarks")]
340parameter_types! {
341	pub const ExistentialDeposit: Balance = 1;
342}
343
344impl pallet_balances::Config for Runtime {
345	type MaxReserves = ConstU32<50>;
346	type ReserveIdentifier = [u8; 4];
347	type MaxLocks = ConstU32<50>;
348	/// The type for recording an account's balance.
349	type Balance = Balance;
350	/// The ubiquitous event type.
351	type RuntimeEvent = RuntimeEvent;
352	type DustRemoval = ();
353	type ExistentialDeposit = ExistentialDeposit;
354	type AccountStore = System;
355	type FreezeIdentifier = RuntimeFreezeReason;
356	type MaxFreezes = VariantCountOf<Self::RuntimeFreezeReason>;
357	type RuntimeHoldReason = RuntimeHoldReason;
358	type RuntimeFreezeReason = RuntimeFreezeReason;
359	type WeightInfo = moonbeam_weights::pallet_balances::WeightInfo<Runtime>;
360	type DoneSlashHandler = ();
361}
362
363pub struct LengthToFee;
364impl WeightToFeePolynomial for LengthToFee {
365	type Balance = Balance;
366
367	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
368		smallvec![
369			WeightToFeeCoefficient {
370				degree: 1,
371				coeff_frac: Perbill::zero(),
372				coeff_integer: currency::TRANSACTION_BYTE_FEE,
373				negative: false,
374			},
375			WeightToFeeCoefficient {
376				degree: 3,
377				coeff_frac: Perbill::zero(),
378				coeff_integer: 1 * currency::SUPPLY_FACTOR,
379				negative: false,
380			},
381		]
382	}
383}
384
385impl pallet_transaction_payment::Config for Runtime {
386	type RuntimeEvent = RuntimeEvent;
387	type OnChargeTransaction = FungibleAdapter<
388		Balances,
389		DealWithSubstrateFeesAndTip<
390			Runtime,
391			dynamic_params::runtime_config::FeesTreasuryProportion,
392		>,
393	>;
394	type OperationalFeeMultiplier = ConstU8<5>;
395	type WeightToFee = WeightToFee<
396		RefTimeToFee<ConstU128<{ currency::WEIGHT_FEE }>>,
397		ProofSizeToFee<
398			ConstU128<
399				{ currency::WEIGHT_FEE.saturating_mul(GasLimitPovSizeRatio::get() as Balance) },
400			>,
401		>,
402	>;
403	type LengthToFee = LengthToFee;
404	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Runtime>;
405	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
406}
407
408impl pallet_evm_chain_id::Config for Runtime {}
409
410/// Current approximation of the gas/s consumption considering
411/// EVM execution over compiled WASM (on 4.4Ghz CPU).
412/// Given the 2000ms Weight, from which 75% only are used for transactions,
413/// the total EVM execution gas limit is: GAS_PER_SECOND * 2 * 0.75 ~= 60_000_000.
414pub const GAS_PER_SECOND: u64 = 40_000_000;
415
416/// Approximate ratio of the amount of Weight per Gas.
417/// u64 works for approximations because Weight is a very small unit compared to gas.
418pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;
419
420/// The highest amount of new storage that can be created in a block (160KB).
421/// Originally 40KB, then multiplied by 4 when the block deadline was increased from 500ms to 2000ms.
422/// Reference: https://github.com/moonbeam-foundation/moonbeam/blob/master/MBIPS/MBIP-5.md#specification
423pub const BLOCK_STORAGE_LIMIT: u64 = 160 * 1024;
424
425parameter_types! {
426	pub BlockGasLimit: U256
427		= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
428	pub TransactionGasLimit: Option<U256> = Some(U256::from(TX_MAX_GAS_LIMIT));
429	/// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less
430	/// than this will decrease the weight and more will increase.
431	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(35);
432	/// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to
433	/// change the fees more rapidly. This low value causes changes to occur slowly over time.
434	pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(4, 1_000);
435	/// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure
436	/// that combined with `AdjustmentVariable`, we can recover from the minimum.
437	/// See `multiplier_can_grow_from_zero` in integration_tests.rs.
438	/// This value is currently only used by pallet-transaction-payment as an assertion that the
439	/// next multiplier is always > min value.
440	pub MinimumMultiplier: Multiplier = Multiplier::from(1u128);
441	/// Maximum multiplier. We pick a value that is expensive but not impossibly so; it should act
442	/// as a safety net.
443	pub MaximumMultiplier: Multiplier = Multiplier::from(100_000u128);
444	pub PrecompilesValue: MoonbeamPrecompiles<Runtime> = MoonbeamPrecompiles::<_>::new();
445	pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
446	/// The amount of gas per pov. A ratio of 8 if we convert ref_time to gas and we compare
447	/// it with the pov_size for a block. E.g.
448	/// ceil(
449	///     (max_extrinsic.ref_time() / max_extrinsic.proof_size()) / WEIGHT_PER_GAS
450	/// )
451	/// We should re-check `xcm_config::Erc20XcmBridgeTransferGasLimit` when changing this value
452	pub const GasLimitPovSizeRatio: u64 = 8;
453	/// The amount of gas per storage (in bytes): BLOCK_GAS_LIMIT / BLOCK_STORAGE_LIMIT
454	/// The current definition of BLOCK_STORAGE_LIMIT is 160 KB, resulting in a value of 366.
455	pub GasLimitStorageGrowthRatio: u64 = 366;
456}
457
458pub struct TransactionPaymentAsGasPrice;
459impl FeeCalculator for TransactionPaymentAsGasPrice {
460	fn min_gas_price() -> (U256, Weight) {
461		// note: transaction-payment differs from EIP-1559 in that its tip and length fees are not
462		//       scaled by the multiplier, which means its multiplier will be overstated when
463		//       applied to an ethereum transaction
464		// note: transaction-payment uses both a congestion modifier (next_fee_multiplier, which is
465		//       updated once per block in on_finalize) and a 'WeightToFee' implementation. Our
466		//       runtime implements this as a 'ConstantModifier', so we can get away with a simple
467		//       multiplication here.
468		// It is imperative that `saturating_mul_int` be performed as late as possible in the
469		// expression since it involves fixed point multiplication with a division by a fixed
470		// divisor. This leads to truncation and subsequent precision loss if performed too early.
471		// This can lead to min_gas_price being same across blocks even if the multiplier changes.
472		// There's still some precision loss when the final `gas_price` (used_gas * min_gas_price)
473		// is computed in frontier, but that's currently unavoidable.
474		let min_gas_price = TransactionPayment::next_fee_multiplier()
475			.saturating_mul_int((currency::WEIGHT_FEE).saturating_mul(WEIGHT_PER_GAS as u128));
476		(
477			min_gas_price.into(),
478			<Runtime as frame_system::Config>::DbWeight::get().reads(1),
479		)
480	}
481}
482
483/// Parameterized slow adjusting fee updated based on
484/// https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism // editorconfig-checker-disable-line
485///
486/// The adjustment algorithm boils down to:
487///
488/// diff = (previous_block_weight - target) / maximum_block_weight
489/// next_multiplier = prev_multiplier * (1 + (v * diff) + ((v * diff)^2 / 2))
490/// assert(next_multiplier > min)
491///     where: v is AdjustmentVariable
492///            target is TargetBlockFullness
493///            min is MinimumMultiplier
494pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
495	R,
496	TargetBlockFullness,
497	AdjustmentVariable,
498	MinimumMultiplier,
499	MaximumMultiplier,
500>;
501
502use frame_support::traits::FindAuthor;
503//TODO It feels like this shold be able to work for any T: H160, but I tried for
504// embarassingly long and couldn't figure that out.
505
506/// The author inherent provides a AccountId20, but pallet evm needs an H160.
507/// This simple adapter makes the conversion.
508pub struct FindAuthorAdapter<Inner>(sp_std::marker::PhantomData<Inner>);
509
510impl<Inner> FindAuthor<H160> for FindAuthorAdapter<Inner>
511where
512	Inner: FindAuthor<AccountId20>,
513{
514	fn find_author<'a, I>(digests: I) -> Option<H160>
515	where
516		I: 'a + IntoIterator<Item = (sp_runtime::ConsensusEngineId, &'a [u8])>,
517	{
518		Inner::find_author(digests).map(Into::into)
519	}
520}
521
522moonbeam_runtime_common::impl_on_charge_evm_transaction!();
523
524impl pallet_evm::Config for Runtime {
525	type FeeCalculator = TransactionPaymentAsGasPrice;
526	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
527	type WeightPerGas = WeightPerGas;
528	type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
529	type CallOrigin = EnsureAddressRoot<AccountId>;
530	type WithdrawOrigin = EnsureAddressNever<AccountId>;
531	type AddressMapping = IdentityAddressMapping;
532	type Currency = Balances;
533	type Runner = pallet_evm::runner::stack::Runner<Self>;
534	type PrecompilesType = MoonbeamPrecompiles<Self>;
535	type PrecompilesValue = PrecompilesValue;
536	type ChainId = EthereumChainId;
537	type OnChargeTransaction = OnChargeEVMTransaction<
538		DealWithEthereumBaseFees<Runtime, dynamic_params::runtime_config::FeesTreasuryProportion>,
539		DealWithEthereumPriorityFees<Runtime>,
540	>;
541	type BlockGasLimit = BlockGasLimit;
542	type TransactionGasLimit = TransactionGasLimit;
543	type FindAuthor = FindAuthorAdapter<AuthorInherent>;
544	type OnCreate = ();
545	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
546	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
547	type Timestamp = Timestamp;
548	type AccountProvider = FrameSystemAccountProvider<Runtime>;
549	type CreateOriginFilter = ();
550	type CreateInnerOriginFilter = ();
551	type WeightInfo = moonbeam_weights::pallet_evm::WeightInfo<Runtime>;
552}
553
554parameter_types! {
555	pub MaxServiceWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
556}
557
558impl pallet_scheduler::Config for Runtime {
559	type RuntimeEvent = RuntimeEvent;
560	type RuntimeOrigin = RuntimeOrigin;
561	type PalletsOrigin = OriginCaller;
562	type RuntimeCall = RuntimeCall;
563	type MaximumWeight = MaxServiceWeight;
564	type ScheduleOrigin = EnsureRoot<AccountId>;
565	type MaxScheduledPerBlock = ConstU32<50>;
566	type WeightInfo = moonbeam_weights::pallet_scheduler::WeightInfo<Runtime>;
567	type OriginPrivilegeCmp = EqualPrivilegeOnly;
568	type Preimages = Preimage;
569	type BlockNumberProvider = System;
570}
571
572parameter_types! {
573	pub const PreimageBaseDeposit: Balance = 5 * currency::GLMR * currency::SUPPLY_FACTOR ;
574	pub const PreimageByteDeposit: Balance = currency::STORAGE_BYTE_FEE;
575	pub const PreimageHoldReason: RuntimeHoldReason =
576		RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
577}
578
579impl pallet_preimage::Config for Runtime {
580	type WeightInfo = moonbeam_weights::pallet_preimage::WeightInfo<Runtime>;
581	type RuntimeEvent = RuntimeEvent;
582	type Currency = Balances;
583	type ManagerOrigin = EnsureRoot<AccountId>;
584	type Consideration = HoldConsideration<
585		AccountId,
586		Balances,
587		PreimageHoldReason,
588		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
589	>;
590}
591
592parameter_types! {
593	pub const ProposalBond: Permill = Permill::from_percent(5);
594	pub const TreasuryId: PalletId = PalletId(*b"py/trsry");
595	pub TreasuryAccount: AccountId = Treasury::account_id();
596	pub const MaxSpendBalance: crate::Balance = crate::Balance::max_value();
597}
598
599type RootOrTreasuryCouncilOrigin = EitherOfDiverse<
600	EnsureRoot<AccountId>,
601	pallet_collective::EnsureProportionMoreThan<AccountId, TreasuryCouncilInstance, 1, 2>,
602>;
603
604impl pallet_treasury::Config for Runtime {
605	type PalletId = TreasuryId;
606	type Currency = Balances;
607	// More than half of the council is required (or root) to reject a proposal
608	type RejectOrigin = RootOrTreasuryCouncilOrigin;
609	type RuntimeEvent = RuntimeEvent;
610	type SpendPeriod = ConstU32<{ 6 * DAYS }>;
611	type Burn = ();
612	type BurnDestination = ();
613	type MaxApprovals = ConstU32<100>;
614	type WeightInfo = moonbeam_weights::pallet_treasury::WeightInfo<Runtime>;
615	type SpendFunds = ();
616	type SpendOrigin =
617		frame_system::EnsureWithSuccess<RootOrTreasuryCouncilOrigin, AccountId, MaxSpendBalance>;
618	type AssetKind = NativeOrWithId<AssetId>;
619	type Beneficiary = AccountId;
620	type BeneficiaryLookup = IdentityLookup<AccountId>;
621	type Paymaster = MultiAssetPaymaster<Runtime, TreasuryAccount, Balances>;
622	type BalanceConverter = AssetRateConverter<Runtime, Balances>;
623	type PayoutPeriod = ConstU32<{ 30 * DAYS }>;
624	#[cfg(feature = "runtime-benchmarks")]
625	type BenchmarkHelper = BenchmarkHelper<Runtime>;
626	type BlockNumberProvider = System;
627}
628
629parameter_types! {
630	pub const MaxSubAccounts: u32 = 100;
631	pub const MaxAdditionalFields: u32 = 100;
632	pub const MaxRegistrars: u32 = 20;
633	pub const PendingUsernameExpiration: u32 = 7 * DAYS;
634	pub const MaxSuffixLength: u32 = 7;
635	pub const MaxUsernameLength: u32 = 32;
636}
637
638type IdentityForceOrigin =
639	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
640type IdentityRegistrarOrigin =
641	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
642
643impl pallet_identity::Config for Runtime {
644	type RuntimeEvent = RuntimeEvent;
645	type Currency = Balances;
646	// Add one item in storage and take 258 bytes
647	type BasicDeposit = ConstU128<{ currency::deposit(1, 258) }>;
648	// Does not add any item to the storage but takes 1 bytes
649	type ByteDeposit = ConstU128<{ currency::deposit(0, 1) }>;
650	// Add one item in storage and take 53 bytes
651	type SubAccountDeposit = ConstU128<{ currency::deposit(1, 53) }>;
652	type MaxSubAccounts = MaxSubAccounts;
653	type IdentityInformation = pallet_identity::legacy::IdentityInfo<MaxAdditionalFields>;
654	type MaxRegistrars = MaxRegistrars;
655	type Slashed = Treasury;
656	type ForceOrigin = IdentityForceOrigin;
657	type RegistrarOrigin = IdentityRegistrarOrigin;
658	type OffchainSignature = Signature;
659	type SigningPublicKey = <Signature as sp_runtime::traits::Verify>::Signer;
660	type UsernameAuthorityOrigin = EnsureRoot<AccountId>;
661	type PendingUsernameExpiration = PendingUsernameExpiration;
662	type MaxSuffixLength = MaxSuffixLength;
663	type MaxUsernameLength = MaxUsernameLength;
664	type WeightInfo = moonbeam_weights::pallet_identity::WeightInfo<Runtime>;
665	type UsernameDeposit = ConstU128<{ currency::deposit(0, MaxUsernameLength::get()) }>;
666	type UsernameGracePeriod = ConstU32<{ 30 * DAYS }>;
667	#[cfg(feature = "runtime-benchmarks")]
668	type BenchmarkHelper = BenchmarkHelper<Runtime>;
669}
670
671pub struct TransactionConverter;
672
673impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
674	fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
675		UncheckedExtrinsic::new_bare(
676			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
677		)
678	}
679}
680
681impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
682	fn convert_transaction(
683		&self,
684		transaction: pallet_ethereum::Transaction,
685	) -> opaque::UncheckedExtrinsic {
686		let extrinsic = UncheckedExtrinsic::new_bare(
687			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
688		);
689		let encoded = extrinsic.encode();
690		opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
691			.expect("Encoded extrinsic is always valid")
692	}
693}
694
695parameter_types! {
696	pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
697	pub const AllowUnprotectedTxs: bool = false;
698}
699
700impl pallet_ethereum::Config for Runtime {
701	type StateRoot = pallet_ethereum::IntermediateStateRoot<Self::Version>;
702	type PostLogContent = PostBlockAndTxnHashes;
703	type ExtraDataLength = ConstU32<30>;
704	type AllowUnprotectedTxs = AllowUnprotectedTxs;
705}
706
707/// Relay chain slot duration, in milliseconds.
708const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
709/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
710/// into the relay chain.
711const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
712/// Build with an offset of 1 behind the relay chain.
713const RELAY_PARENT_OFFSET: u32 = 1;
714/// How many parachain blocks are processed by the relay chain per parent. Limits the
715/// number of blocks authored per slot.
716const BLOCK_PROCESSING_VELOCITY: u32 = 1;
717
718type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
719	Runtime,
720	RELAY_CHAIN_SLOT_DURATION_MILLIS,
721	BLOCK_PROCESSING_VELOCITY,
722	UNINCLUDED_SEGMENT_CAPACITY,
723>;
724
725impl cumulus_pallet_parachain_system::Config for Runtime {
726	type RuntimeEvent = RuntimeEvent;
727	type OnSystemEvent = ();
728	type SelfParaId = ParachainInfo;
729	type ReservedDmpWeight = ReservedDmpWeight;
730	type OutboundXcmpMessageSource = XcmpQueue;
731	type XcmpMessageHandler = XcmpQueue;
732	type ReservedXcmpWeight = ReservedXcmpWeight;
733	type CheckAssociatedRelayNumber = EmergencyParaXcm;
734	type ConsensusHook = ConsensusHook;
735	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
736	type WeightInfo = moonbeam_weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
737	type RelayParentOffset = ConstU32<0>;
738}
739
740pub struct EthereumXcmEnsureProxy;
741impl xcm_primitives::EnsureProxy<AccountId> for EthereumXcmEnsureProxy {
742	fn ensure_ok(delegator: AccountId, delegatee: AccountId) -> Result<(), &'static str> {
743		// The EVM implicitely contains an Any proxy, so we only allow for "Any" proxies
744		let def: pallet_proxy::ProxyDefinition<AccountId, ProxyType, BlockNumber> =
745			pallet_proxy::Pallet::<Runtime>::find_proxy(
746				&delegator,
747				&delegatee,
748				Some(ProxyType::Any),
749			)
750			.map_err(|_| "proxy error: expected `ProxyType::Any`")?;
751		// We only allow to use it for delay zero proxies, as the call will immediatly be executed
752		ensure!(def.delay.is_zero(), "proxy delay is Non-zero`");
753		Ok(())
754	}
755}
756
757impl pallet_ethereum_xcm::Config for Runtime {
758	type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
759	type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
760	type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
761	type ReservedXcmpWeight = ReservedXcmpWeight;
762	type EnsureProxy = EthereumXcmEnsureProxy;
763	type ControllerOrigin = EnsureRoot<AccountId>;
764	type ForceOrigin = EnsureRoot<AccountId>;
765}
766
767parameter_types! {
768	// Reserved weight is 1/4 of MAXIMUM_BLOCK_WEIGHT
769	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
770	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
771	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
772}
773
774impl parachain_info::Config for Runtime {}
775
776pub struct OnNewRound;
777impl pallet_parachain_staking::OnNewRound for OnNewRound {
778	fn on_new_round(round_index: pallet_parachain_staking::RoundIndex) -> Weight {
779		MoonbeamOrbiters::on_new_round(round_index)
780	}
781}
782pub struct PayoutCollatorOrOrbiterReward;
783impl pallet_parachain_staking::PayoutCollatorReward<Runtime> for PayoutCollatorOrOrbiterReward {
784	fn payout_collator_reward(
785		for_round: pallet_parachain_staking::RoundIndex,
786		collator_id: AccountId,
787		amount: Balance,
788	) -> Weight {
789		let extra_weight =
790			if MoonbeamOrbiters::is_collator_pool_with_active_orbiter(for_round, collator_id) {
791				MoonbeamOrbiters::distribute_rewards(for_round, collator_id, amount)
792			} else {
793				ParachainStaking::mint_collator_reward(for_round, collator_id, amount)
794			};
795
796		<Runtime as frame_system::Config>::DbWeight::get()
797			.reads(1)
798			.saturating_add(extra_weight)
799	}
800}
801
802pub struct OnInactiveCollator;
803impl pallet_parachain_staking::OnInactiveCollator<Runtime> for OnInactiveCollator {
804	fn on_inactive_collator(
805		collator_id: AccountId,
806		round: pallet_parachain_staking::RoundIndex,
807	) -> Result<Weight, DispatchErrorWithPostInfo<PostDispatchInfo>> {
808		let extra_weight = if !MoonbeamOrbiters::is_collator_pool_with_active_orbiter(
809			round,
810			collator_id.clone(),
811		) {
812			ParachainStaking::go_offline_inner(collator_id)?;
813			<Runtime as pallet_parachain_staking::Config>::WeightInfo::go_offline(
814				pallet_parachain_staking::MAX_CANDIDATES,
815			)
816		} else {
817			Weight::zero()
818		};
819
820		Ok(<Runtime as frame_system::Config>::DbWeight::get()
821			.reads(1)
822			.saturating_add(extra_weight))
823	}
824}
825type MonetaryGovernanceOrigin =
826	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
827
828pub struct RelayChainSlotProvider;
829impl Get<Slot> for RelayChainSlotProvider {
830	fn get() -> Slot {
831		let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
832		slot_info.unwrap_or_default().0
833	}
834}
835
836parameter_types! {
837	// Voted by the moonbeam community on this referenda: https://moonbeam.polkassembly.network/referenda/116
838	pub const LinearInflationThreshold: Option<Balance> = Some(1_200_000_000 * currency::GLMR);
839}
840
841impl pallet_parachain_staking::Config for Runtime {
842	type Currency = Balances;
843	type MonetaryGovernanceOrigin = MonetaryGovernanceOrigin;
844	/// Minimum round length is 2 minutes (10 * 12 second block times)
845	type MinBlocksPerRound = ConstU32<10>;
846	/// If a collator doesn't produce any block on this number of rounds, it is notified as inactive
847	type MaxOfflineRounds = ConstU32<1>;
848	/// Rounds before the collator leaving the candidates request can be executed
849	type LeaveCandidatesDelay = ConstU32<{ 4 * 7 }>;
850	/// Rounds before the candidate bond increase/decrease can be executed
851	type CandidateBondLessDelay = ConstU32<{ 4 * 7 }>;
852	/// Rounds before the delegator exit can be executed
853	type LeaveDelegatorsDelay = ConstU32<{ 4 * 7 }>;
854	/// Rounds before the delegator revocation can be executed
855	type RevokeDelegationDelay = ConstU32<{ 4 * 7 }>;
856	/// Rounds before the delegator bond increase/decrease can be executed
857	type DelegationBondLessDelay = ConstU32<{ 4 * 7 }>;
858	/// Rounds before the reward is paid
859	type RewardPaymentDelay = ConstU32<2>;
860	/// Minimum collators selected per round, default at genesis and minimum forever after
861	type MinSelectedCandidates = ConstU32<8>;
862	/// Maximum top delegations per candidate
863	type MaxTopDelegationsPerCandidate = ConstU32<300>;
864	/// Maximum bottom delegations per candidate
865	type MaxBottomDelegationsPerCandidate = ConstU32<50>;
866	/// Maximum delegations per delegator
867	type MaxDelegationsPerDelegator = ConstU32<100>;
868	/// Maximum scheduled delegation requests per (collator, delegator)
869	type MaxScheduledRequestsPerDelegator = ConstU32<50>;
870	/// Minimum stake required to be reserved to be a candidate
871	type MinCandidateStk = ConstU128<{ 100_000 * currency::GLMR }>;
872	/// Minimum stake required to be reserved to be a delegator
873	type MinDelegation = ConstU128<{ 500 * currency::MILLIGLMR * currency::SUPPLY_FACTOR }>;
874	type BlockAuthor = AuthorInherent;
875	type OnCollatorPayout = ();
876	type PayoutCollatorReward = PayoutCollatorOrOrbiterReward;
877	type OnInactiveCollator = OnInactiveCollator;
878	type OnNewRound = OnNewRound;
879	type SlotProvider = RelayChainSlotProvider;
880	type WeightInfo = moonbeam_weights::pallet_parachain_staking::WeightInfo<Runtime>;
881	type MaxCandidates = ConstU32<200>;
882	type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
883	type BlockTime = ConstU64<MILLISECS_PER_BLOCK>;
884	type RuntimeFreezeReason = RuntimeFreezeReason;
885	type LinearInflationThreshold = LinearInflationThreshold;
886}
887
888impl pallet_author_inherent::Config for Runtime {
889	type SlotBeacon = RelaychainDataProvider<Self>;
890	type AccountLookup = MoonbeamOrbiters;
891	type CanAuthor = AuthorFilter;
892	type AuthorId = AccountId;
893	type WeightInfo = moonbeam_weights::pallet_author_inherent::WeightInfo<Runtime>;
894}
895
896impl pallet_author_slot_filter::Config for Runtime {
897	type RandomnessSource = Randomness;
898	type PotentialAuthors = ParachainStaking;
899	type WeightInfo = moonbeam_weights::pallet_author_slot_filter::WeightInfo<Runtime>;
900}
901
902impl pallet_async_backing::Config for Runtime {
903	type AllowMultipleBlocksPerSlot = ConstBool<true>;
904	type GetAndVerifySlot = pallet_async_backing::RelaySlot;
905	type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
906	type ExpectedBlockTime = ConstU64<MILLISECS_PER_BLOCK>;
907}
908
909parameter_types! {
910	pub const InitializationPayment: Perbill = Perbill::from_percent(30);
911	pub const RelaySignaturesThreshold: Perbill = Perbill::from_percent(100);
912	pub const SignatureNetworkIdentifier:  &'static [u8] = b"moonbeam-";
913}
914
915impl pallet_crowdloan_rewards::Config for Runtime {
916	type Initialized = ConstBool<false>;
917	type InitializationPayment = InitializationPayment;
918	type MaxInitContributors = ConstU32<500>;
919	type MinimumReward = ConstU128<0>;
920	type RewardCurrency = Balances;
921	type RelayChainAccountId = [u8; 32];
922	type RewardAddressAssociateOrigin = EnsureSigned<Self::AccountId>;
923	type RewardAddressChangeOrigin = EnsureSigned<Self::AccountId>;
924	type RewardAddressRelayVoteThreshold = RelaySignaturesThreshold;
925	type SignatureNetworkIdentifier = SignatureNetworkIdentifier;
926	type VestingBlockNumber = relay_chain::BlockNumber;
927	type VestingBlockProvider = RelaychainDataProvider<Self>;
928	type WeightInfo = moonbeam_weights::pallet_crowdloan_rewards::WeightInfo<Runtime>;
929}
930
931// This is a simple session key manager. It should probably either work with, or be replaced
932// entirely by pallet sessions
933impl pallet_author_mapping::Config for Runtime {
934	type DepositCurrency = Balances;
935	type DepositAmount = ConstU128<{ 100 * currency::GLMR * currency::SUPPLY_FACTOR }>;
936	type Keys = session_keys_primitives::VrfId;
937	type WeightInfo = moonbeam_weights::pallet_author_mapping::WeightInfo<Runtime>;
938}
939
940/// The type used to represent the kinds of proxying allowed.
941#[derive(
942	Copy,
943	Clone,
944	Eq,
945	PartialEq,
946	Ord,
947	PartialOrd,
948	Encode,
949	Decode,
950	Debug,
951	MaxEncodedLen,
952	TypeInfo,
953	Serialize,
954	Deserialize,
955	DecodeWithMemTracking,
956)]
957pub enum ProxyType {
958	/// All calls can be proxied. This is the trivial/most permissive filter.
959	Any = 0,
960	/// Only extrinsics that do not transfer funds.
961	NonTransfer = 1,
962	/// Only extrinsics related to governance (democracy and collectives).
963	Governance = 2,
964	/// Only extrinsics related to staking.
965	Staking = 3,
966	/// Allow to veto an announced proxy call.
967	CancelProxy = 4,
968	/// Allow extrinsic related to Balances.
969	Balances = 5,
970	/// Allow extrinsic related to AuthorMapping.
971	AuthorMapping = 6,
972	/// Allow extrinsic related to IdentityJudgement.
973	IdentityJudgement = 7,
974}
975
976impl Default for ProxyType {
977	fn default() -> Self {
978		Self::Any
979	}
980}
981
982fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool {
983	matches!(
984		precompile_name,
985		PrecompileName::ConvictionVotingPrecompile
986			| PrecompileName::PreimagePrecompile
987			| PrecompileName::ReferendaPrecompile
988			| PrecompileName::OpenTechCommitteeInstance
989			| PrecompileName::TreasuryCouncilInstance
990	)
991}
992
993// Be careful: Each time this filter is modified, the substrate filter must also be modified
994// consistently.
995impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {
996	fn is_evm_proxy_call_allowed(
997		&self,
998		call: &pallet_evm_precompile_proxy::EvmSubCall,
999		recipient_has_code: bool,
1000		gas: u64,
1001	) -> precompile_utils::EvmResult<bool> {
1002		Ok(match self {
1003			ProxyType::Any => {
1004				match PrecompileName::from_address(call.to.0) {
1005					// Any precompile that can execute a subcall should be forbidden here,
1006					// to ensure that unauthorized smart contract can't be called
1007					// indirectly.
1008					// To be safe, we only allow the precompiles we need.
1009					Some(
1010						PrecompileName::AuthorMappingPrecompile
1011						| PrecompileName::ParachainStakingPrecompile,
1012					) => true,
1013					Some(ref precompile) if is_governance_precompile(precompile) => true,
1014					// All non-whitelisted precompiles are forbidden
1015					Some(_) => false,
1016					// Allow evm transfer to "simple" account (no code nor precompile)
1017					// For the moment, no smart contract other than precompiles is allowed.
1018					// In the future, we may create a dynamic whitelist to authorize some audited
1019					// smart contracts through governance.
1020					None => {
1021						// If the address is not recognized, allow only evm transfer to "simple"
1022						// accounts (no code nor precompile).
1023						// Note: Checking the presence of the code is not enough because some
1024						// precompiles have no code.
1025						!recipient_has_code
1026							&& !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
1027								call.to.0, gas,
1028							)?
1029					}
1030				}
1031			}
1032			ProxyType::NonTransfer => {
1033				call.value == U256::zero()
1034					&& match PrecompileName::from_address(call.to.0) {
1035						Some(
1036							PrecompileName::AuthorMappingPrecompile
1037							| PrecompileName::ParachainStakingPrecompile,
1038						) => true,
1039						Some(ref precompile) if is_governance_precompile(precompile) => true,
1040						_ => false,
1041					}
1042			}
1043			ProxyType::Governance => {
1044				call.value == U256::zero()
1045					&& matches!(
1046						PrecompileName::from_address(call.to.0),
1047						Some(ref precompile) if is_governance_precompile(precompile)
1048					)
1049			}
1050			ProxyType::Staking => {
1051				call.value == U256::zero()
1052					&& matches!(
1053						PrecompileName::from_address(call.to.0),
1054						Some(
1055							PrecompileName::AuthorMappingPrecompile
1056								| PrecompileName::ParachainStakingPrecompile
1057						)
1058					)
1059			}
1060			// The proxy precompile does not contain method cancel_proxy
1061			ProxyType::CancelProxy => false,
1062			ProxyType::Balances => {
1063				// Allow only "simple" accounts as recipient (no code nor precompile).
1064				// Note: Checking the presence of the code is not enough because some precompiles
1065				// have no code.
1066				!recipient_has_code
1067					&& !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
1068						call.to.0, gas,
1069					)?
1070			}
1071			ProxyType::AuthorMapping => {
1072				call.value == U256::zero()
1073					&& matches!(
1074						PrecompileName::from_address(call.to.0),
1075						Some(PrecompileName::AuthorMappingPrecompile)
1076					)
1077			}
1078			// There is no identity precompile
1079			ProxyType::IdentityJudgement => false,
1080		})
1081	}
1082}
1083
1084// Be careful: Each time this filter is modified, the EVM filter must also be modified consistently.
1085impl InstanceFilter<RuntimeCall> for ProxyType {
1086	fn filter(&self, c: &RuntimeCall) -> bool {
1087		match self {
1088			ProxyType::Any => true,
1089			ProxyType::NonTransfer => match c {
1090				RuntimeCall::Identity(
1091					pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. },
1092				) => false,
1093				call => {
1094					matches!(
1095						call,
1096						RuntimeCall::System(..)
1097							| RuntimeCall::ParachainSystem(..)
1098							| RuntimeCall::Timestamp(..)
1099							| RuntimeCall::ParachainStaking(..)
1100							| RuntimeCall::Referenda(..)
1101							| RuntimeCall::Preimage(..)
1102							| RuntimeCall::ConvictionVoting(..)
1103							| RuntimeCall::TreasuryCouncilCollective(..)
1104							| RuntimeCall::OpenTechCommitteeCollective(..)
1105							| RuntimeCall::Utility(..)
1106							| RuntimeCall::Proxy(..)
1107							| RuntimeCall::Identity(..)
1108							| RuntimeCall::AuthorMapping(..)
1109							| RuntimeCall::CrowdloanRewards(
1110								pallet_crowdloan_rewards::Call::claim { .. }
1111							)
1112					)
1113				}
1114			},
1115			ProxyType::Governance => matches!(
1116				c,
1117				RuntimeCall::Referenda(..)
1118					| RuntimeCall::Preimage(..)
1119					| RuntimeCall::ConvictionVoting(..)
1120					| RuntimeCall::TreasuryCouncilCollective(..)
1121					| RuntimeCall::OpenTechCommitteeCollective(..)
1122					| RuntimeCall::Utility(..)
1123			),
1124			ProxyType::Staking => matches!(
1125				c,
1126				RuntimeCall::ParachainStaking(..)
1127					| RuntimeCall::Utility(..)
1128					| RuntimeCall::AuthorMapping(..)
1129					| RuntimeCall::MoonbeamOrbiters(..)
1130			),
1131			ProxyType::CancelProxy => matches!(
1132				c,
1133				RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
1134			),
1135			ProxyType::Balances => {
1136				matches!(c, RuntimeCall::Balances(..) | RuntimeCall::Utility(..))
1137			}
1138			ProxyType::AuthorMapping => matches!(c, RuntimeCall::AuthorMapping(..)),
1139			ProxyType::IdentityJudgement => matches!(
1140				c,
1141				RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. })
1142					| RuntimeCall::Utility(..)
1143			),
1144		}
1145	}
1146
1147	fn is_superset(&self, o: &Self) -> bool {
1148		match (self, o) {
1149			(x, y) if x == y => true,
1150			(ProxyType::Any, _) => true,
1151			(_, ProxyType::Any) => false,
1152			_ => false,
1153		}
1154	}
1155}
1156
1157impl pallet_proxy::Config for Runtime {
1158	type RuntimeEvent = RuntimeEvent;
1159	type RuntimeCall = RuntimeCall;
1160	type Currency = Balances;
1161	type ProxyType = ProxyType;
1162	// One storage item; key size 32, value size 8
1163	type ProxyDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
1164	// Additional storage item size of 21 bytes (20 bytes AccountId + 1 byte sizeof(ProxyType)).
1165	type ProxyDepositFactor = ConstU128<{ currency::deposit(0, 21) }>;
1166	type MaxProxies = ConstU32<32>;
1167	type WeightInfo = moonbeam_weights::pallet_proxy::WeightInfo<Runtime>;
1168	type MaxPending = ConstU32<32>;
1169	type CallHasher = BlakeTwo256;
1170	type AnnouncementDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
1171	// Additional storage item size of 56 bytes:
1172	// - 20 bytes AccountId
1173	// - 32 bytes Hasher (Blake2256)
1174	// - 4 bytes BlockNumber (u32)
1175	type AnnouncementDepositFactor = ConstU128<{ currency::deposit(0, 56) }>;
1176	type BlockNumberProvider = System;
1177}
1178
1179pub type ForeignAssetMigratorOrigin = EitherOfDiverse<
1180	EnsureRoot<AccountId>,
1181	EitherOfDiverse<
1182		pallet_collective::EnsureProportionMoreThan<AccountId, OpenTechCommitteeInstance, 5, 9>,
1183		EitherOf<
1184			governance::custom_origins::GeneralAdmin,
1185			governance::custom_origins::FastGeneralAdmin,
1186		>,
1187	>,
1188>;
1189
1190impl pallet_moonbeam_lazy_migrations::Config for Runtime {
1191	type WeightInfo = moonbeam_weights::pallet_moonbeam_lazy_migrations::WeightInfo<Runtime>;
1192}
1193
1194/// Maintenance mode Call filter
1195pub struct MaintenanceFilter;
1196impl Contains<RuntimeCall> for MaintenanceFilter {
1197	fn contains(c: &RuntimeCall) -> bool {
1198		match c {
1199			RuntimeCall::Balances(_) => false,
1200			RuntimeCall::CrowdloanRewards(_) => false,
1201			RuntimeCall::Ethereum(_) => false,
1202			RuntimeCall::EVM(_) => false,
1203			RuntimeCall::Identity(_) => false,
1204			RuntimeCall::ParachainStaking(_) => false,
1205			RuntimeCall::MoonbeamOrbiters(_) => false,
1206			RuntimeCall::PolkadotXcm(_) => false,
1207			RuntimeCall::Treasury(_) => false,
1208			RuntimeCall::XcmTransactor(_) => false,
1209			RuntimeCall::EthereumXcm(_) => false,
1210			_ => true,
1211		}
1212	}
1213}
1214
1215/// Normal Call Filter
1216pub struct NormalFilter;
1217
1218impl Contains<RuntimeCall> for NormalFilter {
1219	fn contains(c: &RuntimeCall) -> bool {
1220		match c {
1221			RuntimeCall::PolkadotXcm(method) => match method {
1222				// User Operations (Anyone can call these extrinsics)
1223				pallet_xcm::Call::send { .. }
1224				| pallet_xcm::Call::claim_assets { .. }
1225				| pallet_xcm::Call::transfer_assets { .. }
1226				| pallet_xcm::Call::transfer_assets_using_type_and_then { .. } => true,
1227				// Administrative operations (Only AdminOrigin can call these extrinsics)
1228				pallet_xcm::Call::force_xcm_version { .. }
1229				| pallet_xcm::Call::force_default_xcm_version { .. }
1230				| pallet_xcm::Call::force_subscribe_version_notify { .. }
1231				| pallet_xcm::Call::force_unsubscribe_version_notify { .. } => true,
1232				// Anything else is disallowed
1233				_ => false,
1234			},
1235			RuntimeCall::Proxy(method) => match method {
1236				pallet_proxy::Call::proxy { real, .. } => {
1237					!pallet_evm::AccountCodes::<Runtime>::contains_key(H160::from(*real))
1238				}
1239				_ => true,
1240			},
1241			// Filtering the EVM prevents possible re-entrancy from the precompiles which could
1242			// lead to unexpected scenarios.
1243			// See https://github.com/PureStake/sr-moonbeam/issues/30
1244			// Note: It is also assumed that EVM calls are only allowed through `Origin::Root` so
1245			// this can be seen as an additional security
1246			RuntimeCall::EVM(_) => false,
1247			_ => true,
1248		}
1249	}
1250}
1251
1252pub struct XcmExecutionManager;
1253impl moonkit_xcm_primitives::PauseXcmExecution for XcmExecutionManager {
1254	fn suspend_xcm_execution() -> DispatchResult {
1255		XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
1256	}
1257	fn resume_xcm_execution() -> DispatchResult {
1258		XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
1259	}
1260}
1261
1262impl pallet_maintenance_mode::Config for Runtime {
1263	type NormalCallFilter = NormalFilter;
1264	type MaintenanceCallFilter = MaintenanceFilter;
1265	type MaintenanceOrigin =
1266		pallet_collective::EnsureProportionAtLeast<AccountId, OpenTechCommitteeInstance, 5, 9>;
1267	type XcmExecutionManager = XcmExecutionManager;
1268}
1269
1270impl pallet_proxy_genesis_companion::Config for Runtime {
1271	type ProxyType = ProxyType;
1272	type BlockNumberProvider = System;
1273}
1274
1275parameter_types! {
1276	pub OrbiterReserveIdentifier: [u8; 4] = [b'o', b'r', b'b', b'i'];
1277}
1278
1279type AddCollatorOrigin =
1280	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
1281type DelCollatorOrigin =
1282	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
1283
1284impl pallet_moonbeam_orbiters::Config for Runtime {
1285	type AccountLookup = AuthorMapping;
1286	type AddCollatorOrigin = AddCollatorOrigin;
1287	type Currency = Balances;
1288	type DelCollatorOrigin = DelCollatorOrigin;
1289	/// Maximum number of orbiters per collator
1290	type MaxPoolSize = ConstU32<8>;
1291	/// Maximum number of round to keep on storage
1292	type MaxRoundArchive = ConstU32<4>;
1293	type OrbiterReserveIdentifier = OrbiterReserveIdentifier;
1294	type RotatePeriod = ConstU32<1>;
1295	/// Round index type.
1296	type RoundIndex = pallet_parachain_staking::RoundIndex;
1297	type WeightInfo = moonbeam_weights::pallet_moonbeam_orbiters::WeightInfo<Runtime>;
1298}
1299
1300/// Only callable after `set_validation_data` is called which forms this proof the same way
1301fn relay_chain_state_proof<Runtime>() -> RelayChainStateProof
1302where
1303	Runtime: cumulus_pallet_parachain_system::Config,
1304{
1305	let relay_storage_root = ValidationData::<Runtime>::get()
1306		.expect("set in `set_validation_data`")
1307		.relay_parent_storage_root;
1308	let relay_chain_state =
1309		RelayStateProof::<Runtime>::get().expect("set in `set_validation_data`");
1310	RelayChainStateProof::new(ParachainInfo::get(), relay_storage_root, relay_chain_state)
1311		.expect("Invalid relay chain state proof, already constructed in `set_validation_data`")
1312}
1313
1314pub struct BabeDataGetter<Runtime>(sp_std::marker::PhantomData<Runtime>);
1315impl<Runtime> pallet_randomness::GetBabeData<u64, Option<Hash>> for BabeDataGetter<Runtime>
1316where
1317	Runtime: cumulus_pallet_parachain_system::Config,
1318{
1319	// Tolerate panic here because only ever called in inherent (so can be omitted)
1320	fn get_epoch_index() -> u64 {
1321		if cfg!(feature = "runtime-benchmarks") {
1322			// storage reads as per actual reads
1323			let _relay_storage_root = ValidationData::<Runtime>::get();
1324			let _relay_chain_state = RelayStateProof::<Runtime>::get();
1325			const BENCHMARKING_NEW_EPOCH: u64 = 10u64;
1326			return BENCHMARKING_NEW_EPOCH;
1327		}
1328		relay_chain_state_proof::<Runtime>()
1329			.read_optional_entry(relay_chain::well_known_keys::EPOCH_INDEX)
1330			.ok()
1331			.flatten()
1332			.expect("expected to be able to read epoch index from relay chain state proof")
1333	}
1334	fn get_epoch_randomness() -> Option<Hash> {
1335		if cfg!(feature = "runtime-benchmarks") {
1336			// storage reads as per actual reads
1337			let _relay_storage_root = ValidationData::<Runtime>::get();
1338			let _relay_chain_state = RelayStateProof::<Runtime>::get();
1339			let benchmarking_babe_output = Hash::default();
1340			return Some(benchmarking_babe_output);
1341		}
1342		relay_chain_state_proof::<Runtime>()
1343			.read_optional_entry(relay_chain::well_known_keys::ONE_EPOCH_AGO_RANDOMNESS)
1344			.ok()
1345			.flatten()
1346	}
1347}
1348
1349impl pallet_randomness::Config for Runtime {
1350	type AddressMapping = sp_runtime::traits::ConvertInto;
1351	type Currency = Balances;
1352	type BabeDataGetter = BabeDataGetter<Runtime>;
1353	type VrfKeyLookup = AuthorMapping;
1354	type Deposit = runtime_params::PalletRandomnessDepositU128;
1355	type MaxRandomWords = ConstU8<100>;
1356	type MinBlockDelay = ConstU32<2>;
1357	type MaxBlockDelay = ConstU32<2_000>;
1358	type BlockExpirationDelay = ConstU32<10_000>;
1359	type EpochExpirationDelay = ConstU64<10_000>;
1360	type WeightInfo = moonbeam_weights::pallet_randomness::WeightInfo<Runtime>;
1361}
1362
1363impl pallet_root_testing::Config for Runtime {
1364	type RuntimeEvent = RuntimeEvent;
1365}
1366
1367parameter_types! {
1368	// One storage item; key size is 32 + 20; value is size 4+4+16+20 bytes = 44 bytes.
1369	pub const DepositBase: Balance = currency::deposit(1, 96);
1370	// Additional storage item size of 20 bytes.
1371	pub const DepositFactor: Balance = currency::deposit(0, 20);
1372	pub const MaxSignatories: u32 = 100;
1373}
1374
1375impl pallet_multisig::Config for Runtime {
1376	type RuntimeEvent = RuntimeEvent;
1377	type RuntimeCall = RuntimeCall;
1378	type Currency = Balances;
1379	type DepositBase = DepositBase;
1380	type DepositFactor = DepositFactor;
1381	type MaxSignatories = MaxSignatories;
1382	type WeightInfo = moonbeam_weights::pallet_multisig::WeightInfo<Runtime>;
1383	type BlockNumberProvider = System;
1384}
1385
1386impl pallet_relay_storage_roots::Config for Runtime {
1387	type MaxStorageRoots = ConstU32<30>;
1388	type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Self>;
1389	type WeightInfo = moonbeam_weights::pallet_relay_storage_roots::WeightInfo<Runtime>;
1390}
1391
1392#[cfg(feature = "runtime-benchmarks")]
1393impl pallet_precompile_benchmarks::Config for Runtime {
1394	type WeightInfo = moonbeam_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>;
1395}
1396
1397impl pallet_parameters::Config for Runtime {
1398	type AdminOrigin = EnsureRoot<AccountId>;
1399	type RuntimeEvent = RuntimeEvent;
1400	type RuntimeParameters = RuntimeParameters;
1401	type WeightInfo = moonbeam_weights::pallet_parameters::WeightInfo<Runtime>;
1402}
1403
1404impl cumulus_pallet_weight_reclaim::Config for Runtime {
1405	type WeightInfo = moonbeam_weights::cumulus_pallet_weight_reclaim::WeightInfo<Runtime>;
1406}
1407
1408impl pallet_migrations::Config for Runtime {
1409	type RuntimeEvent = RuntimeEvent;
1410	#[cfg(not(feature = "runtime-benchmarks"))]
1411	type Migrations = migrations::MultiBlockMigrationList<Runtime>;
1412	#[cfg(feature = "runtime-benchmarks")]
1413	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
1414	type CursorMaxLen = ConstU32<65_536>;
1415	type IdentifierMaxLen = ConstU32<256>;
1416	type MigrationStatusHandler = ();
1417	type FailedMigrationHandler = MaintenanceMode;
1418	type MaxServiceWeight = MaxServiceWeight;
1419	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
1420}
1421
1422construct_runtime! {
1423	pub enum Runtime
1424	{
1425		// System support stuff.
1426		System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>} = 0,
1427		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 1,
1428		// Previously 2: pallet_randomness_collective_flip
1429		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
1430		ParachainInfo: parachain_info::{Pallet, Storage, Config<T>} = 4,
1431		RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event<T>} = 5,
1432
1433		// Monetary stuff.
1434		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
1435		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Config<T>, Event<T>} = 11,
1436
1437		// Consensus support.
1438		ParachainStaking: pallet_parachain_staking::{Pallet, Call, Storage, Event<T>, Config<T>, FreezeReason} = 20,
1439		AuthorInherent: pallet_author_inherent::{Pallet, Call, Storage, Inherent} = 21,
1440		AuthorFilter: pallet_author_slot_filter::{Pallet, Call, Storage, Event, Config<T>} = 22,
1441		AuthorMapping: pallet_author_mapping::{Pallet, Call, Config<T>, Storage, Event<T>} = 23,
1442		MoonbeamOrbiters: pallet_moonbeam_orbiters::{Pallet, Call, Storage, Event<T>} = 24,
1443		AsyncBacking: pallet_async_backing::{Pallet, Storage} = 25,
1444
1445		// Handy utilities.
1446		Utility: pallet_utility::{Pallet, Call, Event} = 30,
1447		Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 31,
1448		MaintenanceMode: pallet_maintenance_mode::{Pallet, Call, Config<T>, Storage, Event} = 32,
1449		Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 33,
1450		// [Removed] Migrations: pallet_migrations::{Pallet, Storage, Config<T>, Event<T>} = 34,
1451		ProxyGenesisCompanion: pallet_proxy_genesis_companion::{Pallet, Config<T>} = 35,
1452		Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 36,
1453		MoonbeamLazyMigrations: pallet_moonbeam_lazy_migrations::{Pallet, Call, Storage} = 37,
1454		Parameters: pallet_parameters = 38,
1455
1456		// Has been permanently removed for safety reasons.
1457		// Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>} = 40,
1458
1459		// Ethereum compatibility.
1460		EthereumChainId: pallet_evm_chain_id::{Pallet, Storage, Config<T>} = 50,
1461		EVM: pallet_evm::{Pallet, Config<T>, Call, Storage, Event<T>} = 51,
1462		Ethereum: pallet_ethereum::{Pallet, Call, Storage, Event, Origin, Config<T>} = 52,
1463
1464		// Governance stuff.
1465		Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 60,
1466		// Democracy: 61,
1467		Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 62,
1468		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 63,
1469		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 64,
1470		Origins: governance::custom_origins::{Origin} = 65,
1471		Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 66,
1472
1473		// Council stuff.
1474		// CouncilCollective: 70
1475		// TechCommitteeCollective: 71
1476		TreasuryCouncilCollective:
1477			pallet_collective::<Instance3>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 72,
1478		OpenTechCommitteeCollective:
1479			pallet_collective::<Instance4>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 73,
1480
1481		// Treasury stuff.
1482		Treasury: pallet_treasury::{Pallet, Storage, Config<T>, Event<T>, Call} = 80,
1483
1484		// Crowdloan stuff.
1485		CrowdloanRewards: pallet_crowdloan_rewards::{Pallet, Call, Storage, Event<T>} = 90,
1486
1487		// XCM
1488		XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Storage, Event<T>} = 100,
1489		CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 101,
1490		// Previously 102: DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>}
1491		PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event<T>, Origin, Config<T>} = 103,
1492		// [Removed] Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 104,
1493		// Previously 105: AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event<T>}
1494		// Previously 106: XTokens
1495		XcmTransactor: pallet_xcm_transactor::{Pallet, Call, Storage, Event<T>} = 107,
1496		// Previously 108: pallet_assets::<Instance1>
1497		EthereumXcm: pallet_ethereum_xcm::{Pallet, Call, Storage, Origin, Event<T>} = 109,
1498		Erc20XcmBridge: pallet_erc20_xcm_bridge::{Pallet} = 110,
1499		MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 111,
1500		EvmForeignAssets: pallet_moonbeam_foreign_assets::{Pallet, Call, Storage, Event<T>, Config<T>} = 114,
1501		XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>, Config<T>} = 115,
1502		EmergencyParaXcm: pallet_emergency_para_xcm::{Pallet, Call, Storage, Event} = 116,
1503		MultiBlockMigrations: pallet_migrations = 117,
1504		WeightReclaim: cumulus_pallet_weight_reclaim = 118,
1505
1506		// Utils
1507		RelayStorageRoots: pallet_relay_storage_roots::{Pallet, Storage} = 112,
1508
1509		#[cfg(feature = "runtime-benchmarks")]
1510		PrecompileBenchmarks: pallet_precompile_benchmarks::{Pallet} = 113,
1511
1512		// Randomness
1513		Randomness: pallet_randomness::{Pallet, Call, Storage, Event<T>, Inherent} = 120,
1514
1515		// Bridge pallets (reserved indexes from 130 to 140)
1516		BridgeKusamaGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 130,
1517		BridgeKusamaParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 131,
1518		BridgeKusamaMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 132,
1519		BridgeXcmOverMoonriver: pallet_xcm_bridge::<Instance1>::{Pallet, Call, Storage, Event<T>, HoldReason, Config<T>} = 133,
1520	}
1521}
1522
1523bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
1524	RuntimeCall, AccountId,
1525	// Grandpa
1526	BridgeKusamaGrandpa,
1527	// Parachains
1528	BridgeKusamaParachains,
1529	// Messages
1530	BridgeKusamaMessages
1531}
1532
1533#[cfg(feature = "runtime-benchmarks")]
1534use moonbeam_runtime_common::benchmarking::BenchmarkHelper;
1535#[cfg(feature = "runtime-benchmarks")]
1536mod benches {
1537	frame_support::parameter_types! {
1538		pub const MaxBalance: crate::Balance = crate::Balance::max_value();
1539	}
1540
1541	frame_benchmarking::define_benchmarks!(
1542		[frame_system, SystemBench::<Runtime>]
1543		[frame_system_extensions, frame_system_benchmarking::extensions::Pallet::<Runtime>]
1544		[pallet_utility, Utility]
1545		[pallet_timestamp, Timestamp]
1546		[pallet_balances, Balances]
1547		[pallet_evm, EVM]
1548		[pallet_parachain_staking, ParachainStaking]
1549		[pallet_scheduler, Scheduler]
1550		[pallet_treasury, Treasury]
1551		[pallet_author_inherent, AuthorInherent]
1552		[pallet_author_slot_filter, AuthorFilter]
1553		[pallet_crowdloan_rewards, CrowdloanRewards]
1554		[pallet_author_mapping, AuthorMapping]
1555		[pallet_proxy, Proxy]
1556		[pallet_transaction_payment, TransactionPaymentBenchmark::<Runtime>]
1557		[pallet_identity, Identity]
1558		[cumulus_pallet_parachain_system, ParachainSystem]
1559		[cumulus_pallet_xcmp_queue, XcmpQueue]
1560		[pallet_message_queue, MessageQueue]
1561		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
1562		[pallet_xcm_transactor, XcmTransactor]
1563		[pallet_moonbeam_foreign_assets, EvmForeignAssets]
1564		[pallet_moonbeam_orbiters, MoonbeamOrbiters]
1565		[pallet_randomness, Randomness]
1566		[pallet_conviction_voting, ConvictionVoting]
1567		[pallet_referenda, Referenda]
1568		[pallet_preimage, Preimage]
1569		[pallet_whitelist, Whitelist]
1570		[pallet_multisig, Multisig]
1571		[pallet_migrations, MultiBlockMigrations]
1572		// Currently there are no extrinsics to benchmark for the Lazy Migrations pallet
1573		// [pallet_moonbeam_lazy_migrations, MoonbeamLazyMigrations]
1574		[pallet_relay_storage_roots, RelayStorageRoots]
1575		[pallet_precompile_benchmarks, PrecompileBenchmarks]
1576		[pallet_parameters, Parameters]
1577		[pallet_xcm_weight_trader, XcmWeightTrader]
1578		[pallet_collective, TreasuryCouncilCollective]
1579		[pallet_collective, OpenTechCommitteeCollective]
1580		[pallet_bridge_grandpa, BridgeKusamaGrandpa]
1581		[pallet_bridge_parachains, pallet_bridge_parachains::benchmarking::Pallet::<Runtime, bridge_config::BridgeMoonriverInstance>]
1582		[pallet_bridge_messages, pallet_bridge_messages::benchmarking::Pallet::<Runtime, bridge_config::WithKusamaMessagesInstance>]
1583		[cumulus_pallet_weight_reclaim, WeightReclaim]
1584		[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet<Runtime>]
1585		[pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet<Runtime>]
1586	);
1587}
1588
1589/// Block type as expected by this runtime.
1590pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1591/// A Block signed with a Justification
1592pub type SignedBlock = generic::SignedBlock<Block>;
1593/// BlockId type as expected by this runtime.
1594pub type BlockId = generic::BlockId<Block>;
1595
1596/// The TransactionExtension to the basic transaction logic.
1597pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
1598	Runtime,
1599	(
1600		frame_system::CheckNonZeroSender<Runtime>,
1601		frame_system::CheckSpecVersion<Runtime>,
1602		frame_system::CheckTxVersion<Runtime>,
1603		frame_system::CheckGenesis<Runtime>,
1604		frame_system::CheckEra<Runtime>,
1605		frame_system::CheckNonce<Runtime>,
1606		frame_system::CheckWeight<Runtime>,
1607		pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1608		BridgeRejectObsoleteHeadersAndMessages,
1609		frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
1610	),
1611>;
1612/// Unchecked extrinsic type as expected by this runtime.
1613pub type UncheckedExtrinsic =
1614	fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
1615/// Extrinsic type that has already been checked.
1616pub type CheckedExtrinsic =
1617	fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension, H160>;
1618/// Executive: handles dispatch to the various pallets.
1619pub type Executive = frame_executive::Executive<
1620	Runtime,
1621	Block,
1622	frame_system::ChainContext<Runtime>,
1623	Runtime,
1624	AllPalletsWithSystem,
1625>;
1626
1627// All of our runtimes share most of their Runtime API implementations.
1628// We use a macro to implement this common part and add runtime-specific additional implementations.
1629// This macro expands to :
1630// ```
1631// impl_runtime_apis! {
1632//     // All impl blocks shared between all runtimes.
1633//
1634//     // Specific impls provided to the `impl_runtime_apis_plus_common!` macro.
1635// }
1636// ```
1637moonbeam_runtime_common::impl_runtime_apis_plus_common!(
1638	{
1639		impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1640			fn validate_transaction(
1641				source: TransactionSource,
1642				xt: <Block as BlockT>::Extrinsic,
1643				block_hash: <Block as BlockT>::Hash,
1644			) -> TransactionValidity {
1645				// Filtered calls should not enter the tx pool as they'll fail if inserted.
1646				// If this call is not allowed, we return early.
1647				if !<Runtime as frame_system::Config>::BaseCallFilter::contains(&xt.0.function) {
1648					return InvalidTransaction::Call.into();
1649				}
1650
1651				// This runtime uses Substrate's pallet transaction payment. This
1652				// makes the chain feel like a standard Substrate chain when submitting
1653				// frame transactions and using Substrate ecosystem tools. It has the downside that
1654				// transaction are not prioritized by gas_price. The following code reprioritizes
1655				// transactions to overcome this.
1656				//
1657				// A more elegant, ethereum-first solution is
1658				// a pallet that replaces pallet transaction payment, and allows users
1659				// to directly specify a gas price rather than computing an effective one.
1660				// #HopefullySomeday
1661
1662				// First we pass the transactions to the standard FRAME executive. This calculates all the
1663				// necessary tags, longevity and other properties that we will leave unchanged.
1664				// This also assigns some priority that we don't care about and will overwrite next.
1665				let mut intermediate_valid = Executive::validate_transaction(source, xt.clone(), block_hash)?;
1666
1667				let dispatch_info = xt.get_dispatch_info();
1668
1669				// If this is a pallet ethereum transaction, then its priority is already set
1670				// according to gas price from pallet ethereum. If it is any other kind of transaction,
1671				// we modify its priority.
1672				Ok(match &xt.0.function {
1673					RuntimeCall::Ethereum(transact { .. }) => intermediate_valid,
1674					_ if dispatch_info.class != DispatchClass::Normal => intermediate_valid,
1675					_ => {
1676						let tip = match &xt.0.preamble {
1677							Preamble::Bare(_) => 0,
1678							Preamble::Signed(_, _, signed_extra) => {
1679								// Yuck, this depends on the index of ChargeTransactionPayment in TxExtension
1680								// Get the 7th item from the tuple
1681								let charge_transaction_payment = &signed_extra.0.7;
1682								charge_transaction_payment.tip()
1683							},
1684							Preamble::General(_, _) => 0,
1685						};
1686
1687						// Calculate the fee that will be taken by pallet transaction payment
1688						let fee: u64 = TransactionPayment::compute_fee(
1689							xt.encode().len() as u32,
1690							&dispatch_info,
1691							tip,
1692						).saturated_into();
1693
1694						// Calculate how much gas this effectively uses according to the existing mapping
1695						let effective_gas =
1696							<Runtime as pallet_evm::Config>::GasWeightMapping::weight_to_gas(
1697								dispatch_info.total_weight()
1698							);
1699
1700						// Here we calculate an ethereum-style effective gas price using the
1701						// current fee of the transaction. Because the weight -> gas conversion is
1702						// lossy, we have to handle the case where a very low weight maps to zero gas.
1703						let effective_gas_price = if effective_gas > 0 {
1704							fee / effective_gas
1705						} else {
1706							// If the effective gas was zero, we just act like it was 1.
1707							fee
1708						};
1709
1710						// Overwrite the original prioritization with this ethereum one
1711						intermediate_valid.priority = effective_gas_price;
1712						intermediate_valid
1713					}
1714				})
1715			}
1716		}
1717
1718		impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
1719			fn can_build_upon(
1720				included_hash: <Block as BlockT>::Hash,
1721				slot: async_backing_primitives::Slot,
1722			) -> bool {
1723				ConsensusHook::can_build_upon(included_hash, slot)
1724			}
1725		}
1726
1727		impl bp_kusama::KusamaFinalityApi<Block> for Runtime {
1728			fn best_finalized() -> Option<bp_runtime::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumber>> {
1729				BridgeKusamaGrandpa::best_finalized()
1730			}
1731			fn free_headers_interval() -> Option<bp_kusama::BlockNumber> {
1732				<Runtime as pallet_bridge_grandpa::Config<
1733					bridge_config::BridgeGrandpaKusamaInstance
1734				>>::FreeHeadersInterval::get()
1735			}
1736			fn synced_headers_grandpa_info(
1737			) -> Vec<bp_header_chain::StoredHeaderGrandpaInfo<bp_kusama::Header>> {
1738				BridgeKusamaGrandpa::synced_headers_grandpa_info()
1739			}
1740		}
1741
1742		impl bp_moonriver::MoonriverKusamaFinalityApi<Block> for Runtime {
1743			fn best_finalized() -> Option<bp_runtime::HeaderId<bp_moonriver::Hash, bp_moonriver::BlockNumber>> {
1744				BridgeKusamaParachains::best_parachain_head_id::<
1745					bp_moonriver::Moonriver
1746				>().unwrap_or(None)
1747			}
1748			fn free_headers_interval() -> Option<bp_moonriver::BlockNumber> {
1749				// "free interval" is not currently used for parachains
1750				None
1751			}
1752		}
1753
1754		impl bp_moonriver::ToMoonriverKusamaOutboundLaneApi<Block> for Runtime {
1755			fn message_details(
1756				lane: bp_moonriver::LaneId,
1757				begin: bp_messages::MessageNonce,
1758				end: bp_messages::MessageNonce,
1759			) -> Vec<bp_messages::OutboundMessageDetails> {
1760				bridge_runtime_common::messages_api::outbound_message_details::<
1761					Runtime,
1762					bridge_config::WithKusamaMessagesInstance,
1763				>(lane, begin, end)
1764			}
1765		}
1766
1767		impl bp_moonriver::FromMoonriverKusamaInboundLaneApi<Block> for Runtime {
1768			fn message_details(
1769				lane: bp_moonriver::LaneId,
1770				messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>,
1771			) -> Vec<bp_messages::InboundMessageDetails> {
1772				bridge_runtime_common::messages_api::inbound_message_details::<
1773					Runtime,
1774					bridge_config::WithKusamaMessagesInstance,
1775				>(lane, messages)
1776			}
1777		}
1778	}
1779
1780	// Benchmark customizations
1781	{
1782		impl pallet_bridge_parachains::benchmarking::Config<bridge_config::BridgeMoonriverInstance> for Runtime {
1783			fn parachains() -> Vec<bp_polkadot_core::parachains::ParaId> {
1784				use bp_runtime::Parachain;
1785				vec![bp_polkadot_core::parachains::ParaId(bp_moonriver::Moonriver::PARACHAIN_ID)]
1786			}
1787
1788			fn prepare_parachain_heads_proof(
1789				parachains: &[bp_polkadot_core::parachains::ParaId],
1790				parachain_head_size: u32,
1791				proof_params: bp_runtime::UnverifiedStorageProofParams,
1792			) -> (
1793				bp_parachains::RelayBlockNumber,
1794				bp_parachains::RelayBlockHash,
1795				bp_polkadot_core::parachains::ParaHeadsProof,
1796				Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>,
1797			) {
1798				bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof::<Runtime, bridge_config::BridgeMoonriverInstance>(
1799					parachains,
1800					parachain_head_size,
1801					proof_params,
1802				)
1803			}
1804		}
1805
1806		use bridge_runtime_common::messages_benchmarking::{
1807			generate_xcm_builder_bridge_message_sample, prepare_message_delivery_proof_from_parachain,
1808			prepare_message_proof_from_parachain,
1809		};
1810		use pallet_bridge_messages::benchmarking::{
1811			Config as BridgeMessagesConfig, MessageDeliveryProofParams, MessageProofParams,
1812		};
1813
1814		impl BridgeMessagesConfig<bridge_config::WithKusamaMessagesInstance> for Runtime {
1815			fn is_relayer_rewarded(_relayer: &Self::AccountId) -> bool {
1816				// Currently, we do not reward relayers
1817				true
1818			}
1819
1820			fn prepare_message_proof(
1821				params: MessageProofParams<
1822					pallet_bridge_messages::LaneIdOf<Runtime, bridge_config::WithKusamaMessagesInstance>,
1823				>,
1824			) -> (
1825				bridge_config::benchmarking::FromMoonriverMessagesProof<
1826					bridge_config::WithKusamaMessagesInstance,
1827				>,
1828				Weight,
1829			) {
1830				use cumulus_primitives_core::XcmpMessageSource;
1831				assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty());
1832				ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into());
1833				PolkadotXcm::force_xcm_version(
1834					RuntimeOrigin::root(),
1835					Box::new(Location::new(1, Parachain(42))),
1836					cumulus_primitives_core::XCM_VERSION,
1837				)
1838				.map_err(|e| {
1839					log::error!(
1840						"Failed to dispatch `force_xcm_version({:?}, {:?}, {:?})`, error: {:?}",
1841						RuntimeOrigin::root(),
1842						Location::new(1, Parachain(42)),
1843						cumulus_primitives_core::XCM_VERSION,
1844						e
1845					);
1846				})
1847				.expect("XcmVersion stored!");
1848				let universal_source = bridge_config::benchmarking::open_bridge_for_benchmarks::<
1849					Runtime,
1850					bridge_config::XcmOverKusamaInstance,
1851					xcm_config::LocationToAccountId,
1852				>(params.lane, 42);
1853				prepare_message_proof_from_parachain::<
1854					Runtime,
1855					bridge_config::BridgeGrandpaKusamaInstance,
1856					bridge_config::WithKusamaMessagesInstance,
1857				>(params, generate_xcm_builder_bridge_message_sample(universal_source))
1858			}
1859
1860			fn prepare_message_delivery_proof(
1861				params: MessageDeliveryProofParams<
1862					AccountId,
1863					pallet_bridge_messages::LaneIdOf<Runtime, bridge_config::WithKusamaMessagesInstance>,
1864				>,
1865			) -> bridge_config::benchmarking::ToMoonriverMessagesDeliveryProof<
1866				bridge_config::WithKusamaMessagesInstance,
1867			> {
1868				let _ = bridge_config::benchmarking::open_bridge_for_benchmarks::<
1869					Runtime,
1870					bridge_config::XcmOverKusamaInstance,
1871					xcm_config::LocationToAccountId,
1872				>(params.lane, 42);
1873				prepare_message_delivery_proof_from_parachain::<
1874					Runtime,
1875					bridge_config::BridgeGrandpaKusamaInstance,
1876					bridge_config::WithKusamaMessagesInstance,
1877				>(params)
1878			}
1879
1880			fn is_message_successfully_dispatched(_nonce: bp_messages::MessageNonce) -> bool {
1881				// The message is not routed from Bridge Hub
1882				true
1883			}
1884		}
1885	}
1886);
1887
1888// Nimbus's Executive wrapper allows relay validators to verify the seal digest
1889cumulus_pallet_parachain_system::register_validate_block!(
1890	Runtime = Runtime,
1891	BlockExecutor = pallet_author_inherent::BlockExecutor::<Runtime, Executive>,
1892);
1893
1894moonbeam_runtime_common::impl_self_contained_call!();
1895
1896// Shorthand for a Get field of a pallet Config.
1897#[macro_export]
1898macro_rules! get {
1899	($pallet:ident, $name:ident, $type:ty) => {
1900		<<$crate::Runtime as $pallet::Config>::$name as $crate::Get<$type>>::get()
1901	};
1902}
1903
1904#[cfg(test)]
1905mod tests {
1906	use super::{currency::*, *};
1907
1908	#[test]
1909	// Helps us to identify a Pallet Call in case it exceeds the 1kb limit.
1910	// Hint: this should be a rare case. If that happens, one or more of the dispatchable arguments
1911	// need to be Boxed.
1912	fn call_max_size() {
1913		const CALL_ALIGN: u32 = 1024;
1914		assert!(std::mem::size_of::<pallet_evm_chain_id::Call<Runtime>>() <= CALL_ALIGN as usize);
1915		assert!(std::mem::size_of::<pallet_evm::Call<Runtime>>() <= CALL_ALIGN as usize);
1916		assert!(std::mem::size_of::<pallet_ethereum::Call<Runtime>>() <= CALL_ALIGN as usize);
1917		assert!(
1918			std::mem::size_of::<pallet_parachain_staking::Call<Runtime>>() <= CALL_ALIGN as usize
1919		);
1920		assert!(
1921			std::mem::size_of::<pallet_author_inherent::Call<Runtime>>() <= CALL_ALIGN as usize
1922		);
1923		assert!(
1924			std::mem::size_of::<pallet_author_slot_filter::Call<Runtime>>() <= CALL_ALIGN as usize
1925		);
1926		assert!(
1927			std::mem::size_of::<pallet_crowdloan_rewards::Call<Runtime>>() <= CALL_ALIGN as usize
1928		);
1929		assert!(std::mem::size_of::<pallet_author_mapping::Call<Runtime>>() <= CALL_ALIGN as usize);
1930		assert!(
1931			std::mem::size_of::<pallet_maintenance_mode::Call<Runtime>>() <= CALL_ALIGN as usize
1932		);
1933		assert!(std::mem::size_of::<pallet_migrations::Call<Runtime>>() <= CALL_ALIGN as usize);
1934		assert!(
1935			std::mem::size_of::<pallet_moonbeam_lazy_migrations::Call<Runtime>>()
1936				<= CALL_ALIGN as usize
1937		);
1938		assert!(
1939			std::mem::size_of::<pallet_proxy_genesis_companion::Call<Runtime>>()
1940				<= CALL_ALIGN as usize
1941		);
1942	}
1943
1944	#[test]
1945	fn currency_constants_are_correct() {
1946		assert_eq!(SUPPLY_FACTOR, 100);
1947
1948		// txn fees
1949		assert_eq!(TRANSACTION_BYTE_FEE, Balance::from(100 * GIGAWEI));
1950		assert_eq!(
1951			get!(pallet_transaction_payment, OperationalFeeMultiplier, u8),
1952			5_u8
1953		);
1954		assert_eq!(STORAGE_BYTE_FEE, Balance::from(10 * MILLIGLMR));
1955
1956		// pallet_identity deposits
1957		assert_eq!(
1958			get!(pallet_identity, BasicDeposit, u128),
1959			Balance::from(10 * GLMR + 2580 * MILLIGLMR)
1960		);
1961		assert_eq!(
1962			get!(pallet_identity, ByteDeposit, u128),
1963			Balance::from(10 * MILLIGLMR)
1964		);
1965		assert_eq!(
1966			get!(pallet_identity, SubAccountDeposit, u128),
1967			Balance::from(10 * GLMR + 530 * MILLIGLMR)
1968		);
1969
1970		// staking minimums
1971		assert_eq!(
1972			get!(pallet_parachain_staking, MinCandidateStk, u128),
1973			Balance::from(100_000 * GLMR)
1974		);
1975		assert_eq!(
1976			get!(pallet_parachain_staking, MinDelegation, u128),
1977			Balance::from(50 * GLMR)
1978		);
1979
1980		// crowdloan min reward
1981		assert_eq!(
1982			get!(pallet_crowdloan_rewards, MinimumReward, u128),
1983			Balance::from(0u128)
1984		);
1985
1986		// deposit for AuthorMapping
1987		assert_eq!(
1988			get!(pallet_author_mapping, DepositAmount, u128),
1989			Balance::from(10 * KILOGLMR)
1990		);
1991
1992		// proxy deposits
1993		assert_eq!(
1994			get!(pallet_proxy, ProxyDepositBase, u128),
1995			Balance::from(10 * GLMR + 80 * MILLIGLMR)
1996		);
1997		assert_eq!(
1998			get!(pallet_proxy, ProxyDepositFactor, u128),
1999			Balance::from(210 * MILLIGLMR)
2000		);
2001		assert_eq!(
2002			get!(pallet_proxy, AnnouncementDepositBase, u128),
2003			Balance::from(10 * GLMR + 80 * MILLIGLMR)
2004		);
2005		assert_eq!(
2006			get!(pallet_proxy, AnnouncementDepositFactor, u128),
2007			Balance::from(560 * MILLIGLMR)
2008		);
2009	}
2010
2011	#[test]
2012	fn max_offline_rounds_lower_or_eq_than_reward_payment_delay() {
2013		assert!(
2014			get!(pallet_parachain_staking, MaxOfflineRounds, u32)
2015				<= get!(pallet_parachain_staking, RewardPaymentDelay, u32)
2016		);
2017	}
2018
2019	#[test]
2020	// Required migration is
2021	// pallet_parachain_staking::migrations::IncreaseMaxTopDelegationsPerCandidate
2022	// Purpose of this test is to remind of required migration if constant is ever changed
2023	fn updating_maximum_delegators_per_candidate_requires_configuring_required_migration() {
2024		assert_eq!(
2025			get!(pallet_parachain_staking, MaxTopDelegationsPerCandidate, u32),
2026			300
2027		);
2028		assert_eq!(
2029			get!(
2030				pallet_parachain_staking,
2031				MaxBottomDelegationsPerCandidate,
2032				u32
2033			),
2034			50
2035		);
2036	}
2037
2038	#[test]
2039	fn configured_base_extrinsic_weight_is_evm_compatible() {
2040		let min_ethereum_transaction_weight = WeightPerGas::get() * 21_000;
2041		let base_extrinsic = <Runtime as frame_system::Config>::BlockWeights::get()
2042			.get(frame_support::dispatch::DispatchClass::Normal)
2043			.base_extrinsic;
2044		assert!(base_extrinsic.ref_time() <= min_ethereum_transaction_weight.ref_time());
2045	}
2046
2047	#[test]
2048	fn test_storage_growth_ratio_is_correct() {
2049		// This is the highest amount of new storage that can be created in a block 160 KB
2050		let block_storage_limit = 160 * 1024;
2051		let expected_storage_growth_ratio = BlockGasLimit::get()
2052			.low_u64()
2053			.saturating_div(block_storage_limit);
2054		let actual_storage_growth_ratio =
2055			<Runtime as pallet_evm::Config>::GasLimitStorageGrowthRatio::get();
2056		assert_eq!(
2057			expected_storage_growth_ratio, actual_storage_growth_ratio,
2058			"Storage growth ratio is not correct"
2059		);
2060	}
2061}