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