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")]
29
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
30

            
31
extern crate alloc;
32
extern crate core;
33

            
34
use account::AccountId20;
35
use alloc::borrow::Cow;
36
use cumulus_pallet_parachain_system::{
37
	RelayChainStateProof, RelayStateProof, RelaychainDataProvider, ValidationData,
38
};
39
use fp_rpc::TransactionStatus;
40

            
41
// Re-export required by get! macro.
42
use bp_moonriver::bp_polkadot;
43
use cumulus_primitives_core::{relay_chain, AggregateMessageOrigin};
44
#[cfg(feature = "std")]
45
pub use fp_evm::GenesisAccount;
46
pub use frame_support::traits::Get;
47
use 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,
58
	},
59
	weights::{
60
		constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient,
61
		WeightToFeeCoefficients, WeightToFeePolynomial,
62
	},
63
	PalletId,
64
};
65
use frame_system::{EnsureRoot, EnsureSigned};
66
pub use moonbeam_core_primitives::{
67
	AccountId, AccountIndex, Address, AssetId, Balance, BlockNumber, DigestItem, Hash, Header,
68
	Index, Signature,
69
};
70
use moonbeam_rpc_primitives_txpool::TxPoolResponse;
71
use moonbeam_runtime_common::impl_asset_conversion::AssetRateConverter;
72
use moonbeam_runtime_common::{
73
	deal_with_fees::{
74
		DealWithEthereumBaseFees, DealWithEthereumPriorityFees, DealWithSubstrateFeesAndTip,
75
	},
76
	impl_multiasset_paymaster::MultiAssetPaymaster,
77
};
78
pub use pallet_author_slot_filter::EligibilityValue;
79
use pallet_ethereum::Call::transact;
80
use pallet_ethereum::{PostLogContent, Transaction as EthereumTransaction};
81
use pallet_evm::{
82
	Account as EVMAccount, EVMFungibleAdapter, EnsureAddressNever, EnsureAddressRoot,
83
	FeeCalculator, FrameSystemAccountProvider, GasWeightMapping, IdentityAddressMapping,
84
	OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
85
};
86
pub use pallet_parachain_staking::{weights::WeightInfo, InflationInfo, Range};
87
use pallet_transaction_payment::{FungibleAdapter, Multiplier, TargetedFeeAdjustment};
88
use parity_scale_codec as codec;
89
use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
90
use scale_info::TypeInfo;
91
use sp_api::impl_runtime_apis;
92
use sp_consensus_slots::Slot;
93
use sp_core::{OpaqueMetadata, H160, H256, U256};
94
use sp_runtime::generic::Preamble;
95
use 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
};
108
use sp_std::{convert::TryFrom, prelude::*};
109
use xcm::{
110
	Version as XcmVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
111
};
112
use xcm_runtime_apis::{
113
	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
114
	fees::Error as XcmPaymentApiError,
115
};
116

            
117
use runtime_params::*;
118

            
119
use smallvec::smallvec;
120
#[cfg(feature = "std")]
121
use sp_version::NativeVersion;
122
use sp_version::RuntimeVersion;
123

            
124
use nimbus_primitives::CanAuthor;
125

            
126
pub use precompiles::{
127
	MoonriverPrecompiles, PrecompileName, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
128
};
129

            
130
#[cfg(any(feature = "std", test))]
131
pub use sp_runtime::BuildStorage;
132

            
133
pub type Precompiles = MoonriverPrecompiles<Runtime>;
134

            
135
pub mod asset_config;
136
pub mod bridge_config;
137
#[cfg(not(feature = "disable-genesis-builder"))]
138
pub mod genesis_config_preset;
139
pub mod governance;
140
pub mod runtime_params;
141
pub mod xcm_config;
142

            
143
mod migrations;
144
mod precompiles;
145
mod weights;
146

            
147
pub(crate) use weights as moonriver_weights;
148
pub use weights::xcm as moonriver_xcm_weights;
149

            
150
pub use governance::councils::*;
151

            
152
/// MOVR, the native token, uses 18 decimals of precision.
153
pub 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
14
	pub const fn deposit(items: u32, bytes: u32) -> Balance {
173
14
		items as Balance * 1 * MOVR * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
174
14
	}
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
180
pub const MAX_POV_SIZE: u32 = 10 * 1024 * 1024;
181

            
182
/// Maximum weight per block
183
pub 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

            
188
pub const MILLISECS_PER_BLOCK: u64 = 6_000;
189
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
190
pub const HOURS: BlockNumber = MINUTES * 60;
191
pub const DAYS: BlockNumber = HOURS * 24;
192
pub 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.
197
pub 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]
216
pub const VERSION: RuntimeVersion = RuntimeVersion {
217
	spec_name: Cow::Borrowed("moonriver"),
218
	impl_name: Cow::Borrowed("moonriver"),
219
	authoring_version: 3,
220
	spec_version: 4000,
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")]
229
pub fn native_version() -> NativeVersion {
230
	NativeVersion {
231
		runtime_version: VERSION,
232
		can_author_with: Default::default(),
233
	}
234
}
235

            
236
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
237
pub 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
242
pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
243

            
244
pub struct RuntimeBlockWeights;
245
impl Get<frame_system::limits::BlockWeights> for RuntimeBlockWeights {
246
421878
	fn get() -> frame_system::limits::BlockWeights {
247
421878
		frame_system::limits::BlockWeights::builder()
248
421878
			.for_class(DispatchClass::Normal, |weights| {
249
421878
				weights.base_extrinsic = EXTRINSIC_BASE_WEIGHT;
250
421878
				weights.max_total = NORMAL_WEIGHT.into();
251
421878
			})
252
421878
			.for_class(DispatchClass::Operational, |weights| {
253
421878
				weights.max_total = MAXIMUM_BLOCK_WEIGHT.into();
254
421878
				weights.reserved = (MAXIMUM_BLOCK_WEIGHT - NORMAL_WEIGHT).into();
255
421878
			})
256
421878
			.avg_block_initialization(Perbill::from_percent(10))
257
421878
			.build()
258
421878
			.expect("Provided BlockWeight definitions are valid, qed")
259
421878
	}
260
}
261

            
262
parameter_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

            
269
impl 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

            
320
impl 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

            
327
impl 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"))]
336
parameter_types! {
337
	pub const ExistentialDeposit: Balance = 0;
338
}
339

            
340
#[cfg(feature = "runtime-benchmarks")]
341
parameter_types! {
342
	pub const ExistentialDeposit: Balance = 1;
343
}
344

            
345
impl 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 = ();
357
	type MaxFreezes = ConstU32<0>;
358
	type RuntimeHoldReason = RuntimeHoldReason;
359
	type RuntimeFreezeReason = RuntimeFreezeReason;
360
	type WeightInfo = moonriver_weights::pallet_balances::WeightInfo<Runtime>;
361
	type DoneSlashHandler = ();
362
}
363

            
364
pub struct LengthToFee;
365
impl WeightToFeePolynomial for LengthToFee {
366
	type Balance = Balance;
367

            
368
77
	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
369
77
		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
77
	}
384
}
385

            
386
impl 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

            
402
impl 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.
408
pub 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.
412
pub 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
417
pub const BLOCK_STORAGE_LIMIT: u64 = 160 * 1024;
418

            
419
parameter_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

            
451
pub struct TransactionPaymentAsGasPrice;
452
impl FeeCalculator for TransactionPaymentAsGasPrice {
453
644
	fn min_gas_price() -> (U256, Weight) {
454
644
		// note: transaction-payment differs from EIP-1559 in that its tip and length fees are not
455
644
		//       scaled by the multiplier, which means its multiplier will be overstated when
456
644
		//       applied to an ethereum transaction
457
644
		// note: transaction-payment uses both a congestion modifier (next_fee_multiplier, which is
458
644
		//       updated once per block in on_finalize) and a 'WeightToFee' implementation. Our
459
644
		//       runtime implements this as a 'ConstantModifier', so we can get away with a simple
460
644
		//       multiplication here.
461
644
		// It is imperative that `saturating_mul_int` be performed as late as possible in the
462
644
		// expression since it involves fixed point multiplication with a division by a fixed
463
644
		// divisor. This leads to truncation and subsequent precision loss if performed too early.
464
644
		// This can lead to min_gas_price being same across blocks even if the multiplier changes.
465
644
		// There's still some precision loss when the final `gas_price` (used_gas * min_gas_price)
466
644
		// is computed in frontier, but that's currently unavoidable.
467
644
		let min_gas_price = TransactionPayment::next_fee_multiplier()
468
644
			.saturating_mul_int((currency::WEIGHT_FEE).saturating_mul(WEIGHT_PER_GAS as u128));
469
644
		(
470
644
			min_gas_price.into(),
471
644
			<Runtime as frame_system::Config>::DbWeight::get().reads(1),
472
644
		)
473
644
	}
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
487
pub type SlowAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
488
	R,
489
	TargetBlockFullness,
490
	AdjustmentVariable,
491
	MinimumMultiplier,
492
	MaximumMultiplier,
493
>;
494

            
495
use 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.
501
pub struct FindAuthorAdapter<Inner>(sp_std::marker::PhantomData<Inner>);
502

            
503
impl<Inner> FindAuthor<H160> for FindAuthorAdapter<Inner>
504
where
505
	Inner: FindAuthor<AccountId20>,
506
{
507
374
	fn find_author<'a, I>(digests: I) -> Option<H160>
508
374
	where
509
374
		I: 'a + IntoIterator<Item = (sp_runtime::ConsensusEngineId, &'a [u8])>,
510
374
	{
511
374
		Inner::find_author(digests).map(Into::into)
512
374
	}
513
}
514

            
515
moonbeam_runtime_common::impl_on_charge_evm_transaction!();
516

            
517
impl 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 RuntimeEvent = RuntimeEvent;
527
	type Runner = pallet_evm::runner::stack::Runner<Self>;
528
	type PrecompilesType = MoonriverPrecompiles<Self>;
529
	type PrecompilesValue = PrecompilesValue;
530
	type ChainId = EthereumChainId;
531
	type OnChargeTransaction = OnChargeEVMTransaction<
532
		DealWithEthereumBaseFees<Runtime, dynamic_params::runtime_config::FeesTreasuryProportion>,
533
		DealWithEthereumPriorityFees<Runtime>,
534
	>;
535
	type BlockGasLimit = BlockGasLimit;
536
	type FindAuthor = FindAuthorAdapter<AuthorInherent>;
537
	type OnCreate = ();
538
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
539
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
540
	type Timestamp = Timestamp;
541
	type AccountProvider = FrameSystemAccountProvider<Runtime>;
542
	type WeightInfo = moonriver_weights::pallet_evm::WeightInfo<Runtime>;
543
	type CreateOriginFilter = ();
544
	type CreateInnerOriginFilter = ();
545
}
546

            
547
parameter_types! {
548
	pub MaxServiceWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
549
}
550

            
551
impl pallet_scheduler::Config for Runtime {
552
	type RuntimeEvent = RuntimeEvent;
553
	type RuntimeOrigin = RuntimeOrigin;
554
	type PalletsOrigin = OriginCaller;
555
	type RuntimeCall = RuntimeCall;
556
	type MaximumWeight = MaxServiceWeight;
557
	type ScheduleOrigin = EnsureRoot<AccountId>;
558
	type MaxScheduledPerBlock = ConstU32<50>;
559
	type WeightInfo = moonriver_weights::pallet_scheduler::WeightInfo<Runtime>;
560
	type OriginPrivilegeCmp = EqualPrivilegeOnly;
561
	type Preimages = Preimage;
562
	type BlockNumberProvider = System;
563
}
564

            
565
parameter_types! {
566
	pub const PreimageBaseDeposit: Balance = 5 * currency::MOVR * currency::SUPPLY_FACTOR ;
567
	pub const PreimageByteDeposit: Balance = currency::STORAGE_BYTE_FEE;
568
	pub const PreimageHoldReason: RuntimeHoldReason =
569
		RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
570
}
571

            
572
impl pallet_preimage::Config for Runtime {
573
	type WeightInfo = moonriver_weights::pallet_preimage::WeightInfo<Runtime>;
574
	type RuntimeEvent = RuntimeEvent;
575
	type Currency = Balances;
576
	type ManagerOrigin = EnsureRoot<AccountId>;
577
	type Consideration = HoldConsideration<
578
		AccountId,
579
		Balances,
580
		PreimageHoldReason,
581
		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
582
	>;
583
}
584

            
585
parameter_types! {
586
	pub const ProposalBond: Permill = Permill::from_percent(5);
587
	pub const TreasuryId: PalletId = PalletId(*b"py/trsry");
588
	pub TreasuryAccount: AccountId = Treasury::account_id();
589
	pub const MaxSpendBalance: crate::Balance = crate::Balance::max_value();
590
}
591

            
592
type RootOrTreasuryCouncilOrigin = EitherOfDiverse<
593
	EnsureRoot<AccountId>,
594
	pallet_collective::EnsureProportionMoreThan<AccountId, TreasuryCouncilInstance, 1, 2>,
595
>;
596

            
597
impl pallet_treasury::Config for Runtime {
598
	type PalletId = TreasuryId;
599
	type Currency = Balances;
600
	// More than half of the council is required (or root) to reject a proposal
601
	type RejectOrigin = RootOrTreasuryCouncilOrigin;
602
	type RuntimeEvent = RuntimeEvent;
603
	type SpendPeriod = ConstU32<{ 6 * DAYS }>;
604
	type Burn = ();
605
	type BurnDestination = ();
606
	type MaxApprovals = ConstU32<100>;
607
	type WeightInfo = moonriver_weights::pallet_treasury::WeightInfo<Runtime>;
608
	type SpendFunds = ();
609
	type SpendOrigin =
610
		frame_system::EnsureWithSuccess<RootOrTreasuryCouncilOrigin, AccountId, MaxSpendBalance>;
611
	type AssetKind = NativeOrWithId<AssetId>;
612
	type Beneficiary = AccountId;
613
	type BeneficiaryLookup = IdentityLookup<AccountId>;
614
	type Paymaster = MultiAssetPaymaster<Runtime, TreasuryAccount, Balances>;
615
	type BalanceConverter = AssetRateConverter<Runtime, Balances>;
616
	type PayoutPeriod = ConstU32<{ 30 * DAYS }>;
617
	#[cfg(feature = "runtime-benchmarks")]
618
	type BenchmarkHelper = BenchmarkHelper;
619
	type BlockNumberProvider = System;
620
}
621

            
622
parameter_types! {
623
	pub const MaxSubAccounts: u32 = 100;
624
	pub const MaxAdditionalFields: u32 = 100;
625
	pub const MaxRegistrars: u32 = 20;
626
	pub const PendingUsernameExpiration: u32 = 7 * DAYS;
627
	pub const MaxSuffixLength: u32 = 7;
628
	pub const MaxUsernameLength: u32 = 32;
629
}
630

            
631
type IdentityForceOrigin =
632
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
633
type IdentityRegistrarOrigin =
634
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
635

            
636
impl pallet_identity::Config for Runtime {
637
	type RuntimeEvent = RuntimeEvent;
638
	type Currency = Balances;
639
	// Add one item in storage and take 258 bytes
640
	type BasicDeposit = ConstU128<{ currency::deposit(1, 258) }>;
641
	// Does not add any item to the storage but takes 1 bytes
642
	type ByteDeposit = ConstU128<{ currency::deposit(0, 1) }>;
643
	// Add one item in storage and take 53 bytes
644
	type SubAccountDeposit = ConstU128<{ currency::deposit(1, 53) }>;
645
	type MaxSubAccounts = MaxSubAccounts;
646
	type IdentityInformation = pallet_identity::legacy::IdentityInfo<MaxAdditionalFields>;
647
	type MaxRegistrars = MaxRegistrars;
648
	type Slashed = Treasury;
649
	type ForceOrigin = IdentityForceOrigin;
650
	type RegistrarOrigin = IdentityRegistrarOrigin;
651
	type OffchainSignature = Signature;
652
	type SigningPublicKey = <Signature as sp_runtime::traits::Verify>::Signer;
653
	type UsernameAuthorityOrigin = EnsureRoot<AccountId>;
654
	type PendingUsernameExpiration = PendingUsernameExpiration;
655
	type MaxSuffixLength = MaxSuffixLength;
656
	type MaxUsernameLength = MaxUsernameLength;
657
	type WeightInfo = moonriver_weights::pallet_identity::WeightInfo<Runtime>;
658
	type UsernameDeposit = ConstU128<{ currency::deposit(0, MaxUsernameLength::get()) }>;
659
	type UsernameGracePeriod = ConstU32<{ 30 * DAYS }>;
660
}
661

            
662
pub struct TransactionConverter;
663

            
664
impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
665
21
	fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
666
21
		UncheckedExtrinsic::new_bare(
667
21
			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
668
21
		)
669
21
	}
670
}
671

            
672
impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
673
	fn convert_transaction(
674
		&self,
675
		transaction: pallet_ethereum::Transaction,
676
	) -> opaque::UncheckedExtrinsic {
677
		let extrinsic = UncheckedExtrinsic::new_bare(
678
			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
679
		);
680
		let encoded = extrinsic.encode();
681
		opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
682
			.expect("Encoded extrinsic is always valid")
683
	}
684
}
685

            
686
parameter_types! {
687
	pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
688
}
689

            
690
impl pallet_ethereum::Config for Runtime {
691
	type RuntimeEvent = RuntimeEvent;
692
	type StateRoot =
693
		pallet_ethereum::IntermediateStateRoot<<Runtime as frame_system::Config>::Version>;
694
	type PostLogContent = PostBlockAndTxnHashes;
695
	type ExtraDataLength = ConstU32<30>;
696
}
697

            
698
pub struct EthereumXcmEnsureProxy;
699
impl 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

            
715
impl pallet_ethereum_xcm::Config for Runtime {
716
	type RuntimeEvent = RuntimeEvent;
717
	type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
718
	type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
719
	type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
720
	type ReservedXcmpWeight = ReservedXcmpWeight;
721
	type EnsureProxy = EthereumXcmEnsureProxy;
722
	type ControllerOrigin = EnsureRoot<AccountId>;
723
	type ForceOrigin = EnsureRoot<AccountId>;
724
}
725

            
726
parameter_types! {
727
	// Reserved weight is 1/4 of MAXIMUM_BLOCK_WEIGHT
728
	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
729
	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
730
	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
731
}
732

            
733
/// Relay chain slot duration, in milliseconds.
734
const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
735
/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
736
/// into the relay chain.
737
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
738
/// How many parachain blocks are processed by the relay chain per parent. Limits the
739
/// number of blocks authored per slot.
740
const BLOCK_PROCESSING_VELOCITY: u32 = 1;
741

            
742
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
743
	Runtime,
744
	RELAY_CHAIN_SLOT_DURATION_MILLIS,
745
	BLOCK_PROCESSING_VELOCITY,
746
	UNINCLUDED_SEGMENT_CAPACITY,
747
>;
748

            
749
impl cumulus_pallet_parachain_system::Config for Runtime {
750
	type RuntimeEvent = RuntimeEvent;
751
	type OnSystemEvent = ();
752
	type SelfParaId = ParachainInfo;
753
	type ReservedDmpWeight = ReservedDmpWeight;
754
	type OutboundXcmpMessageSource = XcmpQueue;
755
	type XcmpMessageHandler = XcmpQueue;
756
	type ReservedXcmpWeight = ReservedXcmpWeight;
757
	type CheckAssociatedRelayNumber = EmergencyParaXcm;
758
	type ConsensusHook = ConsensusHook;
759
	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
760
	type WeightInfo = moonriver_weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
761
	type SelectCore = cumulus_pallet_parachain_system::DefaultCoreSelector<Runtime>;
762
}
763

            
764
impl parachain_info::Config for Runtime {}
765

            
766
pub struct OnNewRound;
767
impl pallet_parachain_staking::OnNewRound for OnNewRound {
768
35
	fn on_new_round(round_index: pallet_parachain_staking::RoundIndex) -> Weight {
769
35
		MoonbeamOrbiters::on_new_round(round_index)
770
35
	}
771
}
772
pub struct PayoutCollatorOrOrbiterReward;
773
impl pallet_parachain_staking::PayoutCollatorReward<Runtime> for PayoutCollatorOrOrbiterReward {
774
14
	fn payout_collator_reward(
775
14
		for_round: pallet_parachain_staking::RoundIndex,
776
14
		collator_id: AccountId,
777
14
		amount: Balance,
778
14
	) -> Weight {
779
14
		let extra_weight =
780
14
			if MoonbeamOrbiters::is_collator_pool_with_active_orbiter(for_round, collator_id) {
781
				MoonbeamOrbiters::distribute_rewards(for_round, collator_id, amount)
782
			} else {
783
14
				ParachainStaking::mint_collator_reward(for_round, collator_id, amount)
784
			};
785

            
786
14
		<Runtime as frame_system::Config>::DbWeight::get()
787
14
			.reads(1)
788
14
			.saturating_add(extra_weight)
789
14
	}
790
}
791

            
792
pub struct OnInactiveCollator;
793
impl pallet_parachain_staking::OnInactiveCollator<Runtime> for OnInactiveCollator {
794
	fn on_inactive_collator(
795
		collator_id: AccountId,
796
		round: pallet_parachain_staking::RoundIndex,
797
	) -> Result<Weight, DispatchErrorWithPostInfo<PostDispatchInfo>> {
798
		let extra_weight = if !MoonbeamOrbiters::is_collator_pool_with_active_orbiter(
799
			round,
800
			collator_id.clone(),
801
		) {
802
			ParachainStaking::go_offline_inner(collator_id)?;
803
			<Runtime as pallet_parachain_staking::Config>::WeightInfo::go_offline(
804
				pallet_parachain_staking::MAX_CANDIDATES,
805
			)
806
		} else {
807
			Weight::zero()
808
		};
809

            
810
		Ok(<Runtime as frame_system::Config>::DbWeight::get()
811
			.reads(1)
812
			.saturating_add(extra_weight))
813
	}
814
}
815

            
816
type MonetaryGovernanceOrigin =
817
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
818

            
819
pub struct RelayChainSlotProvider;
820
impl Get<Slot> for RelayChainSlotProvider {
821
35
	fn get() -> Slot {
822
35
		let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
823
35
		slot_info.unwrap_or_default().0
824
35
	}
825
}
826

            
827
impl pallet_parachain_staking::Config for Runtime {
828
	type RuntimeEvent = RuntimeEvent;
829
	type Currency = Balances;
830
	type MonetaryGovernanceOrigin = MonetaryGovernanceOrigin;
831
	/// Minimum round length is 2 minutes (10 * 12 second block times)
832
	type MinBlocksPerRound = ConstU32<10>;
833
	/// If a collator doesn't produce any block on this number of rounds, it is notified as inactive
834
	type MaxOfflineRounds = ConstU32<2>;
835
	/// Rounds before the collator leaving the candidates request can be executed
836
	type LeaveCandidatesDelay = ConstU32<24>;
837
	/// Rounds before the candidate bond increase/decrease can be executed
838
	type CandidateBondLessDelay = ConstU32<24>;
839
	/// Rounds before the delegator exit can be executed
840
	type LeaveDelegatorsDelay = ConstU32<24>;
841
	/// Rounds before the delegator revocation can be executed
842
	type RevokeDelegationDelay = ConstU32<24>;
843
	/// Rounds before the delegator bond increase/decrease can be executed
844
	type DelegationBondLessDelay = ConstU32<24>;
845
	/// Rounds before the reward is paid
846
	type RewardPaymentDelay = ConstU32<2>;
847
	/// Minimum collators selected per round, default at genesis and minimum forever after
848
	type MinSelectedCandidates = ConstU32<8>;
849
	/// Maximum top delegations per candidate
850
	type MaxTopDelegationsPerCandidate = ConstU32<300>;
851
	/// Maximum bottom delegations per candidate
852
	type MaxBottomDelegationsPerCandidate = ConstU32<50>;
853
	/// Maximum delegations per delegator
854
	type MaxDelegationsPerDelegator = ConstU32<100>;
855
	/// Minimum stake required to be reserved to be a candidate
856
	type MinCandidateStk = ConstU128<{ 500 * currency::MOVR * currency::SUPPLY_FACTOR }>;
857
	/// Minimum stake required to be reserved to be a delegator
858
	type MinDelegation = ConstU128<{ 5 * currency::MOVR * currency::SUPPLY_FACTOR }>;
859
	type BlockAuthor = AuthorInherent;
860
	type OnCollatorPayout = ();
861
	type PayoutCollatorReward = PayoutCollatorOrOrbiterReward;
862
	type OnInactiveCollator = OnInactiveCollator;
863
	type OnNewRound = OnNewRound;
864
	type SlotProvider = RelayChainSlotProvider;
865
	type WeightInfo = moonriver_weights::pallet_parachain_staking::WeightInfo<Runtime>;
866
	type MaxCandidates = ConstU32<200>;
867
	type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
868
	type BlockTime = ConstU64<MILLISECS_PER_BLOCK>;
869
	type LinearInflationThreshold = ();
870
}
871

            
872
impl pallet_author_inherent::Config for Runtime {
873
	type SlotBeacon = RelaychainDataProvider<Self>;
874
	type AccountLookup = MoonbeamOrbiters;
875
	type CanAuthor = AuthorFilter;
876
	type AuthorId = AccountId;
877
	type WeightInfo = moonriver_weights::pallet_author_inherent::WeightInfo<Runtime>;
878
}
879

            
880
impl pallet_author_slot_filter::Config for Runtime {
881
	type RuntimeEvent = RuntimeEvent;
882
	type RandomnessSource = Randomness;
883
	type PotentialAuthors = ParachainStaking;
884
	type WeightInfo = moonriver_weights::pallet_author_slot_filter::WeightInfo<Runtime>;
885
}
886

            
887
impl pallet_async_backing::Config for Runtime {
888
	type AllowMultipleBlocksPerSlot = ConstBool<true>;
889
	type GetAndVerifySlot = pallet_async_backing::RelaySlot;
890
	type SlotDuration = ConstU64<MILLISECS_PER_BLOCK>;
891
	type ExpectedBlockTime = ConstU64<MILLISECS_PER_BLOCK>;
892
}
893

            
894
parameter_types! {
895
	pub const InitializationPayment: Perbill = Perbill::from_percent(30);
896
	pub const RelaySignaturesThreshold: Perbill = Perbill::from_percent(100);
897
	pub const SignatureNetworkIdentifier:  &'static [u8] = b"moonriver-";
898

            
899
}
900

            
901
impl pallet_crowdloan_rewards::Config for Runtime {
902
	type RuntimeEvent = RuntimeEvent;
903
	type Initialized = ConstBool<false>;
904
	type InitializationPayment = InitializationPayment;
905
	type MaxInitContributors = ConstU32<500>;
906
	type MinimumReward = ConstU128<0>;
907
	type RewardCurrency = Balances;
908
	type RelayChainAccountId = [u8; 32];
909
	type RewardAddressAssociateOrigin = EnsureSigned<Self::AccountId>;
910
	type RewardAddressChangeOrigin = EnsureSigned<Self::AccountId>;
911
	type RewardAddressRelayVoteThreshold = RelaySignaturesThreshold;
912
	type SignatureNetworkIdentifier = SignatureNetworkIdentifier;
913
	type VestingBlockNumber = relay_chain::BlockNumber;
914
	type VestingBlockProvider = RelaychainDataProvider<Self>;
915
	type WeightInfo = moonriver_weights::pallet_crowdloan_rewards::WeightInfo<Runtime>;
916
}
917

            
918
// This is a simple session key manager. It should probably either work with, or be replaced
919
// entirely by pallet sessions
920
impl pallet_author_mapping::Config for Runtime {
921
	type RuntimeEvent = RuntimeEvent;
922
	type DepositCurrency = Balances;
923
	type DepositAmount = ConstU128<{ 100 * currency::MOVR * currency::SUPPLY_FACTOR }>;
924
	type Keys = session_keys_primitives::VrfId;
925
	type WeightInfo = moonriver_weights::pallet_author_mapping::WeightInfo<Runtime>;
926
}
927

            
928
/// The type used to represent the kinds of proxying allowed.
929
#[derive(
930
	Copy,
931
	Clone,
932
	Eq,
933
	PartialEq,
934
	Ord,
935
	PartialOrd,
936
	Encode,
937
	Decode,
938
	Debug,
939
	MaxEncodedLen,
940
56
	TypeInfo,
941
	Serialize,
942
	Deserialize,
943
	DecodeWithMemTracking,
944
)]
945
pub enum ProxyType {
946
	/// All calls can be proxied. This is the trivial/most permissive filter.
947
	Any = 0,
948
	/// Only extrinsics that do not transfer funds.
949
	NonTransfer = 1,
950
	/// Only extrinsics related to governance (democracy and collectives).
951
	Governance = 2,
952
	/// Only extrinsics related to staking.
953
	Staking = 3,
954
	/// Allow to veto an announced proxy call.
955
	CancelProxy = 4,
956
	/// Allow extrinsic related to Balances.
957
	Balances = 5,
958
	/// Allow extrinsic related to AuthorMapping.
959
	AuthorMapping = 6,
960
	/// Allow extrinsic related to IdentityJudgement.
961
	IdentityJudgement = 7,
962
}
963

            
964
impl Default for ProxyType {
965
	fn default() -> Self {
966
		Self::Any
967
	}
968
}
969

            
970
fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool {
971
	matches!(
972
		precompile_name,
973
		PrecompileName::TreasuryCouncilInstance
974
			| PrecompileName::PreimagePrecompile
975
			| PrecompileName::ReferendaPrecompile
976
			| PrecompileName::ConvictionVotingPrecompile
977
			| PrecompileName::OpenTechCommitteeInstance
978
	)
979
}
980

            
981
// Be careful: Each time this filter is modified, the substrate filter must also be modified
982
// consistently.
983
impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {
984
	fn is_evm_proxy_call_allowed(
985
		&self,
986
		call: &pallet_evm_precompile_proxy::EvmSubCall,
987
		recipient_has_code: bool,
988
		gas: u64,
989
	) -> precompile_utils::EvmResult<bool> {
990
		Ok(match self {
991
			ProxyType::Any => {
992
				match PrecompileName::from_address(call.to.0) {
993
					// Any precompile that can execute a subcall should be forbidden here,
994
					// to ensure that unauthorized smart contract can't be called
995
					// indirectly.
996
					// To be safe, we only allow the precompiles we need.
997
					Some(
998
						PrecompileName::AuthorMappingPrecompile
999
						| PrecompileName::ParachainStakingPrecompile,
					) => true,
					Some(ref precompile) if is_governance_precompile(precompile) => true,
					// All non-whitelisted precompiles are forbidden
					Some(_) => false,
					// Allow evm transfer to "simple" account (no code nor precompile)
					// For the moment, no smart contract other than precompiles is allowed.
					// In the future, we may create a dynamic whitelist to authorize some audited
					// smart contracts through governance.
					None => {
						// If the address is not recognized, allow only evm transfert to "simple"
						// accounts (no code nor precompile).
						// Note: Checking the presence of the code is not enough because some
						// precompiles have no code.
						!recipient_has_code
							&& !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
								call.to.0, gas,
							)?
					}
				}
			}
			ProxyType::NonTransfer => {
				call.value == U256::zero()
					&& match PrecompileName::from_address(call.to.0) {
						Some(
							PrecompileName::AuthorMappingPrecompile
							| PrecompileName::ParachainStakingPrecompile,
						) => true,
						Some(ref precompile) if is_governance_precompile(precompile) => true,
						_ => false,
					}
			}
			ProxyType::Governance => {
				call.value == U256::zero()
					&& matches!(
						PrecompileName::from_address(call.to.0),
						Some(ref precompile) if is_governance_precompile(precompile)
					)
			}
			ProxyType::Staking => {
				call.value == U256::zero()
					&& matches!(
						PrecompileName::from_address(call.to.0),
						Some(
							PrecompileName::AuthorMappingPrecompile
								| PrecompileName::ParachainStakingPrecompile
						)
					)
			}
			// The proxy precompile does not contain method cancel_proxy
			ProxyType::CancelProxy => false,
			ProxyType::Balances => {
				// Allow only "simple" accounts as recipient (no code nor precompile).
				// Note: Checking the presence of the code is not enough because some precompiles
				// have no code.
				!recipient_has_code
					&& !precompile_utils::precompile_set::is_precompile_or_fail::<Runtime>(
						call.to.0, gas,
					)?
			}
			ProxyType::AuthorMapping => {
				call.value == U256::zero()
					&& matches!(
						PrecompileName::from_address(call.to.0),
						Some(PrecompileName::AuthorMappingPrecompile)
					)
			}
			// There is no identity precompile
			ProxyType::IdentityJudgement => false,
		})
	}
}
// Be careful: Each time this filter is modified, the EVM filter must also be modified consistently.
impl InstanceFilter<RuntimeCall> for ProxyType {
	fn filter(&self, c: &RuntimeCall) -> bool {
		match self {
			ProxyType::Any => true,
			ProxyType::NonTransfer => match c {
				RuntimeCall::Identity(
					pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. },
				) => false,
				call => {
					matches!(
						call,
						RuntimeCall::System(..)
							| RuntimeCall::ParachainSystem(..)
							| RuntimeCall::Timestamp(..)
							| RuntimeCall::ParachainStaking(..)
							| RuntimeCall::Referenda(..)
							| RuntimeCall::Preimage(..)
							| RuntimeCall::ConvictionVoting(..)
							| RuntimeCall::TreasuryCouncilCollective(..)
							| RuntimeCall::OpenTechCommitteeCollective(..)
							| RuntimeCall::Utility(..)
							| RuntimeCall::Proxy(..)
							| RuntimeCall::Identity(..)
							| RuntimeCall::AuthorMapping(..)
							| RuntimeCall::CrowdloanRewards(
								pallet_crowdloan_rewards::Call::claim { .. }
							)
					)
				}
			},
			ProxyType::Governance => matches!(
				c,
				RuntimeCall::Referenda(..)
					| RuntimeCall::Preimage(..)
					| RuntimeCall::ConvictionVoting(..)
					| RuntimeCall::TreasuryCouncilCollective(..)
					| RuntimeCall::OpenTechCommitteeCollective(..)
					| RuntimeCall::Utility(..)
			),
			ProxyType::Staking => matches!(
				c,
				RuntimeCall::ParachainStaking(..)
					| RuntimeCall::Utility(..)
					| RuntimeCall::AuthorMapping(..)
					| RuntimeCall::MoonbeamOrbiters(..)
			),
			ProxyType::CancelProxy => matches!(
				c,
				RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
			),
			ProxyType::Balances => {
				matches!(c, RuntimeCall::Balances(..) | RuntimeCall::Utility(..))
			}
			ProxyType::AuthorMapping => matches!(c, RuntimeCall::AuthorMapping(..)),
			ProxyType::IdentityJudgement => matches!(
				c,
				RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. })
					| RuntimeCall::Utility(..)
			),
		}
	}
	fn is_superset(&self, o: &Self) -> bool {
		match (self, o) {
			(x, y) if x == y => true,
			(ProxyType::Any, _) => true,
			(_, ProxyType::Any) => false,
			_ => false,
		}
	}
}
impl pallet_proxy::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type Currency = Balances;
	type ProxyType = ProxyType;
	// One storage item; key size 32, value size 8
	type ProxyDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
	// Additional storage item size of 21 bytes (20 bytes AccountId + 1 byte sizeof(ProxyType)).
	type ProxyDepositFactor = ConstU128<{ currency::deposit(0, 21) }>;
	type MaxProxies = ConstU32<32>;
	type WeightInfo = moonriver_weights::pallet_proxy::WeightInfo<Runtime>;
	type MaxPending = ConstU32<32>;
	type CallHasher = BlakeTwo256;
	type AnnouncementDepositBase = ConstU128<{ currency::deposit(1, 8) }>;
	// Additional storage item size of 56 bytes:
	// - 20 bytes AccountId
	// - 32 bytes Hasher (Blake2256)
	// - 4 bytes BlockNumber (u32)
	type AnnouncementDepositFactor = ConstU128<{ currency::deposit(0, 56) }>;
	type BlockNumberProvider = System;
}
pub type ForeignAssetMigratorOrigin = EitherOfDiverse<
	EnsureRoot<AccountId>,
	EitherOfDiverse<
		pallet_collective::EnsureProportionMoreThan<AccountId, OpenTechCommitteeInstance, 5, 9>,
		EitherOf<
			governance::custom_origins::GeneralAdmin,
			governance::custom_origins::FastGeneralAdmin,
		>,
	>,
>;
impl pallet_moonbeam_lazy_migrations::Config for Runtime {
	type WeightInfo = moonriver_weights::pallet_moonbeam_lazy_migrations::WeightInfo<Runtime>;
}
/// Maintenance mode Call filter
pub struct MaintenanceFilter;
impl Contains<RuntimeCall> for MaintenanceFilter {
	fn contains(c: &RuntimeCall) -> bool {
		match c {
			RuntimeCall::Balances(_) => false,
			RuntimeCall::CrowdloanRewards(_) => false,
			RuntimeCall::Ethereum(_) => false,
			RuntimeCall::EVM(_) => false,
			RuntimeCall::Identity(_) => false,
			RuntimeCall::ParachainStaking(_) => false,
			RuntimeCall::MoonbeamOrbiters(_) => false,
			RuntimeCall::PolkadotXcm(_) => false,
			RuntimeCall::Treasury(_) => false,
			RuntimeCall::XcmTransactor(_) => false,
			RuntimeCall::EthereumXcm(_) => false,
			_ => true,
		}
	}
}
/// Normal Call Filter
pub struct NormalFilter;
impl Contains<RuntimeCall> for NormalFilter {
392
	fn contains(c: &RuntimeCall) -> bool {
392
		match c {
			// We just want to enable this in case of live chains, since the default version
			// is populated at genesis
7
			RuntimeCall::PolkadotXcm(method) => match method {
				pallet_xcm::Call::force_default_xcm_version { .. } => true,
				pallet_xcm::Call::transfer_assets { .. } => true,
				pallet_xcm::Call::transfer_assets_using_type_and_then { .. } => true,
7
				_ => false,
			},
			// We filter anonymous proxy as they make "reserve" inconsistent
			// See: https://github.com/paritytech/substrate/blob/37cca710eed3dadd4ed5364c7686608f5175cce1/frame/proxy/src/lib.rs#L270 // editorconfig-checker-disable-line
			RuntimeCall::Proxy(method) => match method {
				pallet_proxy::Call::create_pure { .. } => false,
				pallet_proxy::Call::kill_pure { .. } => false,
				pallet_proxy::Call::proxy { real, .. } => {
					!pallet_evm::AccountCodes::<Runtime>::contains_key(H160::from(*real))
				}
				_ => true,
			},
			// Filtering the EVM prevents possible re-entrancy from the precompiles which could
			// lead to unexpected scenarios.
			// See https://github.com/PureStake/sr-moonbeam/issues/30
			// Note: It is also assumed that EVM calls are only allowed through `Origin::Root` so
			// this can be seen as an additional security
			RuntimeCall::EVM(_) => false,
385
			_ => true,
		}
392
	}
}
pub struct XcmExecutionManager;
impl moonkit_xcm_primitives::PauseXcmExecution for XcmExecutionManager {
	fn suspend_xcm_execution() -> DispatchResult {
		XcmpQueue::suspend_xcm_execution(RuntimeOrigin::root())
	}
	fn resume_xcm_execution() -> DispatchResult {
		XcmpQueue::resume_xcm_execution(RuntimeOrigin::root())
	}
}
impl pallet_maintenance_mode::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type NormalCallFilter = NormalFilter;
	type MaintenanceCallFilter = MaintenanceFilter;
	type MaintenanceOrigin =
		pallet_collective::EnsureProportionAtLeast<AccountId, OpenTechCommitteeInstance, 5, 9>;
	type XcmExecutionManager = XcmExecutionManager;
}
impl pallet_proxy_genesis_companion::Config for Runtime {
	type ProxyType = ProxyType;
	type BlockNumberProvider = System;
}
parameter_types! {
	pub OrbiterReserveIdentifier: [u8; 4] = [b'o', b'r', b'b', b'i'];
}
type AddCollatorOrigin =
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
type DelCollatorOrigin =
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
impl pallet_moonbeam_orbiters::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type AccountLookup = AuthorMapping;
	type AddCollatorOrigin = AddCollatorOrigin;
	type Currency = Balances;
	type DelCollatorOrigin = DelCollatorOrigin;
	/// Maximum number of orbiters per collator
	type MaxPoolSize = ConstU32<8>;
	/// Maximum number of round to keep on storage
	type MaxRoundArchive = ConstU32<4>;
	type OrbiterReserveIdentifier = OrbiterReserveIdentifier;
	type RotatePeriod = ConstU32<3>;
	/// Round index type.
	type RoundIndex = pallet_parachain_staking::RoundIndex;
	type WeightInfo = moonriver_weights::pallet_moonbeam_orbiters::WeightInfo<Runtime>;
}
/// Only callable after `set_validation_data` is called which forms this proof the same way
fn relay_chain_state_proof<Runtime>() -> RelayChainStateProof
where
	Runtime: cumulus_pallet_parachain_system::Config,
{
	let relay_storage_root = ValidationData::<Runtime>::get()
		.expect("set in `set_validation_data`")
		.relay_parent_storage_root;
	let relay_chain_state =
		RelayStateProof::<Runtime>::get().expect("set in `set_validation_data`");
	RelayChainStateProof::new(ParachainInfo::get(), relay_storage_root, relay_chain_state)
		.expect("Invalid relay chain state proof, already constructed in `set_validation_data`")
}
pub struct BabeDataGetter<Runtime>(sp_std::marker::PhantomData<Runtime>);
impl<Runtime> pallet_randomness::GetBabeData<u64, Option<Hash>> for BabeDataGetter<Runtime>
where
	Runtime: cumulus_pallet_parachain_system::Config,
{
	// Tolerate panic here because only ever called in inherent (so can be omitted)
	fn get_epoch_index() -> u64 {
		if cfg!(feature = "runtime-benchmarks") {
			// storage reads as per actual reads
			let _relay_storage_root = ValidationData::<Runtime>::get();
			let _relay_chain_state = RelayStateProof::<Runtime>::get();
			const BENCHMARKING_NEW_EPOCH: u64 = 10u64;
			return BENCHMARKING_NEW_EPOCH;
		}
		relay_chain_state_proof::<Runtime>()
			.read_optional_entry(relay_chain::well_known_keys::EPOCH_INDEX)
			.ok()
			.flatten()
			.expect("expected to be able to read epoch index from relay chain state proof")
	}
	fn get_epoch_randomness() -> Option<Hash> {
		if cfg!(feature = "runtime-benchmarks") {
			// storage reads as per actual reads
			let _relay_storage_root = ValidationData::<Runtime>::get();
			let _relay_chain_state = RelayStateProof::<Runtime>::get();
			let benchmarking_babe_output = Hash::default();
			return Some(benchmarking_babe_output);
		}
		relay_chain_state_proof::<Runtime>()
			.read_optional_entry(relay_chain::well_known_keys::ONE_EPOCH_AGO_RANDOMNESS)
			.ok()
			.flatten()
	}
}
impl pallet_randomness::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type AddressMapping = sp_runtime::traits::ConvertInto;
	type Currency = Balances;
	type BabeDataGetter = BabeDataGetter<Runtime>;
	type VrfKeyLookup = AuthorMapping;
	type Deposit = runtime_params::PalletRandomnessDepositU128;
	type MaxRandomWords = ConstU8<100>;
	type MinBlockDelay = ConstU32<2>;
	type MaxBlockDelay = ConstU32<2_000>;
	type BlockExpirationDelay = ConstU32<10_000>;
	type EpochExpirationDelay = ConstU64<10_000>;
	type WeightInfo = moonriver_weights::pallet_randomness::WeightInfo<Runtime>;
}
impl pallet_root_testing::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
}
parameter_types! {
	// One storage item; key size is 32 + 20; value is size 4+4+16+20 bytes = 44 bytes.
	pub const DepositBase: Balance = currency::deposit(1, 96);
	// Additional storage item size of 20 bytes.
	pub const DepositFactor: Balance = currency::deposit(0, 20);
	pub const MaxSignatories: u32 = 100;
}
impl pallet_multisig::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type Currency = Balances;
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
	type MaxSignatories = MaxSignatories;
	type WeightInfo = moonriver_weights::pallet_multisig::WeightInfo<Runtime>;
	type BlockNumberProvider = System;
}
impl pallet_relay_storage_roots::Config for Runtime {
	type MaxStorageRoots = ConstU32<30>;
	type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Self>;
	type WeightInfo = moonriver_weights::pallet_relay_storage_roots::WeightInfo<Runtime>;
}
#[cfg(feature = "runtime-benchmarks")]
impl pallet_precompile_benchmarks::Config for Runtime {
	type WeightInfo = moonriver_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>;
}
impl pallet_parameters::Config for Runtime {
	type AdminOrigin = EnsureRoot<AccountId>;
	type RuntimeEvent = RuntimeEvent;
	type RuntimeParameters = RuntimeParameters;
	type WeightInfo = moonriver_weights::pallet_parameters::WeightInfo<Runtime>;
}
impl cumulus_pallet_weight_reclaim::Config for Runtime {
	type WeightInfo = moonriver_weights::cumulus_pallet_weight_reclaim::WeightInfo<Runtime>;
}
impl pallet_migrations::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	#[cfg(not(feature = "runtime-benchmarks"))]
	type Migrations = migrations::MultiBlockMigrationList<Runtime>;
	#[cfg(feature = "runtime-benchmarks")]
	type Migrations = pallet_migrations::mock_helpers::MockedMigrations;
	type CursorMaxLen = ConstU32<65_536>;
	type IdentifierMaxLen = ConstU32<256>;
	type MigrationStatusHandler = ();
	type FailedMigrationHandler = MaintenanceMode;
	type MaxServiceWeight = MaxServiceWeight;
	type WeightInfo = weights::pallet_migrations::WeightInfo<Runtime>;
}
11586
construct_runtime! {
11586
	pub enum Runtime
11586
	{
11586
		// System support stuff.
11586
		System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>} = 0,
11586
		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 1,
11586
		// Previously 2: pallet_randomness_collective_flip
11586
		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
11586
		ParachainInfo: parachain_info::{Pallet, Storage, Config<T>} = 4,
11586
		RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event<T>} = 5,
11586

            
11586
		// Monetary stuff.
11586
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
11586
		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Config<T>, Event<T>} = 11,
11586

            
11586
		// Consensus support.
11586
		ParachainStaking: pallet_parachain_staking::{Pallet, Call, Storage, Event<T>, Config<T>} = 20,
11586
		AuthorInherent: pallet_author_inherent::{Pallet, Call, Storage, Inherent} = 21,
11586
		AuthorFilter: pallet_author_slot_filter::{Pallet, Call, Storage, Event, Config<T>} = 22,
11586
		AuthorMapping: pallet_author_mapping::{Pallet, Call, Config<T>, Storage, Event<T>} = 23,
11586
		MoonbeamOrbiters: pallet_moonbeam_orbiters::{Pallet, Call, Storage, Event<T>} = 24,
11586
		AsyncBacking: pallet_async_backing::{Pallet, Storage} = 25,
11586

            
11586
		// Handy utilities.
11586
		Utility: pallet_utility::{Pallet, Call, Event} = 30,
11586
		Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 31,
11586
		MaintenanceMode: pallet_maintenance_mode::{Pallet, Call, Config<T>, Storage, Event} = 32,
11586
		Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 33,
11586
		// [Removed] Migrations: pallet_migrations::{Pallet, Storage, Config<T>, Event<T>} = 34,
11586
		ProxyGenesisCompanion: pallet_proxy_genesis_companion::{Pallet, Config<T>} = 35,
11586
		Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 36,
11586
		MoonbeamLazyMigrations: pallet_moonbeam_lazy_migrations::{Pallet, Call, Storage} = 37,
11586
		Parameters: pallet_parameters = 38,
11586

            
11586
		// Sudo was previously index 40
11586

            
11586
		// Ethereum compatibility
11586
		EthereumChainId: pallet_evm_chain_id::{Pallet, Storage, Config<T>} = 50,
11586
		EVM: pallet_evm::{Pallet, Config<T>, Call, Storage, Event<T>} = 51,
11586
		Ethereum: pallet_ethereum::{Pallet, Call, Storage, Event, Origin, Config<T>} = 52,
11586

            
11586
		// Governance stuff.
11586
		Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 60,
11586
		// Democracy:  61,
11586
		Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 62,
11586
		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 63,
11586
		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 64,
11586
		Origins: governance::custom_origins::{Origin} = 65,
11586
		Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 66,
11586

            
11586
		// Council stuff.
11586
		// CouncilCollective: 70
11586
		// TechCommitteeCollective: 71,
11586
		TreasuryCouncilCollective:
11586
			pallet_collective::<Instance3>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 72,
11586
		OpenTechCommitteeCollective:
11586
			pallet_collective::<Instance4>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 73,
11586

            
11586
		// Treasury stuff.
11586
		Treasury: pallet_treasury::{Pallet, Storage, Config<T>, Event<T>, Call} = 80,
11586

            
11586
		// Crowdloan stuff.
11586
		CrowdloanRewards: pallet_crowdloan_rewards::{Pallet, Call, Config<T>, Storage, Event<T>} = 90,
11586

            
11586
		// XCM Stuff
11586
		XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Storage, Event<T>} = 100,
11586
		CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 101,
11586
		// Previously 102: DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>}
11586
		PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event<T>, Origin, Config<T>} = 103,
11586
		// [Removed] Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 104,
11586
		// Previously 105: AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event<T>}
11586
		// Previously 106: XTokens
11586
		XcmTransactor: pallet_xcm_transactor::{Pallet, Call, Storage, Event<T>} = 107,
11586
		// Previously 108: pallet_assets::<Instance1>
11586
		EthereumXcm: pallet_ethereum_xcm::{Pallet, Call, Storage, Origin, Event<T>} = 109,
11586
		Erc20XcmBridge: pallet_erc20_xcm_bridge::{Pallet} = 110,
11586
		MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 111,
11586
		EvmForeignAssets: pallet_moonbeam_foreign_assets::{Pallet, Call, Storage, Event<T>, Config<T>} = 114,
11586
		XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>, Config<T>} = 115,
11586
		EmergencyParaXcm: pallet_emergency_para_xcm::{Pallet, Call, Storage, Event} = 116,
11586
		MultiBlockMigrations: pallet_migrations = 117,
11586
		WeightReclaim: cumulus_pallet_weight_reclaim = 118,
11586

            
11586
		// Utils
11586
		RelayStorageRoots: pallet_relay_storage_roots::{Pallet, Storage} = 112,
11586

            
11586
		#[cfg(feature = "runtime-benchmarks")]
11586
		PrecompileBenchmarks: pallet_precompile_benchmarks::{Pallet} = 113,
11586

            
11586
		// Randomness
11586
		Randomness: pallet_randomness::{Pallet, Call, Storage, Event<T>, Inherent} = 120,
11586

            
11586
		// Bridge pallets (reserved indexes from 130 to 140)
11586
		BridgePolkadotGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 130,
11586
		BridgePolkadotParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 131,
11586
		BridgePolkadotMessages: pallet_bridge_messages::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 132,
11586
		BridgeXcmOverMoonbeam: pallet_xcm_bridge::<Instance1>::{Pallet, Call, Storage, Event<T>, HoldReason, Config<T>} = 133
11586
	}
652511
}
bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
	RuntimeCall, AccountId,
	// Grandpa
	BridgePolkadotGrandpa,
	// Parachains
	BridgePolkadotParachains,
	// Messages
	BridgePolkadotMessages
}
#[cfg(feature = "runtime-benchmarks")]
use moonbeam_runtime_common::benchmarking::BenchmarkHelper;
#[cfg(feature = "runtime-benchmarks")]
mod benches {
	frame_support::parameter_types! {
		pub const MaxBalance: crate::Balance = crate::Balance::max_value();
	}
	frame_benchmarking::define_benchmarks!(
		[frame_system, SystemBench::<Runtime>]
		[frame_system_extensions, frame_system_benchmarking::extensions::Pallet::<Runtime>]
		[pallet_utility, Utility]
		[pallet_timestamp, Timestamp]
		[pallet_balances, Balances]
		[pallet_evm, EVM]
		[pallet_parachain_staking, ParachainStaking]
		[pallet_scheduler, Scheduler]
		[pallet_treasury, Treasury]
		[pallet_author_inherent, AuthorInherent]
		[pallet_author_slot_filter, AuthorFilter]
		[pallet_crowdloan_rewards, CrowdloanRewards]
		[pallet_author_mapping, AuthorMapping]
		[pallet_proxy, Proxy]
		[pallet_transaction_payment, PalletTransactionPaymentBenchmark::<Runtime>]
		[pallet_identity, Identity]
		[cumulus_pallet_parachain_system, ParachainSystem]
		[cumulus_pallet_xcmp_queue, XcmpQueue]
		[pallet_message_queue, MessageQueue]
		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
		[pallet_xcm_transactor, XcmTransactor]
		[pallet_moonbeam_foreign_assets, EvmForeignAssets]
		[pallet_moonbeam_orbiters, MoonbeamOrbiters]
		[pallet_randomness, Randomness]
		[pallet_conviction_voting, ConvictionVoting]
		[pallet_referenda, Referenda]
		[pallet_preimage, Preimage]
		[pallet_whitelist, Whitelist]
		[pallet_multisig, Multisig]
		[pallet_migrations, MultiBlockMigrations]
		// Currently there are no extrinsics to benchmark for the Lazy Migrations pallet
		// [pallet_moonbeam_lazy_migrations, MoonbeamLazyMigrations]
		[pallet_relay_storage_roots, RelayStorageRoots]
		[pallet_precompile_benchmarks, PrecompileBenchmarks]
		[pallet_parameters, Parameters]
		[pallet_xcm_weight_trader, XcmWeightTrader]
		[pallet_collective, TreasuryCouncilCollective]
		[pallet_collective, OpenTechCommitteeCollective]
		[pallet_bridge_grandpa, BridgePolkadotGrandpa]
		[pallet_bridge_parachains, pallet_bridge_parachains::benchmarking::Pallet::<Runtime, bridge_config::BridgeMoonbeamInstance>]
		[pallet_bridge_messages, pallet_bridge_messages::benchmarking::Pallet::<Runtime, bridge_config::WithPolkadotMessagesInstance>]
		[cumulus_pallet_weight_reclaim, WeightReclaim]
	);
}
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;
/// The TransactionExtension to the basic transaction logic.
pub type TxExtension = cumulus_pallet_weight_reclaim::StorageWeightReclaim<
	Runtime,
	(
		frame_system::CheckNonZeroSender<Runtime>,
		frame_system::CheckSpecVersion<Runtime>,
		frame_system::CheckTxVersion<Runtime>,
		frame_system::CheckGenesis<Runtime>,
		frame_system::CheckEra<Runtime>,
		frame_system::CheckNonce<Runtime>,
		frame_system::CheckWeight<Runtime>,
		pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
		BridgeRejectObsoleteHeadersAndMessages,
		frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
	),
>;
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic =
	fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension, H160>;
/// Executive: handles dispatch to the various pallets.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
>;
// All of our runtimes share most of their Runtime API implementations.
// We use a macro to implement this common part and add runtime-specific additional implementations.
// This macro expands to :
// ```
// impl_runtime_apis! {
//     // All impl blocks shared between all runtimes.
//
//     // Specific impls provided to the `impl_runtime_apis_plus_common!` macro.
// }
// ```
moonbeam_runtime_common::impl_runtime_apis_plus_common!(
	{
		impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
			fn validate_transaction(
				source: TransactionSource,
				xt: <Block as BlockT>::Extrinsic,
				block_hash: <Block as BlockT>::Hash,
			) -> TransactionValidity {
				// Filtered calls should not enter the tx pool as they'll fail if inserted.
				// If this call is not allowed, we return early.
				if !<Runtime as frame_system::Config>::BaseCallFilter::contains(&xt.0.function) {
					return InvalidTransaction::Call.into();
				}
				// This runtime uses Substrate's pallet transaction payment. This
				// makes the chain feel like a standard Substrate chain when submitting
				// frame transactions and using Substrate ecosystem tools. It has the downside that
				// transaction are not prioritized by gas_price. The following code reprioritizes
				// transactions to overcome this.
				//
				// A more elegant, ethereum-first solution is
				// a pallet that replaces pallet transaction payment, and allows users
				// to directly specify a gas price rather than computing an effective one.
				// #HopefullySomeday
				// First we pass the transactions to the standard FRAME executive. This calculates all the
				// necessary tags, longevity and other properties that we will leave unchanged.
				// This also assigns some priority that we don't care about and will overwrite next.
				let mut intermediate_valid = Executive::validate_transaction(source, xt.clone(), block_hash)?;
				let dispatch_info = xt.get_dispatch_info();
				// If this is a pallet ethereum transaction, then its priority is already set
				// according to gas price from pallet ethereum. If it is any other kind of transaction,
				// we modify its priority.
				Ok(match &xt.0.function {
					RuntimeCall::Ethereum(transact { .. }) => intermediate_valid,
					_ if dispatch_info.class != DispatchClass::Normal => intermediate_valid,
					_ => {
						let tip = match &xt.0.preamble {
							Preamble::Bare(_) => 0,
							Preamble::Signed(_, _, signed_extra) => {
								// Yuck, this depends on the index of ChargeTransactionPayment in TxExtension
								// Get the 7th item from the tuple
								let charge_transaction_payment = &signed_extra.0.7;
								charge_transaction_payment.tip()
							},
							Preamble::General(_, _) => 0,
						};
						// Calculate the fee that will be taken by pallet transaction payment
						let fee: u64 = TransactionPayment::compute_fee(
							xt.encode().len() as u32,
							&dispatch_info,
							tip,
						).saturated_into();
						// Calculate how much gas this effectively uses according to the existing mapping
						let effective_gas =
							<Runtime as pallet_evm::Config>::GasWeightMapping::weight_to_gas(
								dispatch_info.total_weight()
							);
						// Here we calculate an ethereum-style effective gas price using the
						// current fee of the transaction. Because the weight -> gas conversion is
						// lossy, we have to handle the case where a very low weight maps to zero gas.
						let effective_gas_price = if effective_gas > 0 {
							fee / effective_gas
						} else {
							// If the effective gas was zero, we just act like it was 1.
							fee
						};
						// Overwrite the original prioritization with this ethereum one
						intermediate_valid.priority = effective_gas_price;
						intermediate_valid
					}
				})
			}
		}
		impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
			fn can_build_upon(
				included_hash: <Block as BlockT>::Hash,
				slot: async_backing_primitives::Slot,
			) -> bool {
				ConsensusHook::can_build_upon(included_hash, slot)
			}
		}
		impl bp_polkadot::PolkadotFinalityApi<Block> for Runtime {
			fn best_finalized() -> Option<bp_runtime::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>> {
				BridgePolkadotGrandpa::best_finalized()
			}
			fn free_headers_interval() -> Option<bp_polkadot::BlockNumber> {
				<Runtime as pallet_bridge_grandpa::Config<
					bridge_config::BridgeGrandpaPolkadotInstance
				>>::FreeHeadersInterval::get()
			}
			fn synced_headers_grandpa_info(
			) -> Vec<bp_header_chain::StoredHeaderGrandpaInfo<bp_polkadot::Header>> {
				BridgePolkadotGrandpa::synced_headers_grandpa_info()
			}
		}
		impl bp_moonbeam::MoonbeamPolkadotFinalityApi<Block> for Runtime {
			fn best_finalized() -> Option<bp_runtime::HeaderId<bp_moonbeam::Hash, bp_moonbeam::BlockNumber>> {
				BridgePolkadotParachains::best_parachain_head_id::<
					bp_moonbeam::Moonbeam
				>().unwrap_or(None)
			}
			fn free_headers_interval() -> Option<bp_moonbeam::BlockNumber> {
				// "free interval" is not currently used for parachains
				None
			}
		}
		impl bp_moonbeam::ToMoonbeamPolkadotOutboundLaneApi<Block> for Runtime {
			fn message_details(
				lane: bp_moonbeam::LaneId,
				begin: bp_messages::MessageNonce,
				end: bp_messages::MessageNonce,
			) -> Vec<bp_messages::OutboundMessageDetails> {
				bridge_runtime_common::messages_api::outbound_message_details::<
					Runtime,
					bridge_config::WithPolkadotMessagesInstance,
				>(lane, begin, end)
			}
		}
		impl bp_moonbeam::FromMoonbeamPolkadotInboundLaneApi<Block> for Runtime {
			fn message_details(
				lane: bp_moonbeam::LaneId,
				messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>,
			) -> Vec<bp_messages::InboundMessageDetails> {
				bridge_runtime_common::messages_api::inbound_message_details::<
					Runtime,
					bridge_config::WithPolkadotMessagesInstance,
				>(lane, messages)
			}
		}
	}
	// Benchmark customizations
	{
		impl pallet_bridge_parachains::benchmarking::Config<bridge_config::BridgeMoonbeamInstance> for Runtime {
			fn parachains() -> Vec<bp_polkadot_core::parachains::ParaId> {
				use bp_runtime::Parachain;
				vec![bp_polkadot_core::parachains::ParaId(bp_moonbeam::Moonbeam::PARACHAIN_ID)]
			}
			fn prepare_parachain_heads_proof(
				parachains: &[bp_polkadot_core::parachains::ParaId],
				parachain_head_size: u32,
				proof_params: bp_runtime::UnverifiedStorageProofParams,
			) -> (
				bp_parachains::RelayBlockNumber,
				bp_parachains::RelayBlockHash,
				bp_polkadot_core::parachains::ParaHeadsProof,
				Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>,
			) {
				bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof::<Runtime, bridge_config::BridgeMoonbeamInstance>(
					parachains,
					parachain_head_size,
					proof_params,
				)
			}
		}
		use bridge_runtime_common::messages_benchmarking::{
			generate_xcm_builder_bridge_message_sample, prepare_message_delivery_proof_from_parachain,
			prepare_message_proof_from_parachain,
		};
		use pallet_bridge_messages::benchmarking::{
			Config as BridgeMessagesConfig, MessageDeliveryProofParams, MessageProofParams,
		};
		impl BridgeMessagesConfig<bridge_config::WithPolkadotMessagesInstance> for Runtime {
			fn is_relayer_rewarded(_relayer: &Self::AccountId) -> bool {
				// Currently, we do not reward relayers
				true
			}
			fn prepare_message_proof(
				params: MessageProofParams<
					pallet_bridge_messages::LaneIdOf<Runtime, bridge_config::WithPolkadotMessagesInstance>,
				>,
			) -> (
				bridge_config::benchmarking::FromMoonbeamMessagesProof<
					bridge_config::WithPolkadotMessagesInstance,
				>,
				Weight,
			) {
				use cumulus_primitives_core::XcmpMessageSource;
				assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty());
				ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into());
				PolkadotXcm::force_xcm_version(
					RuntimeOrigin::root(),
					Box::new(Location::new(1, Parachain(42))),
					cumulus_primitives_core::XCM_VERSION,
				)
				.map_err(|e| {
					log::error!(
						"Failed to dispatch `force_xcm_version({:?}, {:?}, {:?})`, error: {:?}",
						RuntimeOrigin::root(),
						Location::new(1, Parachain(42)),
						cumulus_primitives_core::XCM_VERSION,
						e
					);
				})
				.expect("XcmVersion stored!");
				let universal_source = bridge_config::benchmarking::open_bridge_for_benchmarks::<
					Runtime,
					bridge_config::XcmOverPolkadotInstance,
					xcm_config::LocationToAccountId,
				>(params.lane, 42);
				prepare_message_proof_from_parachain::<
					Runtime,
					bridge_config::BridgeGrandpaPolkadotInstance,
					bridge_config::WithPolkadotMessagesInstance,
				>(params, generate_xcm_builder_bridge_message_sample(universal_source))
			}
			fn prepare_message_delivery_proof(
				params: MessageDeliveryProofParams<
					AccountId,
					pallet_bridge_messages::LaneIdOf<Runtime, bridge_config::WithPolkadotMessagesInstance>,
				>,
			) -> bridge_config::benchmarking::ToMoonbeamMessagesDeliveryProof<
				bridge_config::WithPolkadotMessagesInstance,
			> {
				let _ = bridge_config::benchmarking::open_bridge_for_benchmarks::<
					Runtime,
					bridge_config::XcmOverPolkadotInstance,
					xcm_config::LocationToAccountId,
				>(params.lane, 42);
				prepare_message_delivery_proof_from_parachain::<
					Runtime,
					bridge_config::BridgeGrandpaPolkadotInstance,
					bridge_config::WithPolkadotMessagesInstance,
				>(params)
			}
			fn is_message_successfully_dispatched(_nonce: bp_messages::MessageNonce) -> bool {
				// The message is not routed from Bridge Hub
				true
			}
		}
	}
);
// Nimbus's Executive wrapper allows relay validators to verify the seal digest
cumulus_pallet_parachain_system::register_validate_block!(
	Runtime = Runtime,
	BlockExecutor = pallet_author_inherent::BlockExecutor::<Runtime, Executive>,
);
moonbeam_runtime_common::impl_self_contained_call!();
// Shorthand for a Get field of a pallet Config.
#[macro_export]
macro_rules! get {
	($pallet:ident, $name:ident, $type:ty) => {
		<<$crate::Runtime as $pallet::Config>::$name as $crate::Get<$type>>::get()
	};
}
#[cfg(test)]
mod tests {
	use super::{currency::*, *};
	#[test]
	// Helps us to identify a Pallet Call in case it exceeds the 1kb limit.
	// Hint: this should be a rare case. If that happens, one or more of the dispatchable arguments
	// need to be Boxed.
1
	fn call_max_size() {
		const CALL_ALIGN: u32 = 1024;
1
		assert!(std::mem::size_of::<pallet_evm_chain_id::Call<Runtime>>() <= CALL_ALIGN as usize);
1
		assert!(std::mem::size_of::<pallet_evm::Call<Runtime>>() <= CALL_ALIGN as usize);
1
		assert!(std::mem::size_of::<pallet_ethereum::Call<Runtime>>() <= CALL_ALIGN as usize);
1
		assert!(
1
			std::mem::size_of::<pallet_parachain_staking::Call<Runtime>>() <= CALL_ALIGN as usize
1
		);
1
		assert!(
1
			std::mem::size_of::<pallet_author_inherent::Call<Runtime>>() <= CALL_ALIGN as usize
1
		);
1
		assert!(
1
			std::mem::size_of::<pallet_author_slot_filter::Call<Runtime>>() <= CALL_ALIGN as usize
1
		);
1
		assert!(
1
			std::mem::size_of::<pallet_crowdloan_rewards::Call<Runtime>>() <= CALL_ALIGN as usize
1
		);
1
		assert!(std::mem::size_of::<pallet_author_mapping::Call<Runtime>>() <= CALL_ALIGN as usize);
1
		assert!(
1
			std::mem::size_of::<pallet_maintenance_mode::Call<Runtime>>() <= CALL_ALIGN as usize
1
		);
1
		assert!(std::mem::size_of::<pallet_migrations::Call<Runtime>>() <= CALL_ALIGN as usize);
1
		assert!(
1
			std::mem::size_of::<pallet_moonbeam_lazy_migrations::Call<Runtime>>()
1
				<= CALL_ALIGN as usize
1
		);
1
		assert!(
1
			std::mem::size_of::<pallet_proxy_genesis_companion::Call<Runtime>>()
1
				<= CALL_ALIGN as usize
1
		);
1
	}
	#[test]
1
	fn currency_constants_are_correct() {
1
		assert_eq!(SUPPLY_FACTOR, 1);
		// txn fees
1
		assert_eq!(TRANSACTION_BYTE_FEE, Balance::from(1 * GIGAWEI));
1
		assert_eq!(
1
			get!(pallet_transaction_payment, OperationalFeeMultiplier, u8),
1
			5_u8
1
		);
1
		assert_eq!(STORAGE_BYTE_FEE, Balance::from(100 * MICROMOVR));
		// pallet_identity deposits
1
		assert_eq!(
1
			get!(pallet_identity, BasicDeposit, u128),
1
			Balance::from(1 * MOVR + 25800 * MICROMOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_identity, ByteDeposit, u128),
1
			Balance::from(100 * MICROMOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_identity, SubAccountDeposit, u128),
1
			Balance::from(1 * MOVR + 5300 * MICROMOVR)
1
		);
		// staking minimums
1
		assert_eq!(
1
			get!(pallet_parachain_staking, MinCandidateStk, u128),
1
			Balance::from(500 * MOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_parachain_staking, MinDelegation, u128),
1
			Balance::from(5 * MOVR)
1
		);
		// crowdloan min reward
1
		assert_eq!(
1
			get!(pallet_crowdloan_rewards, MinimumReward, u128),
1
			Balance::from(0u128)
1
		);
		// deposit for AuthorMapping
1
		assert_eq!(
1
			get!(pallet_author_mapping, DepositAmount, u128),
1
			Balance::from(100 * MOVR)
1
		);
		// proxy deposits
1
		assert_eq!(
1
			get!(pallet_proxy, ProxyDepositBase, u128),
1
			Balance::from(1 * MOVR + 800 * MICROMOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, ProxyDepositFactor, u128),
1
			Balance::from(2100 * MICROMOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, AnnouncementDepositBase, u128),
1
			Balance::from(1 * MOVR + 800 * MICROMOVR)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, AnnouncementDepositFactor, u128),
1
			Balance::from(5600 * MICROMOVR)
1
		);
1
	}
	#[test]
1
	fn max_offline_rounds_lower_or_eq_than_reward_payment_delay() {
1
		assert!(
1
			get!(pallet_parachain_staking, MaxOfflineRounds, u32)
1
				<= get!(pallet_parachain_staking, RewardPaymentDelay, u32)
1
		);
1
	}
	#[test]
	// Required migration is
	// pallet_parachain_staking::migrations::IncreaseMaxTopDelegationsPerCandidate
	// Purpose of this test is to remind of required migration if constant is ever changed
1
	fn updating_maximum_delegators_per_candidate_requires_configuring_required_migration() {
1
		assert_eq!(
1
			get!(pallet_parachain_staking, MaxTopDelegationsPerCandidate, u32),
1
			300
1
		);
1
		assert_eq!(
1
			get!(
1
				pallet_parachain_staking,
1
				MaxBottomDelegationsPerCandidate,
1
				u32
1
			),
1
			50
1
		);
1
	}
	#[test]
1
	fn configured_base_extrinsic_weight_is_evm_compatible() {
1
		let min_ethereum_transaction_weight = WeightPerGas::get() * 21_000;
1
		let base_extrinsic = <Runtime as frame_system::Config>::BlockWeights::get()
1
			.get(frame_support::dispatch::DispatchClass::Normal)
1
			.base_extrinsic;
1
		assert!(base_extrinsic.ref_time() <= min_ethereum_transaction_weight.ref_time());
1
	}
	#[test]
1
	fn test_storage_growth_ratio_is_correct() {
1
		// This is the highest amount of new storage that can be created in a block 40 KB
1
		let block_storage_limit = 160 * 1024;
1
		let expected_storage_growth_ratio = BlockGasLimit::get()
1
			.low_u64()
1
			.saturating_div(block_storage_limit);
1
		let actual_storage_growth_ratio =
1
			<Runtime as pallet_evm::Config>::GasLimitStorageGrowthRatio::get();
1
		assert_eq!(
			expected_storage_growth_ratio, actual_storage_growth_ratio,
			"Storage growth ratio is not correct"
		);
1
	}
}