1
// Copyright 2021 Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

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

            
17
//! Parachain runtime mock.
18

            
19
use frame_support::{
20
	construct_runtime,
21
	dispatch::GetDispatchInfo,
22
	ensure, parameter_types,
23
	traits::{
24
		fungible::NativeOrWithId, AsEnsureOriginWithArg, ConstU32, EitherOf, Everything, Get,
25
		InstanceFilter, Nothing, PalletInfoAccess,
26
	},
27
	weights::Weight,
28
	PalletId,
29
};
30
use frame_system::{pallet_prelude::BlockNumberFor, EnsureNever, EnsureRoot};
31
use moonbeam_runtime_common::{
32
	impl_asset_conversion::AssetRateConverter, impl_multiasset_paymaster::MultiAssetPaymaster,
33
	xcm_origins::AllowSiblingParachains,
34
};
35
use pallet_moonbeam_foreign_assets::{MapSuccessToGovernance, MapSuccessToXcm};
36
use pallet_xcm::{migration::v1::VersionUncheckedMigrateToV1, EnsureXcm};
37
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
38
use sp_core::{H160, H256};
39
use sp_runtime::{
40
	traits::{BlakeTwo256, Hash, IdentityLookup, MaybeEquivalence, Zero},
41
	Permill,
42
};
43
use sp_std::{convert::TryFrom, prelude::*};
44
use xcm::{latest::prelude::*, Version as XcmVersion, VersionedXcm};
45

            
46
use cumulus_primitives_core::relay_chain::HrmpChannelId;
47
use pallet_ethereum::PostLogContent;
48
use polkadot_core_primitives::BlockNumber as RelayBlockNumber;
49
use polkadot_parachain::primitives::{Id as ParaId, Sibling};
50
use xcm::latest::{
51
	Error as XcmError, ExecuteXcm,
52
	Junction::{PalletInstance, Parachain},
53
	Location, NetworkId, Outcome, Xcm,
54
};
55
use xcm_builder::{
56
	AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
57
	AllowTopLevelPaidExecutionFrom, Case, ConvertedConcreteId, EnsureXcmOrigin, FixedWeightBounds,
58
	FungibleAdapter as XcmCurrencyAdapter, FungiblesAdapter, IsConcrete, NoChecking,
59
	ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
60
	SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation,
61
	TakeWeightCredit, WithComputedOrigin,
62
};
63
use xcm_executor::{traits::JustTry, Config, XcmExecutor};
64

            
65
#[cfg(feature = "runtime-benchmarks")]
66
use moonbeam_runtime_common::benchmarking::BenchmarkHelper as ArgumentsBenchmarkHelper;
67
pub use moonriver_runtime::xcm_config::AssetType;
68
use scale_info::TypeInfo;
69
use xcm_simulator::{
70
	DmpMessageHandlerT as DmpMessageHandler, XcmpMessageFormat,
71
	XcmpMessageHandlerT as XcmpMessageHandler,
72
};
73

            
74
pub type AccountId = moonbeam_core_primitives::AccountId;
75
pub type Balance = u128;
76
pub type AssetId = u128;
77
pub type BlockNumber = BlockNumberFor<Runtime>;
78

            
79
parameter_types! {
80
	pub const BlockHashCount: u32 = 250;
81
}
82

            
83
impl frame_system::Config for Runtime {
84
	type RuntimeOrigin = RuntimeOrigin;
85
	type RuntimeCall = RuntimeCall;
86
	type RuntimeTask = RuntimeTask;
87
	type Nonce = u64;
88
	type Block = Block;
89
	type Hash = H256;
90
	type Hashing = ::sp_runtime::traits::BlakeTwo256;
91
	type AccountId = AccountId;
92
	type Lookup = IdentityLookup<AccountId>;
93
	type RuntimeEvent = RuntimeEvent;
94
	type BlockHashCount = BlockHashCount;
95
	type BlockWeights = ();
96
	type BlockLength = ();
97
	type Version = ();
98
	type PalletInfo = PalletInfo;
99
	type AccountData = pallet_balances::AccountData<Balance>;
100
	type OnNewAccount = ();
101
	type OnKilledAccount = ();
102
	type DbWeight = ();
103
	type BaseCallFilter = Everything;
104
	type SystemWeightInfo = ();
105
	type SS58Prefix = ();
106
	type OnSetCode = ();
107
	type MaxConsumers = frame_support::traits::ConstU32<16>;
108
	type SingleBlockMigrations = ();
109
	type MultiBlockMigrator = ();
110
	type PreInherents = ();
111
	type PostInherents = ();
112
	type PostTransactions = ();
113
	type ExtensionsWeightInfo = ();
114
}
115

            
116
parameter_types! {
117
	pub ExistentialDeposit: Balance = 0;
118
	pub const MaxLocks: u32 = 50;
119
	pub const MaxReserves: u32 = 50;
120
}
121

            
122
impl pallet_balances::Config for Runtime {
123
	type MaxLocks = MaxLocks;
124
	type Balance = Balance;
125
	type RuntimeEvent = RuntimeEvent;
126
	type DustRemoval = ();
127
	type ExistentialDeposit = ExistentialDeposit;
128
	type AccountStore = System;
129
	type WeightInfo = ();
130
	type MaxReserves = MaxReserves;
131
	type ReserveIdentifier = [u8; 8];
132
	type RuntimeHoldReason = ();
133
	type FreezeIdentifier = ();
134
	type MaxFreezes = ();
135
	type RuntimeFreezeReason = ();
136
	type DoneSlashHandler = ();
137
}
138

            
139
pub type ForeignAssetInstance = ();
140

            
141
// Required for runtime benchmarks
142
pallet_assets::runtime_benchmarks_enabled! {
143
	pub struct BenchmarkHelper;
144
	impl<AssetIdParameter> pallet_assets::BenchmarkHelper<AssetIdParameter> for BenchmarkHelper
145
	where
146
		AssetIdParameter: From<u128>,
147
	{
148
		fn create_asset_id_parameter(id: u32) -> AssetIdParameter {
149
			(id as u128).into()
150
		}
151
	}
152
}
153

            
154
parameter_types! {
155
	pub const AssetDeposit: Balance = 1; // Does not really matter as this will be only called by root
156
	pub const ApprovalDeposit: Balance = 0;
157
	pub const AssetsStringLimit: u32 = 50;
158
	pub const MetadataDepositBase: Balance = 0;
159
	pub const MetadataDepositPerByte: Balance = 0;
160
	pub const AssetAccountDeposit: Balance = 0;
161
}
162

            
163
impl pallet_assets::Config<ForeignAssetInstance> for Runtime {
164
	type RuntimeEvent = RuntimeEvent;
165
	type Balance = Balance;
166
	type AssetId = AssetId;
167
	type Currency = Balances;
168
	type ForceOrigin = EnsureRoot<AccountId>;
169
	type AssetDeposit = AssetDeposit;
170
	type MetadataDepositBase = MetadataDepositBase;
171
	type MetadataDepositPerByte = MetadataDepositPerByte;
172
	type ApprovalDeposit = ApprovalDeposit;
173
	type StringLimit = AssetsStringLimit;
174
	type Freezer = ();
175
	type Extra = ();
176
	type AssetAccountDeposit = AssetAccountDeposit;
177
	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
178
	type RemoveItemsLimit = ConstU32<656>;
179
	type AssetIdParameter = AssetId;
180
	type CreateOrigin = AsEnsureOriginWithArg<EnsureNever<AccountId>>;
181
	type CallbackHandle = ();
182
	pallet_assets::runtime_benchmarks_enabled! {
183
		type BenchmarkHelper = BenchmarkHelper;
184
	}
185
}
186

            
187
/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
188
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
189
/// `Transact` in order to determine the dispatch Origin.
190
pub type LocationToAccountId = (
191
	// The parent (Relay-chain) origin converts to the default `AccountId`.
192
	ParentIsPreset<AccountId>,
193
	// Sibling parachain origins convert to AccountId via the `ParaId::into`.
194
	SiblingParachainConvertsVia<Sibling, AccountId>,
195
	AccountKey20Aliases<RelayNetwork, AccountId>,
196
	// Generate remote accounts according to polkadot standards
197
	xcm_builder::HashedDescription<
198
		AccountId,
199
		xcm_builder::DescribeFamily<xcm_builder::DescribeAllTerminal>,
200
	>,
201
);
202

            
203
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
204
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
205
/// biases the kind of local `Origin` it will become.
206
pub type XcmOriginToTransactDispatchOrigin = (
207
	// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
208
	// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
209
	// foreign chains who want to have a local sovereign account on this chain which they control.
210
	SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
211
	// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
212
	// recognised.
213
	RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
214
	// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
215
	// recognised.
216
	SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
217
	// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
218
	// transaction from the Root origin.
219
	ParentAsSuperuser<RuntimeOrigin>,
220
	// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
221
	pallet_xcm::XcmPassthrough<RuntimeOrigin>,
222
	SignedAccountKey20AsNative<RelayNetwork, RuntimeOrigin>,
223
);
224

            
225
parameter_types! {
226
	pub const UnitWeightCost: Weight = Weight::from_parts(1u64, 1u64);
227
	pub MaxInstructions: u32 = 100;
228
}
229

            
230
// Instructing how incoming xcm assets will be handled
231
pub type ForeignFungiblesTransactor = FungiblesAdapter<
232
	// Use this fungibles implementation:
233
	Assets,
234
	// Use this currency when it is a fungible asset matching the given location or name:
235
	(
236
		ConvertedConcreteId<
237
			AssetId,
238
			Balance,
239
			xcm_primitives::AsAssetType<AssetId, AssetType, AssetManager>,
240
			JustTry,
241
		>,
242
	),
243
	// Do a simple punn to convert an AccountId32 Location into a native chain account ID:
244
	LocationToAccountId,
245
	// Our chain's account ID type (we can't get away without mentioning it explicitly):
246
	AccountId,
247
	// We dont allow teleports.
248
	NoChecking,
249
	// We dont track any teleports
250
	(),
251
>;
252

            
253
pub type LocalAssetTransactor = XcmCurrencyAdapter<
254
	// Use this currency:
255
	Balances,
256
	// Use this currency when it is a fungible asset matching any of the locations in
257
	// SelfReserveRepresentations
258
	IsConcrete<SelfReserve>,
259
	// We can convert the Locations with our converter above:
260
	LocationToAccountId,
261
	// Our chain's account ID type (we can't get away without mentioning it explicitly):
262
	AccountId,
263
	// We dont allow teleport
264
	(),
265
>;
266

            
267
// We use both transactors
268
pub type AssetTransactors = (LocalAssetTransactor, ForeignFungiblesTransactor);
269

            
270
pub type XcmRouter = super::ParachainXcmRouter<MsgQueue>;
271

            
272
pub type XcmBarrier = (
273
	// Weight that is paid for may be consumed.
274
	TakeWeightCredit,
275
	// Expected responses are OK.
276
	AllowKnownQueryResponses<PolkadotXcm>,
277
	WithComputedOrigin<
278
		(
279
			// If the message is one that immediately attemps to pay for execution, then allow it.
280
			AllowTopLevelPaidExecutionFrom<Everything>,
281
			// Subscriptions for version tracking are OK.
282
			AllowSubscriptionsFrom<Everything>,
283
		),
284
		UniversalLocation,
285
		ConstU32<8>,
286
	>,
287
);
288

            
289
parameter_types! {
290
	/// Xcm fees will go to the treasury account
291
	pub XcmFeesAccount: AccountId = Treasury::account_id();
292
	/// Parachain token units per second of execution
293
	pub ParaTokensPerSecond: u128 = 1000000000000;
294
}
295

            
296
pub struct WeightToFee;
297
impl sp_weights::WeightToFee for WeightToFee {
298
	type Balance = Balance;
299

            
300
49
	fn weight_to_fee(weight: &Weight) -> Self::Balance {
301
		use sp_runtime::SaturatedConversion as _;
302
49
		Self::Balance::saturated_from(weight.ref_time())
303
49
			.saturating_mul(ParaTokensPerSecond::get())
304
49
			.saturating_div(frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND as u128)
305
49
	}
306
}
307

            
308
parameter_types! {
309
	pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
310
	pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
311
	pub UniversalLocation: InteriorLocation =
312
		[GlobalConsensus(RelayNetwork::get()), Parachain(MsgQueue::parachain_id().into())].into();
313
	pub SelfReserve: Location = Location {
314
		parents:0,
315
		interior: [
316
			PalletInstance(<Balances as PalletInfoAccess>::index() as u8)
317
		].into()
318
	};
319
	pub const MaxAssetsIntoHolding: u32 = 64;
320

            
321
	pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
322
	pub RelayLocationFilter: AssetFilter = Wild(AllOf {
323
		fun: WildFungible,
324
		id: xcm::prelude::AssetId(Location::parent()),
325
	});
326

            
327
	pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = (
328
		RelayLocationFilter::get(),
329
		AssetHubLocation::get()
330
	);
331
}
332

            
333
use frame_system::RawOrigin;
334
use sp_runtime::traits::PostDispatchInfoOf;
335
use sp_runtime::DispatchErrorWithPostInfo;
336
use xcm_executor::traits::CallDispatcher;
337
moonbeam_runtime_common::impl_moonbeam_xcm_call!();
338

            
339
type Reserves = (
340
	// Relaychain (DOT) from Asset Hub
341
	Case<RelayChainNativeAssetFromAssetHub>,
342
	// Assets which the reserve is the same as the origin.
343
	xcm_primitives::MultiNativeAsset<
344
		xcm_primitives::AbsoluteAndRelativeReserve<SelfLocationAbsolute>,
345
	>,
346
);
347

            
348
pub struct XcmConfig;
349
impl Config for XcmConfig {
350
	type RuntimeCall = RuntimeCall;
351
	type XcmSender = XcmRouter;
352
	type AssetTransactor = AssetTransactors;
353
	type OriginConverter = XcmOriginToTransactDispatchOrigin;
354
	type IsReserve = Reserves;
355
	type IsTeleporter = ();
356
	type UniversalLocation = UniversalLocation;
357
	type Barrier = XcmBarrier;
358
	type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
359
	type Trader = pallet_xcm_weight_trader::Trader<Runtime>;
360
	type ResponseHandler = PolkadotXcm;
361
	type SubscriptionService = PolkadotXcm;
362
	type AssetTrap = PolkadotXcm;
363
	type AssetClaims = PolkadotXcm;
364
	type CallDispatcher = MoonbeamCall;
365
	type AssetLocker = ();
366
	type AssetExchanger = ();
367
	type PalletInstancesInfo = ();
368
	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
369
	type FeeManager = ();
370
	type MessageExporter = ();
371
	type UniversalAliases = Nothing;
372
	type SafeCallFilter = Everything;
373
	type Aliasers = Nothing;
374
	type TransactionalProcessor = ();
375
	type HrmpNewChannelOpenRequestHandler = ();
376
	type HrmpChannelAcceptedHandler = ();
377
	type HrmpChannelClosingHandler = ();
378
	type XcmRecorder = PolkadotXcm;
379
}
380

            
381
impl cumulus_pallet_xcm::Config for Runtime {
382
	type RuntimeEvent = RuntimeEvent;
383
	type XcmExecutor = XcmExecutor<XcmConfig>;
384
}
385

            
386
// Our currencyId. We distinguish for now between SelfReserve, and Others, defined by their Id.
387
#[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)]
388
pub enum CurrencyId {
389
	SelfReserve,
390
	ForeignAsset(AssetId),
391
}
392

            
393
// How to convert from CurrencyId to Location
394
pub struct CurrencyIdToLocation<AssetXConverter>(sp_std::marker::PhantomData<AssetXConverter>);
395
impl<AssetXConverter> sp_runtime::traits::Convert<CurrencyId, Option<Location>>
396
	for CurrencyIdToLocation<AssetXConverter>
397
where
398
	AssetXConverter: MaybeEquivalence<Location, AssetId>,
399
{
400
25
	fn convert(currency: CurrencyId) -> Option<Location> {
401
25
		match currency {
402
			CurrencyId::SelfReserve => {
403
				// For now and until Xtokens is adapted to handle 0.9.16 version we use
404
				// the old anchoring here
405
				// This is not a problem in either cases, since the view of the destination
406
				// chain does not change
407
				// TODO! change this to NewAnchoringSelfReserve once xtokens is adapted for it
408
8
				let multi: Location = SelfReserve::get();
409
8
				Some(multi)
410
			}
411
17
			CurrencyId::ForeignAsset(asset) => AssetXConverter::convert_back(&asset),
412
		}
413
25
	}
414
}
415

            
416
parameter_types! {
417
	pub const BaseXcmWeight: Weight = Weight::from_parts(100u64, 100u64);
418
	pub const MaxAssetsForTransfer: usize = 2;
419
	pub SelfLocation: Location = Location::here();
420
	pub SelfLocationAbsolute: Location = Location {
421
		parents:1,
422
		interior: [
423
			Parachain(MsgQueue::parachain_id().into())
424
		].into()
425
	};
426
}
427

            
428
parameter_types! {
429
	pub const ProposalBond: Permill = Permill::from_percent(5);
430
	pub const ProposalBondMinimum: Balance = 0;
431
	pub const SpendPeriod: u32 = 0;
432
	pub const TreasuryId: PalletId = PalletId(*b"pc/trsry");
433
	pub const MaxApprovals: u32 = 100;
434
	pub TreasuryAccount: AccountId = Treasury::account_id();
435
}
436

            
437
impl pallet_treasury::Config for Runtime {
438
	type PalletId = TreasuryId;
439
	type Currency = Balances;
440
	type RejectOrigin = EnsureRoot<AccountId>;
441
	type RuntimeEvent = RuntimeEvent;
442
	type SpendPeriod = SpendPeriod;
443
	type Burn = ();
444
	type BurnDestination = ();
445
	type MaxApprovals = MaxApprovals;
446
	type WeightInfo = ();
447
	type SpendFunds = ();
448
	type SpendOrigin = frame_support::traits::NeverEnsureOrigin<Balance>; // Same as Polkadot
449
	type AssetKind = NativeOrWithId<AssetId>;
450
	type Beneficiary = AccountId;
451
	type BeneficiaryLookup = IdentityLookup<AccountId>;
452
	type Paymaster = MultiAssetPaymaster<Runtime, TreasuryAccount, Balances>;
453
	type BalanceConverter = AssetRateConverter<Runtime, Balances>;
454
	type PayoutPeriod = ConstU32<0>;
455
	#[cfg(feature = "runtime-benchmarks")]
456
	type BenchmarkHelper = ArgumentsBenchmarkHelper;
457
	type BlockNumberProvider = System;
458
}
459

            
460
#[frame_support::pallet]
461
pub mod mock_msg_queue {
462
	use super::*;
463
	use frame_support::pallet_prelude::*;
464

            
465
	#[pallet::config]
466
	pub trait Config: frame_system::Config {
467
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
468
		type XcmExecutor: ExecuteXcm<Self::RuntimeCall>;
469
	}
470

            
471
	#[pallet::call]
472
	impl<T: Config> Pallet<T> {}
473

            
474
1
	#[pallet::pallet]
475
	pub struct Pallet<T>(_);
476

            
477
1161
	#[pallet::storage]
478
	#[pallet::getter(fn parachain_id)]
479
	pub(super) type ParachainId<T: Config> = StorageValue<_, ParaId, ValueQuery>;
480

            
481
	impl<T: Config> Get<ParaId> for Pallet<T> {
482
50
		fn get() -> ParaId {
483
50
			Self::parachain_id()
484
50
		}
485
	}
486

            
487
	pub type MessageId = [u8; 32];
488

            
489
	#[pallet::event]
490
54
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
491
	pub enum Event<T: Config> {
492
		// XCMP
493
5
		/// Some XCM was executed OK.
494
		Success(Option<T::Hash>),
495
		/// Some XCM failed.
496
		Fail(Option<T::Hash>, XcmError),
497
		/// Bad XCM version used.
498
		BadVersion(Option<T::Hash>),
499
		/// Bad XCM format used.
500
		BadFormat(Option<T::Hash>),
501

            
502
		// DMP
503
		/// Downward message is invalid XCM.
504
		InvalidFormat(MessageId),
505
		/// Downward message is unsupported version of XCM.
506
		UnsupportedVersion(MessageId),
507
4
		/// Downward message executed with the given outcome.
508
		ExecutedDownward(MessageId, Outcome),
509
	}
510

            
511
	impl<T: Config> Pallet<T> {
512
246
		pub fn set_para_id(para_id: ParaId) {
513
246
			ParachainId::<T>::put(para_id);
514
246
		}
515

            
516
34
		fn handle_xcmp_message(
517
34
			sender: ParaId,
518
34
			_sent_at: RelayBlockNumber,
519
34
			xcm: VersionedXcm<T::RuntimeCall>,
520
34
			max_weight: Weight,
521
34
		) -> Result<Weight, XcmError> {
522
34
			let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
523
34
			let (result, event) = match Xcm::<T::RuntimeCall>::try_from(xcm) {
524
34
				Ok(xcm) => {
525
34
					let location = Location::new(1, [Parachain(sender.into())]);
526
34
					let mut id = [0u8; 32];
527
34
					id.copy_from_slice(hash.as_ref());
528
34
					match T::XcmExecutor::prepare_and_execute(
529
34
						location,
530
34
						xcm,
531
34
						&mut id,
532
34
						max_weight,
533
34
						Weight::zero(),
534
34
					) {
535
						Outcome::Error { error } => {
536
							(Err(error.clone()), Event::Fail(Some(hash), error))
537
						}
538
33
						Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))),
539
						// As far as the caller is concerned, this was dispatched without error, so
540
						// we just report the weight used.
541
1
						Outcome::Incomplete { used, error } => {
542
1
							(Ok(used), Event::Fail(Some(hash), error))
543
						}
544
					}
545
				}
546
				Err(()) => (
547
					Err(XcmError::UnhandledXcmVersion),
548
					Event::BadVersion(Some(hash)),
549
				),
550
			};
551
34
			Self::deposit_event(event);
552
34
			result
553
34
		}
554
	}
555

            
556
	impl<T: Config> XcmpMessageHandler for Pallet<T> {
557
34
		fn handle_xcmp_messages<'a, I: Iterator<Item = (ParaId, RelayBlockNumber, &'a [u8])>>(
558
34
			iter: I,
559
34
			max_weight: Weight,
560
34
		) -> Weight {
561
68
			for (sender, sent_at, data) in iter {
562
34
				let mut data_ref = data;
563
34
				let _ = XcmpMessageFormat::decode(&mut data_ref)
564
34
					.expect("Simulator encodes with versioned xcm format; qed");
565
34

            
566
34
				let mut remaining_fragments = &data_ref[..];
567
68
				while !remaining_fragments.is_empty() {
568
34
					if let Ok(xcm) =
569
34
						VersionedXcm::<T::RuntimeCall>::decode(&mut remaining_fragments)
570
34
					{
571
34
						let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight);
572
34
					} else {
573
						debug_assert!(false, "Invalid incoming XCMP message data");
574
					}
575
				}
576
			}
577
34
			max_weight
578
34
		}
579
	}
580

            
581
	impl<T: Config> DmpMessageHandler for Pallet<T> {
582
20
		fn handle_dmp_messages(
583
20
			iter: impl Iterator<Item = (RelayBlockNumber, Vec<u8>)>,
584
20
			limit: Weight,
585
20
		) -> Weight {
586
20
			for (_i, (_sent_at, data)) in iter.enumerate() {
587
20
				let mut id = sp_io::hashing::blake2_256(&data[..]);
588
20
				let maybe_msg = VersionedXcm::<T::RuntimeCall>::decode(&mut &data[..])
589
20
					.map(Xcm::<T::RuntimeCall>::try_from);
590
20
				match maybe_msg {
591
					Err(_) => {
592
						Self::deposit_event(Event::InvalidFormat(id));
593
					}
594
					Ok(Err(())) => {
595
						Self::deposit_event(Event::UnsupportedVersion(id));
596
					}
597
20
					Ok(Ok(x)) => {
598
20
						let outcome = T::XcmExecutor::prepare_and_execute(
599
20
							Parent,
600
20
							x,
601
20
							&mut id,
602
20
							limit,
603
20
							Weight::zero(),
604
20
						);
605
20

            
606
20
						Self::deposit_event(Event::ExecutedDownward(id, outcome));
607
20
					}
608
				}
609
			}
610
20
			limit
611
20
		}
612
	}
613
}
614

            
615
// Pallet to provide the version, used to test runtime upgrade version changes
616
#[frame_support::pallet]
617
pub mod mock_version_changer {
618
	use super::*;
619
	use frame_support::pallet_prelude::*;
620

            
621
	#[pallet::config]
622
	pub trait Config: frame_system::Config {
623
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
624
	}
625

            
626
	#[pallet::call]
627
	impl<T: Config> Pallet<T> {}
628

            
629
1
	#[pallet::pallet]
630
	pub struct Pallet<T>(_);
631

            
632
22
	#[pallet::storage]
633
	#[pallet::getter(fn current_version)]
634
	pub(super) type CurrentVersion<T: Config> = StorageValue<_, XcmVersion, ValueQuery>;
635

            
636
	impl<T: Config> Get<XcmVersion> for Pallet<T> {
637
4
		fn get() -> XcmVersion {
638
4
			Self::current_version()
639
4
		}
640
	}
641

            
642
	#[pallet::event]
643
5
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
644
	pub enum Event<T: Config> {
645
		// XCMP
646
6
		/// Some XCM was executed OK.
647
		VersionChanged(XcmVersion),
648
	}
649

            
650
	impl<T: Config> Pallet<T> {
651
5
		pub fn set_version(version: XcmVersion) {
652
5
			CurrentVersion::<T>::put(version);
653
5
			Self::deposit_event(Event::VersionChanged(version));
654
5
		}
655
	}
656
}
657

            
658
impl mock_msg_queue::Config for Runtime {
659
	type RuntimeEvent = RuntimeEvent;
660
	type XcmExecutor = XcmExecutor<XcmConfig>;
661
}
662

            
663
impl mock_version_changer::Config for Runtime {
664
	type RuntimeEvent = RuntimeEvent;
665
}
666

            
667
pub type LocalOriginToLocation =
668
	xcm_primitives::SignedToAccountId20<RuntimeOrigin, AccountId, RelayNetwork>;
669

            
670
parameter_types! {
671
	pub MatcherLocation: Location = Location::here();
672
}
673

            
674
impl pallet_xcm::Config for Runtime {
675
	type RuntimeEvent = RuntimeEvent;
676
	type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
677
	type XcmRouter = XcmRouter;
678
	type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
679
	type XcmExecuteFilter = frame_support::traits::Nothing;
680
	type XcmExecutor = XcmExecutor<XcmConfig>;
681
	// Do not allow teleports
682
	type XcmTeleportFilter = Nothing;
683
	type XcmReserveTransferFilter = Everything;
684
	type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
685
	type UniversalLocation = UniversalLocation;
686
	type RuntimeOrigin = RuntimeOrigin;
687
	type RuntimeCall = RuntimeCall;
688
	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
689
	// We use a custom one to test runtime ugprades
690
	type AdvertisedXcmVersion = XcmVersioner;
691
	type Currency = Balances;
692
	type CurrencyMatcher = IsConcrete<MatcherLocation>;
693
	type TrustedLockers = ();
694
	type SovereignAccountOf = ();
695
	type MaxLockers = ConstU32<8>;
696
	type WeightInfo = pallet_xcm::TestWeightInfo;
697
	type MaxRemoteLockConsumers = ConstU32<0>;
698
	type RemoteLockConsumerIdentifier = ();
699
	type AdminOrigin = frame_system::EnsureRoot<AccountId>;
700
}
701

            
702
// We instruct how to register the Assets
703
// In this case, we tell it to Create an Asset in pallet-assets
704
pub struct AssetRegistrar;
705
use frame_support::pallet_prelude::DispatchResult;
706
impl pallet_asset_manager::AssetRegistrar<Runtime> for AssetRegistrar {
707
35
	fn create_foreign_asset(
708
35
		asset: AssetId,
709
35
		min_balance: Balance,
710
35
		metadata: AssetMetadata,
711
35
		is_sufficient: bool,
712
35
	) -> DispatchResult {
713
35
		Assets::force_create(
714
35
			RuntimeOrigin::root(),
715
35
			asset,
716
35
			AssetManager::account_id(),
717
35
			is_sufficient,
718
35
			min_balance,
719
35
		)?;
720

            
721
35
		Assets::force_set_metadata(
722
35
			RuntimeOrigin::root(),
723
35
			asset,
724
35
			metadata.name,
725
35
			metadata.symbol,
726
35
			metadata.decimals,
727
35
			false,
728
35
		)
729
35
	}
730

            
731
	fn destroy_foreign_asset(asset: AssetId) -> DispatchResult {
732
		// Mark the asset as destroying
733
		Assets::start_destroy(RuntimeOrigin::root(), asset.into())?;
734

            
735
		Ok(())
736
	}
737

            
738
	fn destroy_asset_dispatch_info_weight(asset: AssetId) -> Weight {
739
		RuntimeCall::Assets(
740
			pallet_assets::Call::<Runtime, ForeignAssetInstance>::start_destroy {
741
				id: asset.into(),
742
			},
743
		)
744
		.get_dispatch_info()
745
		.total_weight()
746
	}
747
}
748

            
749
#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)]
750
pub struct AssetMetadata {
751
	pub name: Vec<u8>,
752
	pub symbol: Vec<u8>,
753
	pub decimals: u8,
754
}
755

            
756
impl pallet_asset_manager::Config for Runtime {
757
	type RuntimeEvent = RuntimeEvent;
758
	type Balance = Balance;
759
	type AssetId = AssetId;
760
	type AssetRegistrarMetadata = AssetMetadata;
761
	type ForeignAssetType = AssetType;
762
	type AssetRegistrar = AssetRegistrar;
763
	type ForeignAssetModifierOrigin = EnsureRoot<AccountId>;
764
	type WeightInfo = ();
765
}
766

            
767
pub struct AccountIdToH160;
768
impl sp_runtime::traits::Convert<AccountId, H160> for AccountIdToH160 {
769
	fn convert(account_id: AccountId) -> H160 {
770
		account_id.into()
771
	}
772
}
773

            
774
pub struct EvmForeignAssetIdFilter;
775
impl frame_support::traits::Contains<AssetId> for EvmForeignAssetIdFilter {
776
	fn contains(asset_id: &AssetId) -> bool {
777
		use xcm_primitives::AssetTypeGetter as _;
778
		// We should return true only if the AssetId doesn't exist in AssetManager
779
		AssetManager::get_asset_type(*asset_id).is_none()
780
	}
781
}
782

            
783
pub type ForeignAssetManagerOrigin = EitherOf<
784
	MapSuccessToXcm<EnsureXcm<AllowSiblingParachains>>,
785
	MapSuccessToGovernance<EnsureRoot<AccountId>>,
786
>;
787

            
788
moonbeam_runtime_common::impl_evm_runner_precompile_or_eth_xcm!();
789

            
790
parameter_types! {
791
	pub ForeignAssetCreationDeposit: u128 = 100 * currency::MOVR;
792
}
793

            
794
impl pallet_moonbeam_foreign_assets::Config for Runtime {
795
	type AccountIdToH160 = AccountIdToH160;
796
	type AssetIdFilter = EvmForeignAssetIdFilter;
797
	type EvmRunner = EvmRunnerPrecompileOrEthXcm<MoonbeamCall, Self>;
798
	type ConvertLocation =
799
		SiblingParachainConvertsVia<polkadot_parachain::primitives::Sibling, AccountId>;
800
	type ForeignAssetCreatorOrigin = ForeignAssetManagerOrigin;
801
	type ForeignAssetFreezerOrigin = ForeignAssetManagerOrigin;
802
	type ForeignAssetModifierOrigin = ForeignAssetManagerOrigin;
803
	type ForeignAssetUnfreezerOrigin = ForeignAssetManagerOrigin;
804
	type OnForeignAssetCreated = ();
805
	type MaxForeignAssets = ConstU32<256>;
806
	type RuntimeEvent = RuntimeEvent;
807
	type WeightInfo = ();
808
	type XcmLocationToH160 = LocationToH160;
809
	type ForeignAssetCreationDeposit = ForeignAssetCreationDeposit;
810
	type Balance = Balance;
811
	type Currency = Balances;
812
}
813

            
814
// 1 KSM should be enough
815
parameter_types! {
816
	pub MaxHrmpRelayFee: Asset = (Location::parent(), 1_000_000_000_000u128).into();
817
}
818

            
819
impl pallet_xcm_transactor::Config for Runtime {
820
	type RuntimeEvent = RuntimeEvent;
821
	type Balance = Balance;
822
	type Transactor = MockTransactors;
823
	type DerivativeAddressRegistrationOrigin = EnsureRoot<AccountId>;
824
	type SovereignAccountDispatcherOrigin = frame_system::EnsureRoot<AccountId>;
825
	type CurrencyId = CurrencyId;
826
	type AccountIdToLocation = xcm_primitives::AccountIdToLocation<AccountId>;
827
	type CurrencyIdToLocation = CurrencyIdToLocation<(
828
		EvmForeignAssets,
829
		AsAssetType<moonbeam_core_primitives::AssetId, AssetType, AssetManager>,
830
	)>;
831
	type SelfLocation = SelfLocation;
832
	type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
833
	type UniversalLocation = UniversalLocation;
834
	type XcmSender = XcmRouter;
835
	type BaseXcmWeight = BaseXcmWeight;
836
	type AssetTransactor = AssetTransactors;
837
	type ReserveProvider = xcm_primitives::AbsoluteAndRelativeReserve<SelfLocationAbsolute>;
838
	type WeightInfo = ();
839
	type HrmpManipulatorOrigin = EnsureRoot<AccountId>;
840
	type HrmpOpenOrigin = EnsureRoot<AccountId>;
841
	type MaxHrmpFee = xcm_builder::Case<MaxHrmpRelayFee>;
842
}
843

            
844
parameter_types! {
845
	pub RelayLocation: Location = Location::parent();
846
}
847

            
848
impl pallet_xcm_weight_trader::Config for Runtime {
849
	type AccountIdToLocation = xcm_primitives::AccountIdToLocation<AccountId>;
850
	type AddSupportedAssetOrigin = EnsureRoot<AccountId>;
851
	type AssetLocationFilter = Everything;
852
	type AssetTransactor = AssetTransactors;
853
	type Balance = Balance;
854
	type EditSupportedAssetOrigin = EnsureRoot<AccountId>;
855
	type NativeLocation = SelfReserve;
856
	type PauseSupportedAssetOrigin = EnsureRoot<AccountId>;
857
	type RemoveSupportedAssetOrigin = EnsureRoot<AccountId>;
858
	type RuntimeEvent = RuntimeEvent;
859
	type ResumeSupportedAssetOrigin = EnsureRoot<AccountId>;
860
	type WeightInfo = ();
861
	type WeightToFee = WeightToFee;
862
	type XcmFeesAccount = XcmFeesAccount;
863
	#[cfg(feature = "runtime-benchmarks")]
864
	type NotFilteredLocation = RelayLocation;
865
}
866

            
867
parameter_types! {
868
	pub const MinimumPeriod: u64 = 1000;
869
}
870
impl pallet_timestamp::Config for Runtime {
871
	type Moment = u64;
872
	type OnTimestampSet = ();
873
	type MinimumPeriod = MinimumPeriod;
874
	type WeightInfo = ();
875
}
876

            
877
parameter_types! {
878
	pub BlockGasLimit: U256 = U256::from(u64::MAX);
879
	pub WeightPerGas: Weight = Weight::from_parts(1, 0);
880
	pub GasLimitPovSizeRatio: u64 = {
881
		let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
882
		block_gas_limit.saturating_div(MAX_POV_SIZE as u64)
883
	};
884
	pub GasLimitStorageGrowthRatio: u64 =
885
		BlockGasLimit::get().min(u64::MAX.into()).low_u64().saturating_div(BLOCK_STORAGE_LIMIT);
886
}
887

            
888
impl pallet_evm::Config for Runtime {
889
	type FeeCalculator = ();
890
	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
891
	type WeightPerGas = WeightPerGas;
892

            
893
	type CallOrigin = pallet_evm::EnsureAddressRoot<AccountId>;
894
	type WithdrawOrigin = pallet_evm::EnsureAddressNever<AccountId>;
895

            
896
	type AddressMapping = pallet_evm::IdentityAddressMapping;
897
	type Currency = Balances;
898
	type Runner = pallet_evm::runner::stack::Runner<Self>;
899

            
900
	type RuntimeEvent = RuntimeEvent;
901
	type PrecompilesType = ();
902
	type PrecompilesValue = ();
903
	type ChainId = ();
904
	type BlockGasLimit = BlockGasLimit;
905
	type OnChargeTransaction = ();
906
	type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
907
	type FindAuthor = ();
908
	type OnCreate = ();
909
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
910
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
911
	type Timestamp = Timestamp;
912
	type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
913
	type AccountProvider = FrameSystemAccountProvider<Runtime>;
914
}
915

            
916
#[allow(dead_code)]
917
pub struct NormalFilter;
918

            
919
impl frame_support::traits::Contains<RuntimeCall> for NormalFilter {
920
	fn contains(c: &RuntimeCall) -> bool {
921
		match c {
922
			_ => true,
923
		}
924
	}
925
}
926

            
927
// We need to use the encoding from the relay mock runtime
928
#[derive(Encode, Decode)]
929
pub enum RelayCall {
930
	#[codec(index = 5u8)]
931
	// the index should match the position of the module in `construct_runtime!`
932
	Utility(UtilityCall),
933
	#[codec(index = 6u8)]
934
	// the index should match the position of the module in `construct_runtime!`
935
	Hrmp(HrmpCall),
936
}
937

            
938
#[derive(Encode, Decode)]
939
pub enum UtilityCall {
940
	#[codec(index = 1u8)]
941
	AsDerivative(u16),
942
}
943

            
944
// HRMP call encoding, needed for xcm transactor pallet
945
#[derive(Encode, Decode)]
946
pub enum HrmpCall {
947
	#[codec(index = 0u8)]
948
	InitOpenChannel(ParaId, u32, u32),
949
	#[codec(index = 1u8)]
950
	AcceptOpenChannel(ParaId),
951
	#[codec(index = 2u8)]
952
	CloseChannel(HrmpChannelId),
953
	#[codec(index = 6u8)]
954
	CancelOpenRequest(HrmpChannelId, u32),
955
}
956

            
957
#[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)]
958
pub enum MockTransactors {
959
	Relay,
960
}
961

            
962
impl xcm_primitives::XcmTransact for MockTransactors {
963
3
	fn destination(self) -> Location {
964
3
		match self {
965
3
			MockTransactors::Relay => Location::parent(),
966
3
		}
967
3
	}
968
}
969

            
970
impl xcm_primitives::UtilityEncodeCall for MockTransactors {
971
7
	fn encode_call(self, call: xcm_primitives::UtilityAvailableCalls) -> Vec<u8> {
972
7
		match self {
973
7
			MockTransactors::Relay => match call {
974
7
				xcm_primitives::UtilityAvailableCalls::AsDerivative(a, b) => {
975
7
					let mut call =
976
7
						RelayCall::Utility(UtilityCall::AsDerivative(a.clone())).encode();
977
7
					call.append(&mut b.clone());
978
7
					call
979
7
				}
980
7
			},
981
7
		}
982
7
	}
983
}
984

            
985
#[allow(dead_code)]
986
pub struct MockHrmpEncoder;
987

            
988
impl xcm_primitives::HrmpEncodeCall for MockHrmpEncoder {
989
	fn hrmp_encode_call(
990
		call: xcm_primitives::HrmpAvailableCalls,
991
	) -> Result<Vec<u8>, xcm::latest::Error> {
992
		match call {
993
			xcm_primitives::HrmpAvailableCalls::InitOpenChannel(a, b, c) => Ok(RelayCall::Hrmp(
994
				HrmpCall::InitOpenChannel(a.clone(), b.clone(), c.clone()),
995
			)
996
			.encode()),
997
			xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(a) => {
998
				Ok(RelayCall::Hrmp(HrmpCall::AcceptOpenChannel(a.clone())).encode())
999
			}
			xcm_primitives::HrmpAvailableCalls::CloseChannel(a) => {
				Ok(RelayCall::Hrmp(HrmpCall::CloseChannel(a.clone())).encode())
			}
			xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(a, b) => {
				Ok(RelayCall::Hrmp(HrmpCall::CancelOpenRequest(a.clone(), b.clone())).encode())
			}
		}
	}
}
parameter_types! {
	pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
}
impl pallet_ethereum::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type StateRoot =
		pallet_ethereum::IntermediateStateRoot<<Runtime as frame_system::Config>::Version>;
	type PostLogContent = PostBlockAndTxnHashes;
	type ExtraDataLength = ConstU32<30>;
}
parameter_types! {
	pub ReservedXcmpWeight: Weight = Weight::from_parts(u64::max_value(), 0);
}
#[derive(
	Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo,
)]
pub enum ProxyType {
	NotAllowed = 0,
1
	Any = 1,
}
impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {}
impl InstanceFilter<RuntimeCall> for ProxyType {
	fn filter(&self, _c: &RuntimeCall) -> bool {
		match self {
			ProxyType::NotAllowed => false,
			ProxyType::Any => true,
		}
	}
	fn is_superset(&self, _o: &Self) -> bool {
		false
	}
}
impl Default for ProxyType {
	fn default() -> Self {
		Self::NotAllowed
	}
}
parameter_types! {
	pub const ProxyCost: u64 = 1;
}
impl pallet_proxy::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type Currency = Balances;
	type ProxyType = ProxyType;
	type ProxyDepositBase = ProxyCost;
	type ProxyDepositFactor = ProxyCost;
	type MaxProxies = ConstU32<32>;
	type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
	type MaxPending = ConstU32<32>;
	type CallHasher = BlakeTwo256;
	type AnnouncementDepositBase = ProxyCost;
	type AnnouncementDepositFactor = ProxyCost;
}
pub struct EthereumXcmEnsureProxy;
impl xcm_primitives::EnsureProxy<AccountId> for EthereumXcmEnsureProxy {
2
	fn ensure_ok(delegator: AccountId, delegatee: AccountId) -> Result<(), &'static str> {
		// The EVM implicitely contains an Any proxy, so we only allow for "Any" proxies
1
		let def: pallet_proxy::ProxyDefinition<AccountId, ProxyType, BlockNumber> =
2
			pallet_proxy::Pallet::<Runtime>::find_proxy(
2
				&delegator,
2
				&delegatee,
2
				Some(ProxyType::Any),
2
			)
2
			.map_err(|_| "proxy error: expected `ProxyType::Any`")?;
		// We only allow to use it for delay zero proxies, as the call will iMmediatly be executed
1
		ensure!(def.delay.is_zero(), "proxy delay is Non-zero`");
1
		Ok(())
2
	}
}
impl pallet_ethereum_xcm::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
	type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
	type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
	type ReservedXcmpWeight = ReservedXcmpWeight;
	type EnsureProxy = EthereumXcmEnsureProxy;
	type ControllerOrigin = EnsureRoot<AccountId>;
	type ForceOrigin = EnsureRoot<AccountId>;
}
type Block = frame_system::mocking::MockBlockU32<Runtime>;
10099
construct_runtime!(
1896
	pub enum Runtime	{
1896
		System: frame_system,
1896
		Balances: pallet_balances,
1896
		MsgQueue: mock_msg_queue,
1896
		XcmVersioner: mock_version_changer,
1896

            
1896
		PolkadotXcm: pallet_xcm,
1896
		Assets: pallet_assets,
1896
		CumulusXcm: cumulus_pallet_xcm,
1896
		AssetManager: pallet_asset_manager,
1896
		XcmTransactor: pallet_xcm_transactor,
1896
		XcmWeightTrader: pallet_xcm_weight_trader,
1896
		Treasury: pallet_treasury,
1896
		Proxy: pallet_proxy,
1896

            
1896
		Timestamp: pallet_timestamp,
1896
		EVM: pallet_evm,
1896
		Ethereum: pallet_ethereum,
1896
		EthereumXcm: pallet_ethereum_xcm,
1896
		EvmForeignAssets: pallet_moonbeam_foreign_assets,
1896
	}
10291
);
6
pub(crate) fn para_events() -> Vec<RuntimeEvent> {
6
	System::events()
6
		.into_iter()
62
		.map(|r| r.event)
62
		.filter_map(|e| Some(e))
6
		.collect::<Vec<_>>()
6
}
use frame_support::traits::{OnFinalize, OnInitialize, UncheckedOnRuntimeUpgrade};
use moonriver_runtime::{currency, xcm_config::LocationToH160, BLOCK_STORAGE_LIMIT, MAX_POV_SIZE};
use pallet_evm::FrameSystemAccountProvider;
use xcm_primitives::AsAssetType;
2
pub(crate) fn on_runtime_upgrade() {
2
	VersionUncheckedMigrateToV1::<Runtime>::on_runtime_upgrade();
2
}
3
pub(crate) fn para_roll_to(n: BlockNumber) {
6
	while System::block_number() < n {
3
		PolkadotXcm::on_finalize(System::block_number());
3
		Balances::on_finalize(System::block_number());
3
		System::on_finalize(System::block_number());
3
		System::set_block_number(System::block_number() + 1);
3
		System::on_initialize(System::block_number());
3
		Balances::on_initialize(System::block_number());
3
		PolkadotXcm::on_initialize(System::block_number());
3
	}
3
}