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

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

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

            
71
pub type AccountId = moonbeam_core_primitives::AccountId;
72
pub type Balance = u128;
73
pub type AssetId = u128;
74
pub type BlockNumber = BlockNumberFor<Runtime>;
75

            
76
parameter_types! {
77
	pub const BlockHashCount: u32 = 250;
78
}
79

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

            
113
parameter_types! {
114
	pub ExistentialDeposit: Balance = 0;
115
	pub const MaxLocks: u32 = 50;
116
	pub const MaxReserves: u32 = 50;
117
}
118

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

            
136
/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
137
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
138
/// `Transact` in order to determine the dispatch Origin.
139
pub type LocationToAccountId = (
140
	// The parent (Relay-chain) origin converts to the default `AccountId`.
141
	ParentIsPreset<AccountId>,
142
	// Sibling parachain origins convert to AccountId via the `ParaId::into`.
143
	SiblingParachainConvertsVia<Sibling, AccountId>,
144
	AccountKey20Aliases<RelayNetwork, AccountId>,
145
	// Generate remote accounts according to polkadot standards
146
	xcm_builder::HashedDescription<
147
		AccountId,
148
		xcm_builder::DescribeFamily<xcm_builder::DescribeAllTerminal>,
149
	>,
150
);
151

            
152
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
153
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
154
/// biases the kind of local `Origin` it will become.
155
pub type XcmOriginToTransactDispatchOrigin = (
156
	// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
157
	// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
158
	// foreign chains who want to have a local sovereign account on this chain which they control.
159
	SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
160
	// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
161
	// recognised.
162
	RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
163
	// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
164
	// recognised.
165
	SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
166
	// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
167
	// transaction from the Root origin.
168
	ParentAsSuperuser<RuntimeOrigin>,
169
	// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
170
	pallet_xcm::XcmPassthrough<RuntimeOrigin>,
171
	SignedAccountKey20AsNative<RelayNetwork, RuntimeOrigin>,
172
);
173

            
174
parameter_types! {
175
	pub const UnitWeightCost: Weight = Weight::from_parts(1u64, 1u64);
176
	pub MaxInstructions: u32 = 100;
177
}
178

            
179
pub type LocalAssetTransactor = FungibleAdapter<
180
	// Use this currency:
181
	Balances,
182
	// Use this currency when it is a fungible asset matching any of the locations in
183
	// SelfReserveRepresentations
184
	IsConcrete<SelfReserve>,
185
	// We can convert the Locations with our converter above:
186
	LocationToAccountId,
187
	// Our chain's account ID type (we can't get away without mentioning it explicitly):
188
	AccountId,
189
	// We dont allow teleport
190
	(),
191
>;
192

            
193
// We use both transactors
194
pub type AssetTransactors = (LocalAssetTransactor, EvmForeignAssets);
195

            
196
pub type XcmRouter = super::ParachainXcmRouter<MsgQueue>;
197

            
198
pub type XcmBarrier = (
199
	// Weight that is paid for may be consumed.
200
	TakeWeightCredit,
201
	// Expected responses are OK.
202
	AllowKnownQueryResponses<PolkadotXcm>,
203
	WithComputedOrigin<
204
		(
205
			// If the message is one that immediately attemps to pay for execution, then allow it.
206
			AllowTopLevelPaidExecutionFrom<Everything>,
207
			// Subscriptions for version tracking are OK.
208
			AllowSubscriptionsFrom<Everything>,
209
		),
210
		UniversalLocation,
211
		ConstU32<8>,
212
	>,
213
);
214

            
215
parameter_types! {
216
	/// Xcm fees will go to the treasury account
217
	pub XcmFeesAccount: AccountId = Treasury::account_id();
218
	/// Parachain token units per second of execution
219
	pub ParaTokensPerSecond: u128 = 1000000000000;
220
}
221

            
222
pub struct WeightToFee;
223
impl sp_weights::WeightToFee for WeightToFee {
224
	type Balance = Balance;
225

            
226
49
	fn weight_to_fee(weight: &Weight) -> Self::Balance {
227
		use sp_runtime::SaturatedConversion as _;
228
49
		Self::Balance::saturated_from(weight.ref_time())
229
49
			.saturating_mul(ParaTokensPerSecond::get())
230
49
			.saturating_div(frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND as u128)
231
49
	}
232
}
233

            
234
parameter_types! {
235
	pub RelayNetwork: NetworkId = moonriver_runtime::xcm_config::RelayNetwork::get();
236
	pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
237
	pub UniversalLocation: InteriorLocation =
238
		[GlobalConsensus(RelayNetwork::get()), Parachain(MsgQueue::parachain_id().into())].into();
239
	pub SelfReserve: Location = Location {
240
		parents:0,
241
		interior: [
242
			PalletInstance(<Balances as PalletInfoAccess>::index() as u8)
243
		].into()
244
	};
245
	pub const MaxAssetsIntoHolding: u32 = 64;
246

            
247
	pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
248
	pub RelayLocationFilter: AssetFilter = Wild(AllOf {
249
		fun: WildFungible,
250
		id: xcm::prelude::AssetId(Location::parent()),
251
	});
252

            
253
	pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = (
254
		RelayLocationFilter::get(),
255
		AssetHubLocation::get()
256
	);
257
}
258

            
259
use frame_system::RawOrigin;
260
use sp_runtime::traits::PostDispatchInfoOf;
261
use sp_runtime::DispatchErrorWithPostInfo;
262
use xcm_executor::traits::CallDispatcher;
263
moonbeam_runtime_common::impl_moonbeam_xcm_call!();
264

            
265
type Reserves = (
266
	// Relaychain (DOT) from Asset Hub
267
	Case<RelayChainNativeAssetFromAssetHub>,
268
	// Assets which the reserve is the same as the origin.
269
	xcm_primitives::MultiNativeAsset<
270
		xcm_primitives::AbsoluteAndRelativeReserve<SelfLocationAbsolute>,
271
	>,
272
);
273

            
274
pub struct XcmConfig;
275
impl Config for XcmConfig {
276
	type RuntimeCall = RuntimeCall;
277
	type XcmSender = XcmRouter;
278
	type AssetTransactor = AssetTransactors;
279
	type OriginConverter = XcmOriginToTransactDispatchOrigin;
280
	type IsReserve = Reserves;
281
	type IsTeleporter = ();
282
	type UniversalLocation = UniversalLocation;
283
	type Barrier = XcmBarrier;
284
	type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
285
	type Trader = pallet_xcm_weight_trader::Trader<Runtime>;
286
	type ResponseHandler = PolkadotXcm;
287
	type SubscriptionService = PolkadotXcm;
288
	type AssetTrap = PolkadotXcm;
289
	type AssetClaims = PolkadotXcm;
290
	type CallDispatcher = MoonbeamCall;
291
	type AssetLocker = ();
292
	type AssetExchanger = ();
293
	type PalletInstancesInfo = ();
294
	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
295
	type FeeManager = ();
296
	type MessageExporter = ();
297
	type UniversalAliases = Nothing;
298
	type SafeCallFilter = Everything;
299
	type Aliasers = Nothing;
300
	type TransactionalProcessor = ();
301
	type HrmpNewChannelOpenRequestHandler = ();
302
	type HrmpChannelAcceptedHandler = ();
303
	type HrmpChannelClosingHandler = ();
304
	type XcmRecorder = PolkadotXcm;
305
	type XcmEventEmitter = PolkadotXcm;
306
}
307

            
308
impl cumulus_pallet_xcm::Config for Runtime {
309
	type RuntimeEvent = RuntimeEvent;
310
	type XcmExecutor = XcmExecutor<XcmConfig>;
311
}
312

            
313
// Our currencyId. We distinguish for now between SelfReserve, and Others, defined by their Id.
314
#[derive(
315
	Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo, DecodeWithMemTracking,
316
)]
317
pub enum CurrencyId {
318
	SelfReserve,
319
	ForeignAsset(AssetId),
320
}
321

            
322
// How to convert from CurrencyId to Location
323
pub struct CurrencyIdToLocation<AssetXConverter>(sp_std::marker::PhantomData<AssetXConverter>);
324
impl<AssetXConverter> sp_runtime::traits::Convert<CurrencyId, Option<Location>>
325
	for CurrencyIdToLocation<AssetXConverter>
326
where
327
	AssetXConverter: MaybeEquivalence<Location, AssetId>,
328
{
329
25
	fn convert(currency: CurrencyId) -> Option<Location> {
330
25
		match currency {
331
			CurrencyId::SelfReserve => {
332
				// For now and until Xtokens is adapted to handle 0.9.16 version we use
333
				// the old anchoring here
334
				// This is not a problem in either cases, since the view of the destination
335
				// chain does not change
336
				// TODO! change this to NewAnchoringSelfReserve once xtokens is adapted for it
337
8
				let multi: Location = SelfReserve::get();
338
8
				Some(multi)
339
			}
340
17
			CurrencyId::ForeignAsset(asset) => AssetXConverter::convert_back(&asset),
341
		}
342
25
	}
343
}
344

            
345
parameter_types! {
346
	pub const BaseXcmWeight: Weight = Weight::from_parts(100u64, 100u64);
347
	pub const MaxAssetsForTransfer: usize = 2;
348
	pub SelfLocation: Location = Location::here();
349
	pub SelfLocationAbsolute: Location = Location {
350
		parents:1,
351
		interior: [
352
			Parachain(MsgQueue::parachain_id().into())
353
		].into()
354
	};
355
}
356

            
357
parameter_types! {
358
	pub const ProposalBond: Permill = Permill::from_percent(5);
359
	pub const ProposalBondMinimum: Balance = 0;
360
	pub const SpendPeriod: u32 = 0;
361
	pub const TreasuryId: PalletId = PalletId(*b"pc/trsry");
362
	pub const MaxApprovals: u32 = 100;
363
	pub TreasuryAccount: AccountId = Treasury::account_id();
364
}
365

            
366
impl pallet_treasury::Config for Runtime {
367
	type PalletId = TreasuryId;
368
	type Currency = Balances;
369
	type RejectOrigin = EnsureRoot<AccountId>;
370
	type RuntimeEvent = RuntimeEvent;
371
	type SpendPeriod = SpendPeriod;
372
	type Burn = ();
373
	type BurnDestination = ();
374
	type MaxApprovals = MaxApprovals;
375
	type WeightInfo = ();
376
	type SpendFunds = ();
377
	type SpendOrigin = frame_support::traits::NeverEnsureOrigin<Balance>; // Same as Polkadot
378
	type AssetKind = NativeOrWithId<AssetId>;
379
	type Beneficiary = AccountId;
380
	type BeneficiaryLookup = IdentityLookup<AccountId>;
381
	type Paymaster = MultiAssetPaymaster<Runtime, TreasuryAccount, Balances>;
382
	type BalanceConverter = AssetRateConverter<Runtime, Balances>;
383
	type PayoutPeriod = ConstU32<0>;
384
	#[cfg(feature = "runtime-benchmarks")]
385
	type BenchmarkHelper = ArgumentsBenchmarkHelper;
386
	type BlockNumberProvider = System;
387
}
388

            
389
#[frame_support::pallet]
390
pub mod mock_msg_queue {
391
	use super::*;
392
	use frame_support::pallet_prelude::*;
393

            
394
	#[pallet::config]
395
	pub trait Config: frame_system::Config {
396
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
397
		type XcmExecutor: ExecuteXcm<Self::RuntimeCall>;
398
	}
399

            
400
	#[pallet::call]
401
	impl<T: Config> Pallet<T> {}
402

            
403
3
	#[pallet::pallet]
404
	pub struct Pallet<T>(_);
405

            
406
1158
	#[pallet::storage]
407
	#[pallet::getter(fn parachain_id)]
408
	pub(super) type ParachainId<T: Config> = StorageValue<_, ParaId, ValueQuery>;
409

            
410
	impl<T: Config> Get<ParaId> for Pallet<T> {
411
50
		fn get() -> ParaId {
412
50
			Self::parachain_id()
413
50
		}
414
	}
415

            
416
	pub type MessageId = [u8; 32];
417

            
418
	#[pallet::event]
419
53
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
420
	pub enum Event<T: Config> {
421
		// XCMP
422
		/// Some XCM was executed OK.
423
		Success(Option<T::Hash>),
424
		/// Some XCM failed.
425
		Fail(Option<T::Hash>, XcmError),
426
		/// Bad XCM version used.
427
		BadVersion(Option<T::Hash>),
428
		/// Bad XCM format used.
429
		BadFormat(Option<T::Hash>),
430

            
431
		// DMP
432
		/// Downward message is invalid XCM.
433
		InvalidFormat(MessageId),
434
		/// Downward message is unsupported version of XCM.
435
		UnsupportedVersion(MessageId),
436
		/// Downward message executed with the given outcome.
437
		ExecutedDownward(MessageId, Outcome),
438
	}
439

            
440
	impl<T: Config> Pallet<T> {
441
246
		pub fn set_para_id(para_id: ParaId) {
442
246
			ParachainId::<T>::put(para_id);
443
246
		}
444

            
445
34
		fn handle_xcmp_message(
446
34
			sender: ParaId,
447
34
			_sent_at: RelayBlockNumber,
448
34
			xcm: VersionedXcm<T::RuntimeCall>,
449
34
			max_weight: Weight,
450
34
		) -> Result<Weight, XcmError> {
451
34
			let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
452
34
			let (result, event) = match Xcm::<T::RuntimeCall>::try_from(xcm) {
453
34
				Ok(xcm) => {
454
34
					let location = Location::new(1, [Parachain(sender.into())]);
455
34
					let mut id = [0u8; 32];
456
34
					id.copy_from_slice(hash.as_ref());
457
34
					match T::XcmExecutor::prepare_and_execute(
458
34
						location,
459
34
						xcm,
460
34
						&mut id,
461
34
						max_weight,
462
34
						Weight::zero(),
463
34
					) {
464
						Outcome::Error { error } => {
465
							(Err(error.clone()), Event::Fail(Some(hash), error))
466
						}
467
33
						Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))),
468
						// As far as the caller is concerned, this was dispatched without error, so
469
						// we just report the weight used.
470
1
						Outcome::Incomplete { used, error } => {
471
1
							(Ok(used), Event::Fail(Some(hash), error))
472
						}
473
					}
474
				}
475
				Err(()) => (
476
					Err(XcmError::UnhandledXcmVersion),
477
					Event::BadVersion(Some(hash)),
478
				),
479
			};
480
34
			Self::deposit_event(event);
481
34
			result
482
34
		}
483
	}
484

            
485
	impl<T: Config> XcmpMessageHandler for Pallet<T> {
486
34
		fn handle_xcmp_messages<'a, I: Iterator<Item = (ParaId, RelayBlockNumber, &'a [u8])>>(
487
34
			iter: I,
488
34
			max_weight: Weight,
489
34
		) -> Weight {
490
68
			for (sender, sent_at, data) in iter {
491
34
				let mut data_ref = data;
492
34
				let _ = XcmpMessageFormat::decode(&mut data_ref)
493
34
					.expect("Simulator encodes with versioned xcm format; qed");
494
34

            
495
34
				let mut remaining_fragments = &data_ref[..];
496
68
				while !remaining_fragments.is_empty() {
497
34
					if let Ok(xcm) =
498
34
						VersionedXcm::<T::RuntimeCall>::decode(&mut remaining_fragments)
499
34
					{
500
34
						let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight);
501
34
					} else {
502
						debug_assert!(false, "Invalid incoming XCMP message data");
503
					}
504
				}
505
			}
506
34
			max_weight
507
34
		}
508
	}
509

            
510
	impl<T: Config> DmpMessageHandler for Pallet<T> {
511
19
		fn handle_dmp_messages(
512
19
			iter: impl Iterator<Item = (RelayBlockNumber, Vec<u8>)>,
513
19
			limit: Weight,
514
19
		) -> Weight {
515
19
			for (_i, (_sent_at, data)) in iter.enumerate() {
516
19
				let mut id = sp_io::hashing::blake2_256(&data[..]);
517
19
				let maybe_msg = VersionedXcm::<T::RuntimeCall>::decode(&mut &data[..])
518
19
					.map(Xcm::<T::RuntimeCall>::try_from);
519
19
				match maybe_msg {
520
					Err(_) => {
521
						Self::deposit_event(Event::InvalidFormat(id));
522
					}
523
					Ok(Err(())) => {
524
						Self::deposit_event(Event::UnsupportedVersion(id));
525
					}
526
19
					Ok(Ok(x)) => {
527
19
						let outcome = T::XcmExecutor::prepare_and_execute(
528
19
							Parent,
529
19
							x,
530
19
							&mut id,
531
19
							limit,
532
19
							Weight::zero(),
533
19
						);
534
19

            
535
19
						Self::deposit_event(Event::ExecutedDownward(id, outcome));
536
19
					}
537
				}
538
			}
539
19
			limit
540
19
		}
541
	}
542
}
543

            
544
// Pallet to provide the version, used to test runtime upgrade version changes
545
#[frame_support::pallet]
546
pub mod mock_version_changer {
547
	use super::*;
548
	use frame_support::pallet_prelude::*;
549

            
550
	#[pallet::config]
551
	pub trait Config: frame_system::Config {
552
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
553
	}
554

            
555
	#[pallet::call]
556
	impl<T: Config> Pallet<T> {}
557

            
558
3
	#[pallet::pallet]
559
	pub struct Pallet<T>(_);
560

            
561
22
	#[pallet::storage]
562
	#[pallet::getter(fn current_version)]
563
	pub(super) type CurrentVersion<T: Config> = StorageValue<_, XcmVersion, ValueQuery>;
564

            
565
	impl<T: Config> Get<XcmVersion> for Pallet<T> {
566
4
		fn get() -> XcmVersion {
567
4
			Self::current_version()
568
4
		}
569
	}
570

            
571
	#[pallet::event]
572
5
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
573
	pub enum Event<T: Config> {
574
		// XCMP
575
		/// Some XCM was executed OK.
576
		VersionChanged(XcmVersion),
577
	}
578

            
579
	impl<T: Config> Pallet<T> {
580
5
		pub fn set_version(version: XcmVersion) {
581
5
			CurrentVersion::<T>::put(version);
582
5
			Self::deposit_event(Event::VersionChanged(version));
583
5
		}
584
	}
585
}
586

            
587
impl mock_msg_queue::Config for Runtime {
588
	type RuntimeEvent = RuntimeEvent;
589
	type XcmExecutor = XcmExecutor<XcmConfig>;
590
}
591

            
592
impl mock_version_changer::Config for Runtime {
593
	type RuntimeEvent = RuntimeEvent;
594
}
595

            
596
pub type LocalOriginToLocation =
597
	xcm_primitives::SignedToAccountId20<RuntimeOrigin, AccountId, RelayNetwork>;
598

            
599
parameter_types! {
600
	pub MatcherLocation: Location = Location::here();
601
}
602

            
603
impl pallet_xcm::Config for Runtime {
604
	type RuntimeEvent = RuntimeEvent;
605
	type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
606
	type XcmRouter = XcmRouter;
607
	type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
608
	type XcmExecuteFilter = frame_support::traits::Nothing;
609
	type XcmExecutor = XcmExecutor<XcmConfig>;
610
	// Do not allow teleports
611
	type XcmTeleportFilter = Nothing;
612
	type XcmReserveTransferFilter = Everything;
613
	type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
614
	type UniversalLocation = UniversalLocation;
615
	type RuntimeOrigin = RuntimeOrigin;
616
	type RuntimeCall = RuntimeCall;
617
	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
618
	// We use a custom one to test runtime upgrades
619
	type AdvertisedXcmVersion = XcmVersioner;
620
	type Currency = Balances;
621
	type CurrencyMatcher = IsConcrete<MatcherLocation>;
622
	type TrustedLockers = ();
623
	type SovereignAccountOf = ();
624
	type MaxLockers = ConstU32<8>;
625
	type WeightInfo = pallet_xcm::TestWeightInfo;
626
	type MaxRemoteLockConsumers = ConstU32<0>;
627
	type RemoteLockConsumerIdentifier = ();
628
	type AdminOrigin = frame_system::EnsureRoot<AccountId>;
629
	type AuthorizedAliasConsideration = Disabled;
630
	type AssetHubMigrationStarted = ConstBool<false>;
631
}
632

            
633
#[derive(
634
	Clone,
635
	Default,
636
	Eq,
637
	Debug,
638
	PartialEq,
639
	Ord,
640
	PartialOrd,
641
	Encode,
642
	Decode,
643
	TypeInfo,
644
	DecodeWithMemTracking,
645
)]
646
pub struct AssetMetadata {
647
	pub name: Vec<u8>,
648
	pub symbol: Vec<u8>,
649
	pub decimals: u8,
650
}
651

            
652
pub struct AccountIdToH160;
653
impl sp_runtime::traits::Convert<AccountId, H160> for AccountIdToH160 {
654
250
	fn convert(account_id: AccountId) -> H160 {
655
250
		account_id.into()
656
250
	}
657
}
658

            
659
pub struct EvmForeignAssetIdFilter;
660
impl frame_support::traits::Contains<AssetId> for EvmForeignAssetIdFilter {
661
35
	fn contains(_asset_id: &AssetId) -> bool {
662
35
		true
663
35
	}
664
}
665

            
666
pub type ForeignAssetManagerOrigin = EitherOf<
667
	MapSuccessToXcm<EnsureXcm<AllowSiblingParachains>>,
668
	MapSuccessToGovernance<EnsureRoot<AccountId>>,
669
>;
670

            
671
moonbeam_runtime_common::impl_evm_runner_precompile_or_eth_xcm!();
672

            
673
parameter_types! {
674
	pub ForeignAssetCreationDeposit: u128 = 100 * currency::MOVR;
675
}
676

            
677
impl pallet_moonbeam_foreign_assets::Config for Runtime {
678
	type AccountIdToH160 = AccountIdToH160;
679
	type AssetIdFilter = EvmForeignAssetIdFilter;
680
	type EvmRunner = EvmRunnerPrecompileOrEthXcm<MoonbeamCall, Self>;
681
	type ConvertLocation =
682
		SiblingParachainConvertsVia<polkadot_parachain::primitives::Sibling, AccountId>;
683
	type ForeignAssetCreatorOrigin = ForeignAssetManagerOrigin;
684
	type ForeignAssetFreezerOrigin = ForeignAssetManagerOrigin;
685
	type ForeignAssetModifierOrigin = ForeignAssetManagerOrigin;
686
	type ForeignAssetUnfreezerOrigin = ForeignAssetManagerOrigin;
687
	type OnForeignAssetCreated = ();
688
	type MaxForeignAssets = ConstU32<256>;
689
	type RuntimeEvent = RuntimeEvent;
690
	type WeightInfo = ();
691
	type XcmLocationToH160 = LocationToH160;
692
	type ForeignAssetCreationDeposit = ForeignAssetCreationDeposit;
693
	type Balance = Balance;
694
	type Currency = Balances;
695
}
696

            
697
// 1 KSM should be enough
698
parameter_types! {
699
	pub MaxHrmpRelayFee: Asset = (Location::parent(), 1_000_000_000_000u128).into();
700
}
701

            
702
impl pallet_xcm_transactor::Config for Runtime {
703
	type RuntimeEvent = RuntimeEvent;
704
	type Balance = Balance;
705
	type Transactor = MockTransactors;
706
	type DerivativeAddressRegistrationOrigin = EnsureRoot<AccountId>;
707
	type SovereignAccountDispatcherOrigin = frame_system::EnsureRoot<AccountId>;
708
	type CurrencyId = CurrencyId;
709
	type AccountIdToLocation = xcm_primitives::AccountIdToLocation<AccountId>;
710
	type CurrencyIdToLocation = CurrencyIdToLocation<EvmForeignAssets>;
711
	type SelfLocation = SelfLocation;
712
	type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
713
	type UniversalLocation = UniversalLocation;
714
	type XcmSender = XcmRouter;
715
	type BaseXcmWeight = BaseXcmWeight;
716
	type AssetTransactor = AssetTransactors;
717
	type ReserveProvider = xcm_primitives::AbsoluteAndRelativeReserve<SelfLocationAbsolute>;
718
	type WeightInfo = ();
719
	type HrmpManipulatorOrigin = EnsureRoot<AccountId>;
720
	type HrmpOpenOrigin = EnsureRoot<AccountId>;
721
	type MaxHrmpFee = xcm_builder::Case<MaxHrmpRelayFee>;
722
}
723

            
724
parameter_types! {
725
	pub RelayLocation: Location = Location::parent();
726
}
727

            
728
impl pallet_xcm_weight_trader::Config for Runtime {
729
	type AccountIdToLocation = xcm_primitives::AccountIdToLocation<AccountId>;
730
	type AddSupportedAssetOrigin = EnsureRoot<AccountId>;
731
	type AssetLocationFilter = Everything;
732
	type AssetTransactor = AssetTransactors;
733
	type Balance = Balance;
734
	type EditSupportedAssetOrigin = EnsureRoot<AccountId>;
735
	type NativeLocation = SelfReserve;
736
	type PauseSupportedAssetOrigin = EnsureRoot<AccountId>;
737
	type RemoveSupportedAssetOrigin = EnsureRoot<AccountId>;
738
	type RuntimeEvent = RuntimeEvent;
739
	type ResumeSupportedAssetOrigin = EnsureRoot<AccountId>;
740
	type WeightInfo = ();
741
	type WeightToFee = WeightToFee;
742
	type XcmFeesAccount = XcmFeesAccount;
743
	#[cfg(feature = "runtime-benchmarks")]
744
	type NotFilteredLocation = RelayLocation;
745
}
746

            
747
parameter_types! {
748
	pub const MinimumPeriod: u64 = 1000;
749
}
750
impl pallet_timestamp::Config for Runtime {
751
	type Moment = u64;
752
	type OnTimestampSet = ();
753
	type MinimumPeriod = MinimumPeriod;
754
	type WeightInfo = ();
755
}
756

            
757
parameter_types! {
758
	pub BlockGasLimit: U256 = moonriver_runtime::BlockGasLimit::get();
759
	pub WeightPerGas: Weight = moonriver_runtime::WeightPerGas::get();
760
	pub const GasLimitPovSizeRatio: u64 = moonriver_runtime::GasLimitPovSizeRatio::get();
761
	pub GasLimitStorageGrowthRatio: u64 = moonriver_runtime::GasLimitStorageGrowthRatio::get();
762
}
763

            
764
impl pallet_evm::Config for Runtime {
765
	type FeeCalculator = ();
766
	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
767
	type WeightPerGas = WeightPerGas;
768

            
769
	type CallOrigin = pallet_evm::EnsureAddressRoot<AccountId>;
770
	type WithdrawOrigin = pallet_evm::EnsureAddressNever<AccountId>;
771

            
772
	type AddressMapping = pallet_evm::IdentityAddressMapping;
773
	type Currency = Balances;
774
	type Runner = pallet_evm::runner::stack::Runner<Self>;
775

            
776
	type RuntimeEvent = RuntimeEvent;
777
	type PrecompilesType = ();
778
	type PrecompilesValue = ();
779
	type ChainId = ();
780
	type BlockGasLimit = BlockGasLimit;
781
	type OnChargeTransaction = ();
782
	type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
783
	type FindAuthor = ();
784
	type OnCreate = ();
785
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
786
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
787
	type Timestamp = Timestamp;
788
	type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
789
	type AccountProvider = FrameSystemAccountProvider<Runtime>;
790
	type CreateOriginFilter = ();
791
	type CreateInnerOriginFilter = ();
792
}
793

            
794
#[allow(dead_code)]
795
pub struct NormalFilter;
796

            
797
impl frame_support::traits::Contains<RuntimeCall> for NormalFilter {
798
	fn contains(c: &RuntimeCall) -> bool {
799
		match c {
800
			_ => true,
801
		}
802
	}
803
}
804

            
805
// We need to use the encoding from the relay mock runtime
806
#[derive(Encode, Decode)]
807
pub enum RelayCall {
808
	#[codec(index = 5u8)]
809
	// the index should match the position of the module in `construct_runtime!`
810
	Utility(UtilityCall),
811
	#[codec(index = 6u8)]
812
	// the index should match the position of the module in `construct_runtime!`
813
	Hrmp(HrmpCall),
814
}
815

            
816
#[derive(Encode, Decode)]
817
pub enum UtilityCall {
818
	#[codec(index = 1u8)]
819
	AsDerivative(u16),
820
}
821

            
822
// HRMP call encoding, needed for xcm transactor pallet
823
#[derive(Encode, Decode)]
824
pub enum HrmpCall {
825
	#[codec(index = 0u8)]
826
	InitOpenChannel(ParaId, u32, u32),
827
	#[codec(index = 1u8)]
828
	AcceptOpenChannel(ParaId),
829
	#[codec(index = 2u8)]
830
	CloseChannel(HrmpChannelId),
831
	#[codec(index = 6u8)]
832
	CancelOpenRequest(HrmpChannelId, u32),
833
}
834

            
835
#[derive(
836
	Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo, DecodeWithMemTracking,
837
)]
838
pub enum MockTransactors {
839
	Relay,
840
}
841

            
842
impl xcm_primitives::XcmTransact for MockTransactors {
843
3
	fn destination(self) -> Location {
844
3
		match self {
845
3
			MockTransactors::Relay => Location::parent(),
846
3
		}
847
3
	}
848
}
849

            
850
impl xcm_primitives::UtilityEncodeCall for MockTransactors {
851
7
	fn encode_call(self, call: xcm_primitives::UtilityAvailableCalls) -> Vec<u8> {
852
7
		match self {
853
7
			MockTransactors::Relay => match call {
854
7
				xcm_primitives::UtilityAvailableCalls::AsDerivative(a, b) => {
855
7
					let mut call =
856
7
						RelayCall::Utility(UtilityCall::AsDerivative(a.clone())).encode();
857
7
					call.append(&mut b.clone());
858
7
					call
859
7
				}
860
7
			},
861
7
		}
862
7
	}
863
}
864

            
865
#[allow(dead_code)]
866
pub struct MockHrmpEncoder;
867

            
868
impl xcm_primitives::HrmpEncodeCall for MockHrmpEncoder {
869
	fn hrmp_encode_call(
870
		call: xcm_primitives::HrmpAvailableCalls,
871
	) -> Result<Vec<u8>, xcm::latest::Error> {
872
		match call {
873
			xcm_primitives::HrmpAvailableCalls::InitOpenChannel(a, b, c) => Ok(RelayCall::Hrmp(
874
				HrmpCall::InitOpenChannel(a.clone(), b.clone(), c.clone()),
875
			)
876
			.encode()),
877
			xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(a) => {
878
				Ok(RelayCall::Hrmp(HrmpCall::AcceptOpenChannel(a.clone())).encode())
879
			}
880
			xcm_primitives::HrmpAvailableCalls::CloseChannel(a) => {
881
				Ok(RelayCall::Hrmp(HrmpCall::CloseChannel(a.clone())).encode())
882
			}
883
			xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(a, b) => {
884
				Ok(RelayCall::Hrmp(HrmpCall::CancelOpenRequest(a.clone(), b.clone())).encode())
885
			}
886
		}
887
	}
888
}
889

            
890
parameter_types! {
891
	pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes;
892
}
893

            
894
impl pallet_ethereum::Config for Runtime {
895
	type RuntimeEvent = RuntimeEvent;
896
	type StateRoot =
897
		pallet_ethereum::IntermediateStateRoot<<Runtime as frame_system::Config>::Version>;
898
	type PostLogContent = PostBlockAndTxnHashes;
899
	type ExtraDataLength = ConstU32<30>;
900
}
901

            
902
parameter_types! {
903
	pub ReservedXcmpWeight: Weight = Weight::from_parts(u64::max_value(), 0);
904
}
905

            
906
#[derive(
907
	Copy,
908
	Clone,
909
	Eq,
910
	PartialEq,
911
	Ord,
912
	PartialOrd,
913
	Encode,
914
	Decode,
915
	Debug,
916
	MaxEncodedLen,
917
	TypeInfo,
918
	DecodeWithMemTracking,
919
)]
920
pub enum ProxyType {
921
	NotAllowed = 0,
922
1
	Any = 1,
923
}
924

            
925
impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType {}
926

            
927
impl InstanceFilter<RuntimeCall> for ProxyType {
928
	fn filter(&self, _c: &RuntimeCall) -> bool {
929
		match self {
930
			ProxyType::NotAllowed => false,
931
			ProxyType::Any => true,
932
		}
933
	}
934
	fn is_superset(&self, _o: &Self) -> bool {
935
		false
936
	}
937
}
938

            
939
impl Default for ProxyType {
940
	fn default() -> Self {
941
		Self::NotAllowed
942
	}
943
}
944

            
945
parameter_types! {
946
	pub const ProxyCost: u64 = 1;
947
}
948

            
949
impl pallet_proxy::Config for Runtime {
950
	type RuntimeEvent = RuntimeEvent;
951
	type RuntimeCall = RuntimeCall;
952
	type Currency = Balances;
953
	type ProxyType = ProxyType;
954
	type ProxyDepositBase = ProxyCost;
955
	type ProxyDepositFactor = ProxyCost;
956
	type MaxProxies = ConstU32<32>;
957
	type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
958
	type MaxPending = ConstU32<32>;
959
	type CallHasher = BlakeTwo256;
960
	type AnnouncementDepositBase = ProxyCost;
961
	type AnnouncementDepositFactor = ProxyCost;
962
	type BlockNumberProvider = System;
963
}
964

            
965
pub struct EthereumXcmEnsureProxy;
966
impl xcm_primitives::EnsureProxy<AccountId> for EthereumXcmEnsureProxy {
967
2
	fn ensure_ok(delegator: AccountId, delegatee: AccountId) -> Result<(), &'static str> {
968
		// The EVM implicitly contains an Any proxy, so we only allow for "Any" proxies
969
1
		let def: pallet_proxy::ProxyDefinition<AccountId, ProxyType, BlockNumber> =
970
2
			pallet_proxy::Pallet::<Runtime>::find_proxy(
971
2
				&delegator,
972
2
				&delegatee,
973
2
				Some(ProxyType::Any),
974
2
			)
975
2
			.map_err(|_| "proxy error: expected `ProxyType::Any`")?;
976
		// We only allow to use it for delay zero proxies, as the call will immediately be executed
977
1
		ensure!(def.delay.is_zero(), "proxy delay is Non-zero`");
978
1
		Ok(())
979
2
	}
980
}
981

            
982
impl pallet_ethereum_xcm::Config for Runtime {
983
	type RuntimeEvent = RuntimeEvent;
984
	type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
985
	type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
986
	type XcmEthereumOrigin = pallet_ethereum_xcm::EnsureXcmEthereumTransaction;
987
	type ReservedXcmpWeight = ReservedXcmpWeight;
988
	type EnsureProxy = EthereumXcmEnsureProxy;
989
	type ControllerOrigin = EnsureRoot<AccountId>;
990
	type ForceOrigin = EnsureRoot<AccountId>;
991
}
992

            
993
type Block = frame_system::mocking::MockBlockU32<Runtime>;
994

            
995
2431
construct_runtime!(
996
2431
	pub enum Runtime	{
997
2431
		System: frame_system,
998
2431
		Balances: pallet_balances,
999
2431
		MsgQueue: mock_msg_queue,
2431
		XcmVersioner: mock_version_changer,
2431

            
2431
		PolkadotXcm: pallet_xcm,
2431
		CumulusXcm: cumulus_pallet_xcm,
2431
		XcmTransactor: pallet_xcm_transactor,
2431
		XcmWeightTrader: pallet_xcm_weight_trader,
2431
		Treasury: pallet_treasury,
2431
		Proxy: pallet_proxy,
2431

            
2431
		Timestamp: pallet_timestamp,
2431
		EVM: pallet_evm,
2431
		Ethereum: pallet_ethereum,
2431
		EthereumXcm: pallet_ethereum_xcm,
2431
		EvmForeignAssets: pallet_moonbeam_foreign_assets,
2431
	}
2431
);
6
pub(crate) fn para_events() -> Vec<RuntimeEvent> {
6
	System::events()
6
		.into_iter()
79
		.map(|r| r.event)
79
		.filter_map(|e| Some(e))
6
		.collect::<Vec<_>>()
6
}
use frame_support::traits::{
	ConstBool, Disabled, OnFinalize, OnInitialize, UncheckedOnRuntimeUpgrade,
};
use moonriver_runtime::{currency, xcm_config::LocationToH160};
use pallet_evm::FrameSystemAccountProvider;
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
}