1
// Copyright 2019-2022 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 Moonbase Runtime.
18
//!
19
//! Primary features of this runtime include:
20
//! * Ethereum compatibility
21
//! * Moonbase 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 256.
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
pub mod asset_config;
32
pub mod governance;
33
pub mod runtime_params;
34
pub mod xcm_config;
35

            
36
mod migrations;
37
mod precompiles;
38

            
39
// Re-export required by get! macro.
40
#[cfg(feature = "std")]
41
pub use fp_evm::GenesisAccount;
42
pub use frame_support::traits::Get;
43
pub use moonbeam_core_primitives::{
44
	AccountId, AccountIndex, Address, AssetId, Balance, BlockNumber, DigestItem, Hash, Header,
45
	Index, Signature,
46
};
47
pub use pallet_author_slot_filter::EligibilityValue;
48
pub use pallet_parachain_staking::{weights::WeightInfo, InflationInfo, Range};
49
pub use precompiles::{
50
	MoonbasePrecompiles, PrecompileName, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
51
};
52

            
53
use account::AccountId20;
54
use cumulus_pallet_parachain_system::{
55
	RelayChainStateProof, RelayStateProof, RelaychainDataProvider, ValidationData,
56
};
57
use cumulus_primitives_core::{relay_chain, AggregateMessageOrigin};
58
use fp_rpc::TransactionStatus;
59
use frame_support::{
60
	construct_runtime,
61
	dispatch::{DispatchClass, GetDispatchInfo, PostDispatchInfo},
62
	ensure,
63
	pallet_prelude::DispatchResult,
64
	parameter_types,
65
	traits::{
66
		fungible::{Balanced, Credit, HoldConsideration, Inspect},
67
		tokens::imbalance::ResolveTo,
68
		tokens::{PayFromAccount, UnityAssetBalanceConversion},
69
		ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse,
70
		EqualPrivilegeOnly, FindAuthor, Imbalance, InstanceFilter, LinearStoragePrice, OnFinalize,
71
		OnUnbalanced,
72
	},
73
	weights::{
74
		constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient,
75
		WeightToFeeCoefficients, WeightToFeePolynomial,
76
	},
77
	PalletId,
78
};
79

            
80
use frame_system::{EnsureRoot, EnsureSigned};
81
use governance::councils::*;
82
use moonbeam_rpc_primitives_txpool::TxPoolResponse;
83
use moonbeam_runtime_common::{
84
	timestamp::{ConsensusHookWrapperForRelayTimestamp, RelayTimestamp},
85
	weights as moonbase_weights,
86
};
87
use nimbus_primitives::CanAuthor;
88
use pallet_ethereum::Call::transact;
89
use pallet_ethereum::{PostLogContent, Transaction as EthereumTransaction};
90
use pallet_evm::{
91
	Account as EVMAccount, EVMFungibleAdapter, EnsureAddressNever, EnsureAddressRoot,
92
	FeeCalculator, GasWeightMapping, IdentityAddressMapping,
93
	OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
94
};
95
use pallet_transaction_payment::{FungibleAdapter, Multiplier, TargetedFeeAdjustment};
96
use pallet_treasury::TreasuryAccountId;
97
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
98
use runtime_params::*;
99
use scale_info::TypeInfo;
100
use sp_api::impl_runtime_apis;
101
use sp_consensus_slots::Slot;
102
use sp_core::{OpaqueMetadata, H160, H256, U256};
103
use sp_runtime::{
104
	create_runtime_str, generic, impl_opaque_keys,
105
	traits::{
106
		BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, IdentityLookup,
107
		PostDispatchInfoOf, UniqueSaturatedInto, Zero,
108
	},
109
	transaction_validity::{
110
		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
111
	},
112
	ApplyExtrinsicResult, DispatchErrorWithPostInfo, FixedPointNumber, Perbill, Permill,
113
	Perquintill,
114
};
115
use sp_std::{
116
	convert::{From, Into},
117
	prelude::*,
118
};
119
#[cfg(feature = "std")]
120
use sp_version::NativeVersion;
121
use sp_version::RuntimeVersion;
122
use xcm::{VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm};
123
use xcm_runtime_apis::{
124
	dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
125
	fees::Error as XcmPaymentApiError,
126
};
127

            
128
use smallvec::smallvec;
129
use sp_runtime::serde::{Deserialize, Serialize};
130

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

            
134
pub type Precompiles = MoonbasePrecompiles<Runtime>;
135

            
136
/// UNIT, the native token, uses 18 decimals of precision.
137
pub mod currency {
138
	use super::Balance;
139

            
140
	// Provide a common factor between runtimes based on a supply of 10_000_000 tokens.
141
	pub const SUPPLY_FACTOR: Balance = 1;
142

            
143
	pub const WEI: Balance = 1;
144
	pub const KILOWEI: Balance = 1_000;
145
	pub const MEGAWEI: Balance = 1_000_000;
146
	pub const GIGAWEI: Balance = 1_000_000_000;
147
	pub const MICROUNIT: Balance = 1_000_000_000_000;
148
	pub const MILLIUNIT: Balance = 1_000_000_000_000_000;
149
	pub const UNIT: Balance = 1_000_000_000_000_000_000;
150
	pub const KILOUNIT: Balance = 1_000_000_000_000_000_000_000;
151

            
152
	pub const TRANSACTION_BYTE_FEE: Balance = 1 * GIGAWEI * SUPPLY_FACTOR;
153
	pub const STORAGE_BYTE_FEE: Balance = 100 * MICROUNIT * SUPPLY_FACTOR;
154
	pub const WEIGHT_FEE: Balance = 50 * KILOWEI * SUPPLY_FACTOR / 4;
155

            
156
32
	pub const fn deposit(items: u32, bytes: u32) -> Balance {
157
32
		items as Balance * 1 * UNIT * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
158
32
	}
159
}
160

            
161
/// Maximum weight per block
162
pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND, u64::MAX)
163
	.saturating_mul(2)
164
	.set_proof_size(relay_chain::MAX_POV_SIZE as u64);
165

            
166
pub const MILLISECS_PER_BLOCK: u64 = 6_000;
167
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
168
pub const HOURS: BlockNumber = MINUTES * 60;
169
pub const DAYS: BlockNumber = HOURS * 24;
170
pub const WEEKS: BlockNumber = DAYS * 7;
171
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
172
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
173
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
174
/// to even the core data structures.
175
pub mod opaque {
176
	use super::*;
177

            
178
	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
179
	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
180

            
181
	impl_opaque_keys! {
182
		pub struct SessionKeys {
183
			pub nimbus: AuthorInherent,
184
			pub vrf: session_keys_primitives::VrfSessionKey,
185
		}
186
	}
187
}
188

            
189
/// This runtime version.
190
/// The spec_version is composed of 2x2 digits. The first 2 digits represent major changes
191
/// that can't be skipped, such as data migration upgrades. The last 2 digits represent minor
192
/// changes which can be skipped.
193
#[cfg(feature = "runtime-benchmarks")]
194
#[sp_version::runtime_version]
195
pub const VERSION: RuntimeVersion = RuntimeVersion {
196
	spec_name: create_runtime_str!("moonbase"),
197
	impl_name: create_runtime_str!("moonbase"),
198
	authoring_version: 4,
199
	spec_version: 3400,
200
	impl_version: 0,
201
	apis: RUNTIME_API_VERSIONS,
202
	transaction_version: 3,
203
	state_version: 0,
204
};
205

            
206
/// We need to duplicate this because the `runtime_version` macro is conflicting with the
207
/// conditional compilation at the state_version field.
208
#[cfg(not(feature = "runtime-benchmarks"))]
209
#[sp_version::runtime_version]
210
pub const VERSION: RuntimeVersion = RuntimeVersion {
211
	spec_name: create_runtime_str!("moonbase"),
212
	impl_name: create_runtime_str!("moonbase"),
213
	authoring_version: 4,
214
	spec_version: 3400,
215
	impl_version: 0,
216
	apis: RUNTIME_API_VERSIONS,
217
	transaction_version: 3,
218
	state_version: 1,
219
};
220

            
221
/// The version information used to identify this runtime when compiled natively.
222
#[cfg(feature = "std")]
223
pub fn native_version() -> NativeVersion {
224
	NativeVersion {
225
		runtime_version: VERSION,
226
		can_author_with: Default::default(),
227
	}
228
}
229

            
230
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
231
pub const NORMAL_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).saturating_div(4);
232
// Here we assume Ethereum's base fee of 21000 gas and convert to weight, but we
233
// subtract roughly the cost of a balance transfer from it (about 1/3 the cost)
234
// and some cost to account for per-byte-fee.
235
// TODO: we should use benchmarking's overhead feature to measure this
236
pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
237

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

            
256
parameter_types! {
257
	pub const Version: RuntimeVersion = VERSION;
258
	/// TODO: this is left here so that `impl_runtime_apis_plus_common` will find the same type for
259
	/// `BlockWeights` in all runtimes. It can probably be removed once the custom
260
	/// `RuntimeBlockWeights` has been pushed to each runtime.
261
	pub BlockWeights: frame_system::limits::BlockWeights = RuntimeBlockWeights::get();
262
	/// We allow for 5 MB blocks.
263
	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
264
		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
265
}
266

            
267
impl frame_system::Config for Runtime {
268
	/// The identifier used to distinguish between accounts.
269
	type AccountId = AccountId;
270
	/// The aggregated dispatch type that is available for extrinsics.
271
	type RuntimeCall = RuntimeCall;
272
	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
273
	type Lookup = IdentityLookup<AccountId>;
274
	/// The index type for storing how many extrinsics an account has signed.
275
	type Nonce = Index;
276
	/// The index type for blocks.
277
	type Block = Block;
278
	/// The type for hashing blocks and tries.
279
	type Hash = Hash;
280
	/// The hashing algorithm used.
281
	type Hashing = BlakeTwo256;
282
	/// The ubiquitous event type.
283
	type RuntimeEvent = RuntimeEvent;
284
	/// The ubiquitous origin type.
285
	type RuntimeOrigin = RuntimeOrigin;
286
	/// The aggregated RuntimeTask type.
287
	type RuntimeTask = RuntimeTask;
288
	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
289
	type BlockHashCount = ConstU32<256>;
290
	/// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
291
	type BlockWeights = RuntimeBlockWeights;
292
	/// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
293
	type BlockLength = BlockLength;
294
	/// Runtime version.
295
	type Version = Version;
296
	type PalletInfo = PalletInfo;
297
	type AccountData = pallet_balances::AccountData<Balance>;
298
	type OnNewAccount = ();
299
	type OnKilledAccount = ();
300
	type DbWeight = moonbase_weights::db::rocksdb::constants::RocksDbWeight;
301
	type BaseCallFilter = MaintenanceMode;
302
	type SystemWeightInfo = ();
303
	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
304
	type SS58Prefix = ConstU16<1287>;
305
	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
306
	type MaxConsumers = frame_support::traits::ConstU32<16>;
307
	type SingleBlockMigrations = ();
308
	type MultiBlockMigrator = ();
309
	type PreInherents = ();
310
	type PostInherents = ();
311
	type PostTransactions = ();
312
}
313

            
314
impl pallet_utility::Config for Runtime {
315
	type RuntimeEvent = RuntimeEvent;
316
	type RuntimeCall = RuntimeCall;
317
	type PalletsOrigin = OriginCaller;
318
	type WeightInfo = moonbase_weights::pallet_utility::WeightInfo<Runtime>;
319
}
320

            
321
impl pallet_timestamp::Config for Runtime {
322
	/// A timestamp: milliseconds since the unix epoch.
323
	type Moment = u64;
324
	type OnTimestampSet = ();
325
	type MinimumPeriod = ConstU64<3000>;
326
	type WeightInfo = moonbase_weights::pallet_timestamp::WeightInfo<Runtime>;
327
}
328

            
329
#[cfg(not(feature = "runtime-benchmarks"))]
330
parameter_types! {
331
	pub const ExistentialDeposit: Balance = 0;
332
}
333

            
334
#[cfg(feature = "runtime-benchmarks")]
335
parameter_types! {
336
	pub const ExistentialDeposit: Balance = 1;
337
}
338

            
339
impl pallet_balances::Config for Runtime {
340
	type MaxReserves = ConstU32<50>;
341
	type ReserveIdentifier = [u8; 4];
342
	type MaxLocks = ConstU32<50>;
343
	/// The type for recording an account's balance.
344
	type Balance = Balance;
345
	/// The ubiquitous event type.
346
	type RuntimeEvent = RuntimeEvent;
347
	type DustRemoval = ();
348
	type ExistentialDeposit = ExistentialDeposit;
349
	type AccountStore = System;
350
	type FreezeIdentifier = ();
351
	type MaxFreezes = ConstU32<0>;
352
	type RuntimeHoldReason = RuntimeHoldReason;
353
	type RuntimeFreezeReason = RuntimeFreezeReason;
354
	type WeightInfo = moonbase_weights::pallet_balances::WeightInfo<Runtime>;
355
}
356

            
357
pub struct DealWithFees<R>(sp_std::marker::PhantomData<R>);
358
impl<R> OnUnbalanced<Credit<R::AccountId, pallet_balances::Pallet<R>>> for DealWithFees<R>
359
where
360
	R: pallet_balances::Config + pallet_treasury::Config,
361
{
362
	// this seems to be called for substrate-based transactions
363
1
	fn on_unbalanceds<B>(
364
1
		mut fees_then_tips: impl Iterator<Item = Credit<R::AccountId, pallet_balances::Pallet<R>>>,
365
1
	) {
366
1
		if let Some(fees) = fees_then_tips.next() {
367
1
			let treasury_perbill =
368
1
				runtime_params::dynamic_params::runtime_config::FeesTreasuryProportion::get();
369
1
			let treasury_part = treasury_perbill.deconstruct();
370
1
			let burn_part = Perbill::one().deconstruct() - treasury_part;
371
1
			let (_, to_treasury) = fees.ration(burn_part, treasury_part);
372
1
			// Balances pallet automatically burns dropped Credits by decreasing
373
1
			// total_supply accordingly
374
1
			ResolveTo::<TreasuryAccountId<R>, pallet_balances::Pallet<R>>::on_unbalanced(
375
1
				to_treasury,
376
1
			);
377

            
378
			// handle tip if there is one
379
1
			if let Some(tip) = fees_then_tips.next() {
380
1
				// for now we use the same burn/treasury strategy used for regular fees
381
1
				let (_, to_treasury) = tip.ration(80, 20);
382
1
				ResolveTo::<TreasuryAccountId<R>, pallet_balances::Pallet<R>>::on_unbalanced(
383
1
					to_treasury,
384
1
				);
385
1
			}
386
		}
387
1
	}
388

            
389
	// this is called from pallet_evm for Ethereum-based transactions
390
	// (technically, it calls on_unbalanced, which calls this when non-zero)
391
128
	fn on_nonzero_unbalanced(amount: Credit<R::AccountId, pallet_balances::Pallet<R>>) {
392
128
		// Balances pallet automatically burns dropped Credits by decreasing
393
128
		// total_supply accordingly
394
128
		let (_, to_treasury) = amount.ration(80, 20);
395
128
		ResolveTo::<TreasuryAccountId<R>, pallet_balances::Pallet<R>>::on_unbalanced(to_treasury);
396
128
	}
397
}
398

            
399
pub struct LengthToFee;
400
impl WeightToFeePolynomial for LengthToFee {
401
	type Balance = Balance;
402

            
403
96
	fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
404
96
		smallvec![
405
			WeightToFeeCoefficient {
406
				degree: 1,
407
96
				coeff_frac: Perbill::zero(),
408
				coeff_integer: currency::TRANSACTION_BYTE_FEE,
409
				negative: false,
410
			},
411
			WeightToFeeCoefficient {
412
				degree: 3,
413
96
				coeff_frac: Perbill::zero(),
414
96
				coeff_integer: 1 * currency::SUPPLY_FACTOR,
415
				negative: false,
416
			},
417
		]
418
96
	}
419
}
420

            
421
impl pallet_transaction_payment::Config for Runtime {
422
	type RuntimeEvent = RuntimeEvent;
423
	type OnChargeTransaction = FungibleAdapter<Balances, DealWithFees<Runtime>>;
424
	type OperationalFeeMultiplier = ConstU8<5>;
425
	type WeightToFee = ConstantMultiplier<Balance, ConstU128<{ currency::WEIGHT_FEE }>>;
426
	type LengthToFee = LengthToFee;
427
	type FeeMultiplierUpdate = FastAdjustingFeeUpdate<Runtime>;
428
}
429

            
430
impl pallet_sudo::Config for Runtime {
431
	type RuntimeCall = RuntimeCall;
432
	type RuntimeEvent = RuntimeEvent;
433
	type WeightInfo = moonbase_weights::pallet_sudo::WeightInfo<Runtime>;
434
}
435

            
436
impl pallet_evm_chain_id::Config for Runtime {}
437

            
438
/// Current approximation of the gas/s consumption considering
439
/// EVM execution over compiled WASM (on 4.4Ghz CPU).
440
/// Given the 2 sec Weight, from which 75% only are used for transactions,
441
/// the total EVM execution gas limit is: GAS_PER_SECOND * 2 * 0.75 ~= 60_000_000.
442
pub const GAS_PER_SECOND: u64 = 40_000_000;
443

            
444
/// Approximate ratio of the amount of Weight per Gas.
445
/// u64 works for approximations because Weight is a very small unit compared to gas.
446
pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;
447
/// The highest amount of new storage that can be created in a block (160KB).
448
pub const BLOCK_STORAGE_LIMIT: u64 = 160 * 1024;
449
parameter_types! {
450
	pub BlockGasLimit: U256
451
		= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
452
	/// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less
453
	/// than this will decrease the weight and more will increase.
454
	pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(35);
455
	/// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to
456
	/// change the fees more rapidly. This fast multiplier responds by doubling/halving in
457
	/// approximately one hour at extreme block congestion levels.
458
	pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(4, 1_000);
459
	/// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure
460
	/// that combined with `AdjustmentVariable`, we can recover from the minimum.
461
	/// See `multiplier_can_grow_from_zero` in integration_tests.rs.
462
	pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10);
463
	/// Maximum multiplier. We pick a value that is expensive but not impossibly so; it should act
464
	/// as a safety net.
465
	pub MaximumMultiplier: Multiplier = Multiplier::from(100_000u128);
466
	pub PrecompilesValue: MoonbasePrecompiles<Runtime> = MoonbasePrecompiles::<_>::new();
467
	pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
468
	/// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare
469
	/// it with the pov_size for a block. E.g.
470
	/// ceil(
471
	///     (max_extrinsic.ref_time() / max_extrinsic.proof_size()) / WEIGHT_PER_GAS
472
	/// )
473
	/// We should re-check `xcm_config::Erc20XcmBridgeTransferGasLimit` when changing this value
474
	pub const GasLimitPovSizeRatio: u64 = 16;
475
	/// The amount of gas per storage (in bytes): BLOCK_GAS_LIMIT / BLOCK_STORAGE_LIMIT
476
	/// (60_000_000 / 160 kb)
477
	pub GasLimitStorageGrowthRatio: u64 = 366;
478
}
479

            
480
pub struct TransactionPaymentAsGasPrice;
481
impl FeeCalculator for TransactionPaymentAsGasPrice {
482
520
	fn min_gas_price() -> (U256, Weight) {
483
520
		// TODO: transaction-payment differs from EIP-1559 in that its tip and length fees are not
484
520
		//       scaled by the multiplier, which means its multiplier will be overstated when
485
520
		//       applied to an ethereum transaction
486
520
		// note: transaction-payment uses both a congestion modifier (next_fee_multiplier, which is
487
520
		//       updated once per block in on_finalize) and a 'WeightToFee' implementation. Our
488
520
		//       runtime implements this as a 'ConstantModifier', so we can get away with a simple
489
520
		//       multiplication here.
490
520
		// It is imperative that `saturating_mul_int` be performed as late as possible in the
491
520
		// expression since it involves fixed point multiplication with a division by a fixed
492
520
		// divisor. This leads to truncation and subsequent precision loss if performed too early.
493
520
		// This can lead to min_gas_price being same across blocks even if the multiplier changes.
494
520
		// There's still some precision loss when the final `gas_price` (used_gas * min_gas_price)
495
520
		// is computed in frontier, but that's currently unavoidable.
496
520
		let min_gas_price = TransactionPayment::next_fee_multiplier()
497
520
			.saturating_mul_int((currency::WEIGHT_FEE * 4).saturating_mul(WEIGHT_PER_GAS as u128));
498
520
		(
499
520
			min_gas_price.into(),
500
520
			<Runtime as frame_system::Config>::DbWeight::get().reads(1),
501
520
		)
502
520
	}
503
}
504

            
505
/// A "Fast" TargetedFeeAdjustment. Parameters chosen based on model described here:
506
/// https://research.web3.foundation/en/latest/polkadot/overview/2-token-economics.html#-1.-fast-adjusting-mechanism // editorconfig-checker-disable-line
507
///
508
/// The adjustment algorithm boils down to:
509
///
510
/// diff = (previous_block_weight - target) / maximum_block_weight
511
/// next_multiplier = prev_multiplier * (1 + (v * diff) + ((v * diff)^2 / 2))
512
/// assert(next_multiplier > min)
513
///     where: v is AdjustmentVariable
514
///            target is TargetBlockFullness
515
///            min is MinimumMultiplier
516
pub type FastAdjustingFeeUpdate<R> = TargetedFeeAdjustment<
517
	R,
518
	TargetBlockFullness,
519
	AdjustmentVariable,
520
	MinimumMultiplier,
521
	MaximumMultiplier,
522
>;
523

            
524
/// The author inherent provides an AccountId, but pallet evm needs an H160.
525
/// This simple adapter makes the conversion for any types T, U such that T: Into<U>
526
pub struct FindAuthorAdapter<T, U, Inner>(sp_std::marker::PhantomData<(T, U, Inner)>);
527

            
528
impl<T, U, Inner> FindAuthor<U> for FindAuthorAdapter<T, U, Inner>
529
where
530
	T: Into<U>,
531
	Inner: FindAuthor<T>,
532
{
533
6850
	fn find_author<'a, I>(digests: I) -> Option<U>
534
6850
	where
535
6850
		I: 'a + IntoIterator<Item = (sp_runtime::ConsensusEngineId, &'a [u8])>,
536
6850
	{
537
6850
		Inner::find_author(digests).map(Into::into)
538
6850
	}
539
}
540

            
541
moonbeam_runtime_common::impl_on_charge_evm_transaction!();
542

            
543
impl pallet_evm::Config for Runtime {
544
	type FeeCalculator = TransactionPaymentAsGasPrice;
545
	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
546
	type WeightPerGas = WeightPerGas;
547
	type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
548
	type CallOrigin = EnsureAddressRoot<AccountId>;
549
	type WithdrawOrigin = EnsureAddressNever<AccountId>;
550
	type AddressMapping = IdentityAddressMapping;
551
	type Currency = Balances;
552
	type RuntimeEvent = RuntimeEvent;
553
	type Runner = pallet_evm::runner::stack::Runner<Self>;
554
	type PrecompilesType = MoonbasePrecompiles<Self>;
555
	type PrecompilesValue = PrecompilesValue;
556
	type ChainId = EthereumChainId;
557
	type OnChargeTransaction = OnChargeEVMTransaction<DealWithFees<Runtime>>;
558
	type BlockGasLimit = BlockGasLimit;
559
	type FindAuthor = FindAuthorAdapter<AccountId20, H160, AuthorInherent>;
560
	type OnCreate = ();
561
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
562
	type SuicideQuickClearLimit = ConstU32<0>;
563
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
564
	type Timestamp = RelayTimestamp;
565
	type WeightInfo = moonbase_weights::pallet_evm::WeightInfo<Runtime>;
566
}
567

            
568
parameter_types! {
569
	pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
570
	pub const NoPreimagePostponement: Option<u32> = Some(10);
571
}
572

            
573
impl pallet_scheduler::Config for Runtime {
574
	type RuntimeEvent = RuntimeEvent;
575
	type RuntimeOrigin = RuntimeOrigin;
576
	type PalletsOrigin = OriginCaller;
577
	type RuntimeCall = RuntimeCall;
578
	type MaximumWeight = MaximumSchedulerWeight;
579
	type ScheduleOrigin = EnsureRoot<AccountId>;
580
	type MaxScheduledPerBlock = ConstU32<50>;
581
	type WeightInfo = moonbase_weights::pallet_scheduler::WeightInfo<Runtime>;
582
	type OriginPrivilegeCmp = EqualPrivilegeOnly;
583
	type Preimages = Preimage;
584
}
585

            
586
parameter_types! {
587
	pub const PreimageBaseDeposit: Balance = 5 * currency::UNIT * currency::SUPPLY_FACTOR ;
588
	pub const PreimageByteDeposit: Balance = currency::STORAGE_BYTE_FEE;
589
	pub const PreimageHoldReason: RuntimeHoldReason =
590
		RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
591
}
592

            
593
impl pallet_preimage::Config for Runtime {
594
	type WeightInfo = moonbase_weights::pallet_preimage::WeightInfo<Runtime>;
595
	type RuntimeEvent = RuntimeEvent;
596
	type Currency = Balances;
597
	type ManagerOrigin = EnsureRoot<AccountId>;
598
	type Consideration = HoldConsideration<
599
		AccountId,
600
		Balances,
601
		PreimageHoldReason,
602
		LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
603
	>;
604
}
605

            
606
parameter_types! {
607
	pub const ProposalBond: Permill = Permill::from_percent(5);
608
	pub const TreasuryId: PalletId = PalletId(*b"pc/trsry");
609
	pub TreasuryAccount: AccountId = Treasury::account_id();
610
}
611

            
612
type TreasuryRejectOrigin = EitherOfDiverse<
613
	EnsureRoot<AccountId>,
614
	pallet_collective::EnsureProportionMoreThan<AccountId, TreasuryCouncilInstance, 1, 2>,
615
>;
616

            
617
impl pallet_treasury::Config for Runtime {
618
	type PalletId = TreasuryId;
619
	type Currency = Balances;
620
	// More than half of the council is required (or root) to reject a proposal
621
	type RejectOrigin = TreasuryRejectOrigin;
622
	type RuntimeEvent = RuntimeEvent;
623
	type SpendPeriod = ConstU32<{ 6 * DAYS }>;
624
	type Burn = ();
625
	type BurnDestination = ();
626
	type MaxApprovals = ConstU32<100>;
627
	type WeightInfo = moonbase_weights::pallet_treasury::WeightInfo<Runtime>;
628
	type SpendFunds = ();
629
	#[cfg(not(feature = "runtime-benchmarks"))]
630
	type SpendOrigin = frame_support::traits::NeverEnsureOrigin<Balance>; // Disabled, no spending
631
	#[cfg(feature = "runtime-benchmarks")]
632
	type SpendOrigin =
633
		frame_system::EnsureWithSuccess<EnsureRoot<AccountId>, AccountId, benches::MaxBalance>;
634
	type AssetKind = ();
635
	type Beneficiary = AccountId;
636
	type BeneficiaryLookup = IdentityLookup<AccountId>;
637
	type Paymaster = PayFromAccount<Balances, TreasuryAccount>;
638
	type BalanceConverter = UnityAssetBalanceConversion;
639
	type PayoutPeriod = ConstU32<{ 30 * DAYS }>;
640
	#[cfg(feature = "runtime-benchmarks")]
641
	type BenchmarkHelper = BenchmarkHelper;
642
}
643

            
644
parameter_types! {
645
	pub const MaxSubAccounts: u32 = 100;
646
	pub const MaxAdditionalFields: u32 = 100;
647
	pub const MaxRegistrars: u32 = 20;
648
	pub const PendingUsernameExpiration: u32 = 7 * DAYS;
649
	pub const MaxSuffixLength: u32 = 7;
650
	pub const MaxUsernameLength: u32 = 32;
651
}
652

            
653
type IdentityForceOrigin =
654
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
655
type IdentityRegistrarOrigin =
656
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
657

            
658
impl pallet_identity::Config for Runtime {
659
	type RuntimeEvent = RuntimeEvent;
660
	type Currency = Balances;
661
	// Add one item in storage and take 258 bytes
662
	type BasicDeposit = ConstU128<{ currency::deposit(1, 258) }>;
663
	// Does not add any item to the storage but takes 1 bytes
664
	type ByteDeposit = ConstU128<{ currency::deposit(0, 1) }>;
665
	// Add one item in storage and take 53 bytes
666
	type SubAccountDeposit = ConstU128<{ currency::deposit(1, 53) }>;
667
	type MaxSubAccounts = MaxSubAccounts;
668
	type IdentityInformation = pallet_identity::legacy::IdentityInfo<MaxAdditionalFields>;
669
	type MaxRegistrars = MaxRegistrars;
670
	type Slashed = Treasury;
671
	type ForceOrigin = IdentityForceOrigin;
672
	type RegistrarOrigin = IdentityRegistrarOrigin;
673
	type OffchainSignature = Signature;
674
	type SigningPublicKey = <Signature as sp_runtime::traits::Verify>::Signer;
675
	type UsernameAuthorityOrigin = EnsureRoot<AccountId>;
676
	type PendingUsernameExpiration = PendingUsernameExpiration;
677
	type MaxSuffixLength = MaxSuffixLength;
678
	type MaxUsernameLength = MaxUsernameLength;
679
	type WeightInfo = moonbase_weights::pallet_identity::WeightInfo<Runtime>;
680
}
681

            
682
pub struct TransactionConverter;
683

            
684
impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {
685
21
	fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {
686
21
		UncheckedExtrinsic::new_unsigned(
687
21
			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
688
21
		)
689
21
	}
690
}
691

            
692
impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {
693
	fn convert_transaction(
694
		&self,
695
		transaction: pallet_ethereum::Transaction,
696
	) -> opaque::UncheckedExtrinsic {
697
		let extrinsic = UncheckedExtrinsic::new_unsigned(
698
			pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),
699
		);
700
		let encoded = extrinsic.encode();
701
		opaque::UncheckedExtrinsic::decode(&mut &encoded[..])
702
			.expect("Encoded extrinsic is always valid")
703
	}
704
}
705

            
706
parameter_types! {
707
	pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
708
}
709

            
710
impl pallet_ethereum::Config for Runtime {
711
	type RuntimeEvent = RuntimeEvent;
712
	type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
713
	type PostLogContent = PostBlockAndTxnHashes;
714
	type ExtraDataLength = ConstU32<30>;
715
}
716

            
717
pub struct EthereumXcmEnsureProxy;
718
impl xcm_primitives::EnsureProxy<AccountId> for EthereumXcmEnsureProxy {
719
	fn ensure_ok(delegator: AccountId, delegatee: AccountId) -> Result<(), &'static str> {
720
		// The EVM implicitely contains an Any proxy, so we only allow for "Any" proxies
721
		let def: pallet_proxy::ProxyDefinition<AccountId, ProxyType, BlockNumber> =
722
			pallet_proxy::Pallet::<Runtime>::find_proxy(
723
				&delegator,
724
				&delegatee,
725
				Some(ProxyType::Any),
726
			)
727
			.map_err(|_| "proxy error: expected `ProxyType::Any`")?;
728
		// We only allow to use it for delay zero proxies, as the call will immediatly be executed
729
		ensure!(def.delay.is_zero(), "proxy delay is Non-zero`");
730
		Ok(())
731
	}
732
}
733

            
734
impl pallet_ethereum_xcm::Config for Runtime {
735
	type RuntimeEvent = RuntimeEvent;
736
	type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
737
	type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
738
	type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
739
	type ReservedXcmpWeight = ReservedXcmpWeight;
740
	type EnsureProxy = EthereumXcmEnsureProxy;
741
	type ControllerOrigin = EnsureRoot<AccountId>;
742
	type ForceOrigin = EnsureRoot<AccountId>;
743
}
744

            
745
parameter_types! {
746
	pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
747
	pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
748
	pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
749
}
750

            
751
/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
752
/// into the relay chain.
753
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
754
/// How many parachain blocks are processed by the relay chain per parent. Limits the
755
/// number of blocks authored per slot.
756
const BLOCK_PROCESSING_VELOCITY: u32 = 1;
757

            
758
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
759
	Runtime,
760
	BLOCK_PROCESSING_VELOCITY,
761
	UNINCLUDED_SEGMENT_CAPACITY,
762
>;
763

            
764
impl cumulus_pallet_parachain_system::Config for Runtime {
765
	type RuntimeEvent = RuntimeEvent;
766
	type OnSystemEvent = ();
767
	type SelfParaId = ParachainInfo;
768
	type ReservedDmpWeight = ReservedDmpWeight;
769
	type OutboundXcmpMessageSource = XcmpQueue;
770
	type XcmpMessageHandler = XcmpQueue;
771
	type ReservedXcmpWeight = ReservedXcmpWeight;
772
	type CheckAssociatedRelayNumber = EmergencyParaXcm;
773
	type ConsensusHook = ConsensusHookWrapperForRelayTimestamp<Runtime, ConsensusHook>;
774
	type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
775
	type WeightInfo = moonbase_weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
776
}
777

            
778
impl parachain_info::Config for Runtime {}
779

            
780
pub struct OnNewRound;
781
impl pallet_parachain_staking::OnNewRound for OnNewRound {
782
40
	fn on_new_round(round_index: pallet_parachain_staking::RoundIndex) -> Weight {
783
40
		MoonbeamOrbiters::on_new_round(round_index)
784
40
	}
785
}
786
pub struct PayoutCollatorOrOrbiterReward;
787
impl pallet_parachain_staking::PayoutCollatorReward<Runtime> for PayoutCollatorOrOrbiterReward {
788
16
	fn payout_collator_reward(
789
16
		for_round: pallet_parachain_staking::RoundIndex,
790
16
		collator_id: AccountId,
791
16
		amount: Balance,
792
16
	) -> Weight {
793
16
		let extra_weight =
794
16
			if MoonbeamOrbiters::is_collator_pool_with_active_orbiter(for_round, collator_id) {
795
				MoonbeamOrbiters::distribute_rewards(for_round, collator_id, amount)
796
			} else {
797
16
				ParachainStaking::mint_collator_reward(for_round, collator_id, amount)
798
			};
799

            
800
16
		<Runtime as frame_system::Config>::DbWeight::get()
801
16
			.reads(1)
802
16
			.saturating_add(extra_weight)
803
16
	}
804
}
805

            
806
pub struct OnInactiveCollator;
807
impl pallet_parachain_staking::OnInactiveCollator<Runtime> for OnInactiveCollator {
808
	fn on_inactive_collator(
809
		collator_id: AccountId,
810
		round: pallet_parachain_staking::RoundIndex,
811
	) -> Result<Weight, DispatchErrorWithPostInfo<PostDispatchInfo>> {
812
		let extra_weight = if !MoonbeamOrbiters::is_collator_pool_with_active_orbiter(
813
			round,
814
			collator_id.clone(),
815
		) {
816
			ParachainStaking::go_offline_inner(collator_id)?;
817
			<Runtime as pallet_parachain_staking::Config>::WeightInfo::go_offline(
818
				pallet_parachain_staking::MAX_CANDIDATES,
819
			)
820
		} else {
821
			Weight::zero()
822
		};
823

            
824
		Ok(<Runtime as frame_system::Config>::DbWeight::get()
825
			.reads(1)
826
			.saturating_add(extra_weight))
827
	}
828
}
829

            
830
type MonetaryGovernanceOrigin =
831
	EitherOfDiverse<EnsureRoot<AccountId>, governance::custom_origins::GeneralAdmin>;
832

            
833
pub struct RelayChainSlotProvider;
834
impl Get<Slot> for RelayChainSlotProvider {
835
40
	fn get() -> Slot {
836
40
		let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
837
40
		slot_info.unwrap_or_default().0
838
40
	}
839
}
840

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

            
885
impl pallet_author_inherent::Config for Runtime {
886
	type SlotBeacon = RelaychainDataProvider<Self>;
887
	type AccountLookup = MoonbeamOrbiters;
888
	type CanAuthor = AuthorFilter;
889
	type AuthorId = AccountId;
890
	type WeightInfo = moonbase_weights::pallet_author_inherent::WeightInfo<Runtime>;
891
}
892

            
893
#[cfg(test)]
894
mod mock {
895
	use super::*;
896
	pub struct MockRandomness;
897
	impl frame_support::traits::Randomness<H256, BlockNumber> for MockRandomness {
898
		fn random(subject: &[u8]) -> (H256, BlockNumber) {
899
			(H256(sp_io::hashing::blake2_256(subject)), 0)
900
		}
901
	}
902
}
903

            
904
impl pallet_author_slot_filter::Config for Runtime {
905
	type RuntimeEvent = RuntimeEvent;
906
	#[cfg(not(test))]
907
	type RandomnessSource = Randomness;
908
	#[cfg(test)]
909
	type RandomnessSource = mock::MockRandomness;
910
	type PotentialAuthors = ParachainStaking;
911
	type WeightInfo = moonbase_weights::pallet_author_slot_filter::WeightInfo<Runtime>;
912
}
913

            
914
impl pallet_async_backing::Config for Runtime {
915
	type AllowMultipleBlocksPerSlot = ConstBool<true>;
916
	type GetAndVerifySlot = pallet_async_backing::RelaySlot;
917
	type ExpectedBlockTime = ConstU64<6000>;
918
}
919

            
920
parameter_types! {
921
	pub const InitializationPayment: Perbill = Perbill::from_percent(30);
922
	pub const RelaySignaturesThreshold: Perbill = Perbill::from_percent(100);
923
	pub const SignatureNetworkIdentifier:  &'static [u8] = b"moonbase-";
924

            
925
}
926

            
927
impl pallet_crowdloan_rewards::Config for Runtime {
928
	type RuntimeEvent = RuntimeEvent;
929
	type Initialized = ConstBool<false>;
930
	type InitializationPayment = InitializationPayment;
931
	type MaxInitContributors = ConstU32<500>;
932
	// TODO to be revisited
933
	type MinimumReward = ConstU128<0>;
934
	type RewardCurrency = Balances;
935
	type RelayChainAccountId = [u8; 32];
936
	type RewardAddressAssociateOrigin = EnsureSigned<Self::AccountId>;
937
	type RewardAddressChangeOrigin = EnsureSigned<Self::AccountId>;
938
	type RewardAddressRelayVoteThreshold = RelaySignaturesThreshold;
939
	type SignatureNetworkIdentifier = SignatureNetworkIdentifier;
940
	type VestingBlockNumber = relay_chain::BlockNumber;
941
	type VestingBlockProvider = RelaychainDataProvider<Self>;
942
	type WeightInfo = moonbase_weights::pallet_crowdloan_rewards::WeightInfo<Runtime>;
943
}
944

            
945
// This is a simple session key manager. It should probably either work with, or be replaced
946
// entirely by pallet sessions
947
impl pallet_author_mapping::Config for Runtime {
948
	type RuntimeEvent = RuntimeEvent;
949
	type DepositCurrency = Balances;
950
	type DepositAmount = ConstU128<{ 100 * currency::UNIT * currency::SUPPLY_FACTOR }>;
951
	type Keys = session_keys_primitives::VrfId;
952
	type WeightInfo = moonbase_weights::pallet_author_mapping::WeightInfo<Runtime>;
953
}
954

            
955
/// The type used to represent the kinds of proxying allowed.
956
#[derive(
957
	Copy,
958
	Clone,
959
	Eq,
960
	PartialEq,
961
	Ord,
962
	PartialOrd,
963
	Encode,
964
	Decode,
965
	Debug,
966
8
	MaxEncodedLen,
967
64
	TypeInfo,
968
	Serialize,
969
	Deserialize,
970
)]
971
pub enum ProxyType {
972
1
	/// All calls can be proxied. This is the trivial/most permissive filter.
973
	Any = 0,
974
1
	/// Only extrinsics that do not transfer funds.
975
	NonTransfer = 1,
976
1
	/// Only extrinsics related to governance (democracy and collectives).
977
	Governance = 2,
978
1
	/// Only extrinsics related to staking.
979
	Staking = 3,
980
1
	/// Allow to veto an announced proxy call.
981
	CancelProxy = 4,
982
1
	/// Allow extrinsic related to Balances.
983
	Balances = 5,
984
1
	/// Allow extrinsic related to AuthorMapping.
985
	AuthorMapping = 6,
986
1
	/// Allow extrinsic related to IdentityJudgement.
987
	IdentityJudgement = 7,
988
}
989

            
990
impl Default for ProxyType {
991
	fn default() -> Self {
992
		Self::Any
993
	}
994
}
995

            
996
fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool {
997
	matches!(
998
		precompile_name,
999
		PrecompileName::TreasuryCouncilInstance
			| PrecompileName::ReferendaPrecompile
			| PrecompileName::ConvictionVotingPrecompile
			| PrecompileName::PreimagePrecompile
			| PrecompileName::OpenTechCommitteeInstance,
	)
}
// Be careful: Each time this filter is modified, the substrate filter must also be modified
// consistently.
impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {
	fn is_evm_proxy_call_allowed(
		&self,
		call: &pallet_evm_precompile_proxy::EvmSubCall,
		recipient_has_code: bool,
		gas: u64,
	) -> precompile_utils::EvmResult<bool> {
		Ok(match self {
			ProxyType::Any => true,
			ProxyType::NonTransfer => {
				call.value == U256::zero()
					&& match PrecompileName::from_address(call.to.0) {
						Some(
							PrecompileName::AuthorMappingPrecompile
							| PrecompileName::IdentityPrecompile
							| 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 => {
				matches!(
					c,
					RuntimeCall::System(..)
						| RuntimeCall::ParachainSystem(..)
						| RuntimeCall::Timestamp(..)
						| RuntimeCall::ParachainStaking(..)
						| RuntimeCall::Referenda(..)
						| RuntimeCall::Preimage(..)
						| RuntimeCall::ConvictionVoting(..)
						| RuntimeCall::TreasuryCouncilCollective(..)
						| RuntimeCall::OpenTechCommitteeCollective(..)
						| RuntimeCall::Identity(..)
						| RuntimeCall::Utility(..)
						| RuntimeCall::Proxy(..) | 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 = moonbase_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) }>;
}
impl pallet_migrations::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	// TODO wire up our correct list of migrations here. Maybe this shouldn't be in
	// `moonbeam_runtime_common`.
	type MigrationsList = (
		moonbeam_runtime_common::migrations::CommonMigrations<Runtime>,
		migrations::MoonbaseMigrations,
	);
	type XcmExecutionManager = XcmExecutionManager;
}
impl pallet_moonbeam_lazy_migrations::Config for Runtime {
	type WeightInfo = moonbase_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::Assets(_) => false,
			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
/// We dont allow to create nor mint assets, this for now is disabled
/// We only allow transfers. For now creation of assets will go through
/// asset-manager, while minting/burning only happens through xcm messages
/// This can change in the future
pub struct NormalFilter;
impl Contains<RuntimeCall> for NormalFilter {
232
	fn contains(c: &RuntimeCall) -> bool {
		match c {
			RuntimeCall::Assets(method) => match method {
				pallet_assets::Call::transfer { .. } => true,
				pallet_assets::Call::transfer_keep_alive { .. } => true,
				pallet_assets::Call::approve_transfer { .. } => true,
				pallet_assets::Call::transfer_approved { .. } => true,
				pallet_assets::Call::cancel_approval { .. } => true,
				pallet_assets::Call::destroy_accounts { .. } => true,
				pallet_assets::Call::destroy_approvals { .. } => true,
				pallet_assets::Call::finish_destroy { .. } => true,
				_ => 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
8
			RuntimeCall::EVM(_) => false,
			RuntimeCall::Treasury(
				pallet_treasury::Call::spend { .. }
				| pallet_treasury::Call::payout { .. }
				| pallet_treasury::Call::check_status { .. }
				| pallet_treasury::Call::void_spend { .. },
			) => false,
224
			_ => true,
		}
232
	}
}
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;
}
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 = moonbase_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 = moonbase_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 = moonbase_weights::pallet_multisig::WeightInfo<Runtime>;
}
impl pallet_relay_storage_roots::Config for Runtime {
	type MaxStorageRoots = ConstU32<30>;
	type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Self>;
	type WeightInfo = moonbase_weights::pallet_relay_storage_roots::WeightInfo<Runtime>;
}
impl pallet_precompile_benchmarks::Config for Runtime {
	type WeightInfo = moonbase_weights::pallet_precompile_benchmarks::WeightInfo<Runtime>;
}
impl pallet_parameters::Config for Runtime {
	type AdminOrigin = EnsureRoot<AccountId>;
	type RuntimeEvent = RuntimeEvent;
	type RuntimeParameters = RuntimeParameters;
	type WeightInfo = moonbase_weights::pallet_parameters::WeightInfo<Runtime>;
}
747296
construct_runtime! {
	pub enum Runtime
	{
		System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>} = 0,
		Utility: pallet_utility::{Pallet, Call, Event} = 1,
		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2,
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 3,
		Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>} = 4,
		// Previously 5: pallet_randomness_collective_flip
		ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Event<T>} = 6,
		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Config<T>, Event<T>} = 7,
		ParachainInfo: parachain_info::{Pallet, Storage, Config<T>} = 8,
		EthereumChainId: pallet_evm_chain_id::{Pallet, Storage, Config<T>} = 9,
		EVM: pallet_evm::{Pallet, Config<T>, Call, Storage, Event<T>} = 10,
		Ethereum: pallet_ethereum::{Pallet, Call, Storage, Event, Origin, Config<T>} = 11,
		ParachainStaking: pallet_parachain_staking::{Pallet, Call, Storage, Event<T>, Config<T>} = 12,
		Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 13,
		// Previously 14: pallet_democracy::{Pallet, Storage, Config<T>, Event<T>, Call} = 14,
		// Previously 15: CouncilCollective: pallet_collective::<Instance1>
		// Previously 16: TechCommitteeCollective: pallet_collective::<Instance2>
		Treasury: pallet_treasury::{Pallet, Storage, Config<T>, Event<T>, Call} = 17,
		AuthorInherent: pallet_author_inherent::{Pallet, Call, Storage, Inherent} = 18,
		AuthorFilter: pallet_author_slot_filter::{Pallet, Call, Storage, Event, Config<T>} = 19,
		CrowdloanRewards: pallet_crowdloan_rewards::{Pallet, Call, Config<T>, Storage, Event<T>} = 20,
		AuthorMapping: pallet_author_mapping::{Pallet, Call, Config<T>, Storage, Event<T>} = 21,
		Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 22,
		MaintenanceMode: pallet_maintenance_mode::{Pallet, Call, Config<T>, Storage, Event} = 23,
		Identity: pallet_identity::{Pallet, Call, Storage, Event<T>} = 24,
		XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 25,
		CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 26,
		// Previously 27: DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>},
		PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 28,
		Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 29,
		// Previously 30: XTokens
		AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event<T>} = 31,
		Migrations: pallet_migrations::{Pallet, Storage, Config<T>, Event<T>} = 32,
		XcmTransactor: pallet_xcm_transactor::{Pallet, Call, Config<T>, Storage, Event<T>} = 33,
		ProxyGenesisCompanion: pallet_proxy_genesis_companion::{Pallet, Config<T>} = 34,
		// Previously 35: BaseFee
		// Previously 36: pallet_assets::<Instance1>
		MoonbeamOrbiters: pallet_moonbeam_orbiters::{Pallet, Call, Storage, Event<T>, Config<T>} = 37,
		EthereumXcm: pallet_ethereum_xcm::{Pallet, Call, Storage, Origin, Event<T>} = 38,
		Randomness: pallet_randomness::{Pallet, Call, Storage, Event<T>, Inherent} = 39,
		TreasuryCouncilCollective:
			pallet_collective::<Instance3>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 40,
		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 41,
		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 42,
		Origins: governance::custom_origins::{Origin} = 43,
		Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>, HoldReason} = 44,
		Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 45,
		OpenTechCommitteeCollective:
			pallet_collective::<Instance4>::{Pallet, Call, Storage, Event<T>, Origin<T>, Config<T>} = 46,
		RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event<T>} = 47,
		Erc20XcmBridge: pallet_erc20_xcm_bridge::{Pallet} = 48,
		Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 49,
		AsyncBacking: pallet_async_backing::{Pallet, Storage} = 50,
		MoonbeamLazyMigrations: pallet_moonbeam_lazy_migrations::{Pallet, Call, Storage} = 51,
		RelayStorageRoots: pallet_relay_storage_roots::{Pallet, Storage} = 52,
		PrecompileBenchmarks: pallet_precompile_benchmarks::{Pallet} = 53,
		MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 54,
		EmergencyParaXcm: pallet_emergency_para_xcm::{Pallet, Call, Storage, Event} = 55,
		EvmForeignAssets: pallet_moonbeam_foreign_assets::{Pallet, Call, Storage, Event<T>} = 56,
		Parameters: pallet_parameters = 57,
		XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>} = 58,
	}
3606165
}
/// 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 SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	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>,
	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	fp_self_contained::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic =
	fp_self_contained::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra, H160>;
/// Executive: handles dispatch to the various pallets.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
>;
#[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!(
		[pallet_utility, Utility]
		[pallet_timestamp, Timestamp]
		[pallet_balances, Balances]
		[pallet_sudo, Sudo]
		[pallet_evm, EVM]
		[pallet_assets, Assets]
		[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_identity, Identity]
		[cumulus_pallet_parachain_system, ParachainSystem]
		[cumulus_pallet_xcmp_queue, XcmpQueue]
		[pallet_message_queue, MessageQueue]
		[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
		[pallet_asset_manager, AssetManager]
		[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_relay_storage_roots, RelayStorageRoots]
		[pallet_precompile_benchmarks, PrecompileBenchmarks]
		[pallet_moonbeam_lazy_migrations, MoonbeamLazyMigrations]
		[pallet_parameters, Parameters]
		[pallet_xcm_weight_trader, XcmWeightTrader]
	);
}
// 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.
// }
// ```
758972
moonbeam_runtime_common::impl_runtime_apis_plus_common! {
758972
	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
758972
		fn validate_transaction(
8
			source: TransactionSource,
8
			xt: <Block as BlockT>::Extrinsic,
8
			block_hash: <Block as BlockT>::Hash,
8
		) -> TransactionValidity {
8
			// Filtered calls should not enter the tx pool as they'll fail if inserted.
8
			// If this call is not allowed, we return early.
8
			if !<Runtime as frame_system::Config>::BaseCallFilter::contains(&xt.0.function) {
758972
				return InvalidTransaction::Call.into();
758972
			}
758972

            
758972
			// This runtime uses Substrate's pallet transaction payment. This
758972
			// makes the chain feel like a standard Substrate chain when submitting
758972
			// frame transactions and using Substrate ecosystem tools. It has the downside that
758972
			// transaction are not prioritized by gas_price. The following code reprioritizes
758972
			// transactions to overcome this.
758972
			//
758972
			// A more elegant, ethereum-first solution is
758972
			// a pallet that replaces pallet transaction payment, and allows users
758972
			// to directly specify a gas price rather than computing an effective one.
758972
			// #HopefullySomeday
758972

            
758972
			// First we pass the transactions to the standard FRAME executive. This calculates all the
758972
			// necessary tags, longevity and other properties that we will leave unchanged.
758972
			// This also assigns some priority that we don't care about and will overwrite next.
758972
			let mut intermediate_valid = Executive::validate_transaction(source, xt.clone(), block_hash)?;
758972

            
758972
			let dispatch_info = xt.get_dispatch_info();
758972

            
758972
			// If this is a pallet ethereum transaction, then its priority is already set
758972
			// according to effective priority fee from pallet ethereum. If it is any other kind of
758972
			// transaction, we modify its priority. The goal is to arrive at a similar metric used
758972
			// by pallet ethereum, which means we derive a fee-per-gas from the txn's tip and
758972
			// weight.
758972
			Ok(match &xt.0.function {
758972
				RuntimeCall::Ethereum(transact { .. }) => intermediate_valid,
758972
				_ if dispatch_info.class != DispatchClass::Normal => intermediate_valid,
758972
				_ => {
758972
					let tip = match xt.0.signature {
758972
						None => 0,
758972
						Some((_, _, ref signed_extra)) => {
							// Yuck, this depends on the index of charge transaction in Signed Extra
							let charge_transaction = &signed_extra.7;
							charge_transaction.tip()
758972
						}
758972
					};
758972

            
758972
					let effective_gas =
						<Runtime as pallet_evm::Config>::GasWeightMapping::weight_to_gas(
							dispatch_info.weight
						);
758972
					let tip_per_gas = if effective_gas > 0 {
758972
						tip.saturating_div(effective_gas as u128)
758972
					} else {
758972
						0
758972
					};
758972

            
758972
					// Overwrite the original prioritization with this ethereum one
758972
					intermediate_valid.priority = tip_per_gas as u64;
					intermediate_valid
758972
				}
758972
			})
758972
		}
758972
	}
758972

            
758972
	impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
758972
		fn can_build_upon(
			included_hash: <Block as BlockT>::Hash,
			slot: async_backing_primitives::Slot,
		) -> bool {
			ConsensusHook::can_build_upon(included_hash, slot)
		}
758972
	}
758972
}
struct CheckInherents;
// Parity has decided to depreciate this trait, but does not offer a satisfactory replacement,
// see issue: https://github.com/paritytech/polkadot-sdk/issues/2841
#[allow(deprecated)]
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
	fn check_inherents(
		block: &Block,
		relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
	) -> sp_inherents::CheckInherentsResult {
		let relay_chain_slot = relay_state_proof
			.read_slot()
			.expect("Could not read the relay chain slot from the proof");
		let inherent_data =
			cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
				relay_chain_slot,
				sp_std::time::Duration::from_secs(6),
			)
			.create_inherent_data()
			.expect("Could not create the timestamp inherent data");
		inherent_data.check_extrinsics(block)
	}
}
// 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>,
	CheckInherents = CheckInherents,
);
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() {
1
		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_asset_manager::Call<Runtime>>() <= CALL_ALIGN as usize);
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!(std::mem::size_of::<pallet_xcm_transactor::Call<Runtime>>() <= CALL_ALIGN as usize);
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 * MICROUNIT));
		// pallet_identity deposits
1
		assert_eq!(
1
			get!(pallet_identity, BasicDeposit, u128),
1
			Balance::from(1 * UNIT + 25800 * MICROUNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_identity, ByteDeposit, u128),
1
			Balance::from(100 * MICROUNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_identity, SubAccountDeposit, u128),
1
			Balance::from(1 * UNIT + 5300 * MICROUNIT)
1
		);
		// staking minimums
1
		assert_eq!(
1
			get!(pallet_parachain_staking, MinCandidateStk, u128),
1
			Balance::from(500 * UNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_parachain_staking, MinDelegation, u128),
1
			Balance::from(1 * UNIT)
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 * UNIT)
1
		);
		// proxy deposits
1
		assert_eq!(
1
			get!(pallet_proxy, ProxyDepositBase, u128),
1
			Balance::from(1 * UNIT + 800 * MICROUNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, ProxyDepositFactor, u128),
1
			Balance::from(2100 * MICROUNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, AnnouncementDepositBase, u128),
1
			Balance::from(1 * UNIT + 800 * MICROUNIT)
1
		);
1
		assert_eq!(
1
			get!(pallet_proxy, AnnouncementDepositFactor, u128),
1
			Balance::from(5600 * MICROUNIT)
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 test_proxy_type_can_be_decoded_from_valid_values() {
1
		let test_cases = vec![
1
			// (input, expected)
1
			(0u8, ProxyType::Any),
1
			(1, ProxyType::NonTransfer),
1
			(2, ProxyType::Governance),
1
			(3, ProxyType::Staking),
1
			(4, ProxyType::CancelProxy),
1
			(5, ProxyType::Balances),
1
			(6, ProxyType::AuthorMapping),
1
			(7, ProxyType::IdentityJudgement),
1
		];
9
		for (input, expected) in test_cases {
8
			let actual = ProxyType::decode(&mut input.to_le_bytes().as_slice());
8
			assert_eq!(
8
				Ok(expected),
				actual,
				"failed decoding ProxyType for value '{}'",
				input
			);
		}
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
		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
	}
}