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
//! Relay chain runtime mock.
18

            
19
use frame_support::{
20
	construct_runtime, parameter_types,
21
	traits::{Everything, Nothing, ProcessMessage, ProcessMessageError},
22
};
23
use frame_system::pallet_prelude::BlockNumberFor;
24
use sp_core::H256;
25
use sp_runtime::{
26
	traits::{ConstU32, IdentityLookup},
27
	AccountId32,
28
};
29

            
30
use frame_support::weights::{Weight, WeightMeter};
31
use polkadot_parachain::primitives::Id as ParaId;
32
use polkadot_runtime_parachains::{
33
	configuration, dmp, hrmp,
34
	inclusion::{AggregateMessageOrigin, UmpQueueId},
35
	origin, paras, shared,
36
};
37
use sp_runtime::transaction_validity::TransactionPriority;
38
use sp_runtime::Permill;
39
use xcm::latest::prelude::*;
40
use xcm_builder::{
41
	Account32Hash, AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
42
	AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, ChildParachainConvertsVia,
43
	ChildSystemParachainAsSuperuser, FixedRateOfFungible, FixedWeightBounds,
44
	FungibleAdapter as XcmCurrencyAdapter, IsConcrete, ProcessXcmMessage,
45
	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
46
	WithComputedOrigin,
47
};
48
use xcm_executor::{Config, XcmExecutor};
49
pub type AccountId = AccountId32;
50
pub type Balance = u128;
51
pub type BlockNumber = BlockNumberFor<Runtime>;
52

            
53
parameter_types! {
54
	pub const BlockHashCount: u32 = 250;
55
}
56

            
57
impl frame_system::Config for Runtime {
58
	type RuntimeOrigin = RuntimeOrigin;
59
	type RuntimeCall = RuntimeCall;
60
	type RuntimeTask = RuntimeTask;
61
	type Nonce = u64;
62
	type Block = Block;
63
	type Hash = H256;
64
	type Hashing = ::sp_runtime::traits::BlakeTwo256;
65
	type AccountId = AccountId;
66
	type Lookup = IdentityLookup<Self::AccountId>;
67
	type RuntimeEvent = RuntimeEvent;
68
	type BlockHashCount = BlockHashCount;
69
	type BlockWeights = ();
70
	type BlockLength = ();
71
	type Version = ();
72
	type PalletInfo = PalletInfo;
73
	type AccountData = pallet_balances::AccountData<Balance>;
74
	type OnNewAccount = ();
75
	type OnKilledAccount = ();
76
	type DbWeight = ();
77
	type BaseCallFilter = Everything;
78
	type SystemWeightInfo = ();
79
	type SS58Prefix = ();
80
	type OnSetCode = ();
81
	type MaxConsumers = ConstU32<16>;
82
	type SingleBlockMigrations = ();
83
	type MultiBlockMigrator = ();
84
	type PreInherents = ();
85
	type PostInherents = ();
86
	type PostTransactions = ();
87
}
88

            
89
parameter_types! {
90
	pub ExistentialDeposit: Balance = 1;
91
	pub const MaxLocks: u32 = 50;
92
	pub const MaxReserves: u32 = 50;
93
}
94

            
95
impl pallet_balances::Config for Runtime {
96
	type MaxLocks = MaxLocks;
97
	type Balance = Balance;
98
	type RuntimeEvent = RuntimeEvent;
99
	type DustRemoval = ();
100
	type ExistentialDeposit = ExistentialDeposit;
101
	type AccountStore = System;
102
	type WeightInfo = ();
103
	type MaxReserves = MaxReserves;
104
	type ReserveIdentifier = [u8; 8];
105
	type RuntimeHoldReason = ();
106
	type FreezeIdentifier = ();
107
	type MaxFreezes = ();
108
	type RuntimeFreezeReason = ();
109
}
110

            
111
impl pallet_utility::Config for Runtime {
112
	type RuntimeEvent = RuntimeEvent;
113
	type RuntimeCall = RuntimeCall;
114
	type WeightInfo = ();
115
	type PalletsOrigin = OriginCaller;
116
}
117

            
118
impl shared::Config for Runtime {
119
	type DisabledValidators = ();
120
}
121

            
122
impl configuration::Config for Runtime {
123
	type WeightInfo = configuration::TestWeightInfo;
124
}
125

            
126
parameter_types! {
127
	pub KsmLocation: Location = Here.into();
128
	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
129
	pub const AnyNetwork: Option<NetworkId> = None;
130
	pub UniversalLocation: InteriorLocation = Here;
131
}
132

            
133
pub type SovereignAccountOf = (
134
	ChildParachainConvertsVia<ParaId, AccountId>,
135
	AccountId32Aliases<KusamaNetwork, AccountId>,
136
	// Not enabled in the relay per se, but we enable it to test
137
	// the transact_through_signed extrinsic
138
	Account32Hash<KusamaNetwork, AccountId>,
139
);
140

            
141
pub type LocalAssetTransactor =
142
	XcmCurrencyAdapter<Balances, IsConcrete<KsmLocation>, SovereignAccountOf, AccountId, ()>;
143

            
144
type LocalOriginConverter = (
145
	SovereignSignedViaLocation<SovereignAccountOf, RuntimeOrigin>,
146
	ChildParachainAsNative<origin::Origin, RuntimeOrigin>,
147
	SignedAccountId32AsNative<KusamaNetwork, RuntimeOrigin>,
148
	ChildSystemParachainAsSuperuser<ParaId, RuntimeOrigin>,
149
);
150

            
151
parameter_types! {
152
	pub const BaseXcmWeight: Weight = Weight::from_parts(1000u64, 1000u64);
153
	pub KsmPerSecond: (AssetId, u128, u128) = (AssetId(KsmLocation::get()), 1, 1);
154
	pub const MaxInstructions: u32 = 100;
155
	pub const MaxAssetsIntoHolding: u32 = 64;
156
	pub MatcherLocation: Location = Location::here();
157
}
158

            
159
pub type XcmRouter = super::RelayChainXcmRouter;
160

            
161
pub type XcmBarrier = (
162
	// Weight that is paid for may be consumed.
163
	TakeWeightCredit,
164
	// Expected responses are OK.
165
	AllowKnownQueryResponses<XcmPallet>,
166
	WithComputedOrigin<
167
		(
168
			// If the message is one that immediately attemps to pay for execution, then allow it.
169
			AllowTopLevelPaidExecutionFrom<Everything>,
170
			// Subscriptions for version tracking are OK.
171
			AllowSubscriptionsFrom<Everything>,
172
		),
173
		UniversalLocation,
174
		ConstU32<8>,
175
	>,
176
);
177

            
178
parameter_types! {
179
	pub Kusama: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(KsmLocation::get()) });
180
	pub Statemine: Location = Parachain(4).into();
181
	pub KusamaForStatemine: (AssetFilter, Location) = (Kusama::get(), Statemine::get());
182
}
183

            
184
pub type TrustedTeleporters = xcm_builder::Case<KusamaForStatemine>;
185

            
186
pub struct XcmConfig;
187
impl Config for XcmConfig {
188
	type RuntimeCall = RuntimeCall;
189
	type XcmSender = XcmRouter;
190
	type AssetTransactor = LocalAssetTransactor;
191
	type OriginConverter = LocalOriginConverter;
192
	type IsReserve = ();
193
	type IsTeleporter = TrustedTeleporters;
194
	type UniversalLocation = UniversalLocation;
195
	type Barrier = XcmBarrier;
196
	type Weigher = FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;
197
	type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
198
	type ResponseHandler = XcmPallet;
199
	type AssetTrap = XcmPallet;
200
	type AssetClaims = XcmPallet;
201
	type SubscriptionService = XcmPallet;
202
	type CallDispatcher = RuntimeCall;
203
	type AssetLocker = ();
204
	type AssetExchanger = ();
205
	type PalletInstancesInfo = ();
206
	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
207
	type FeeManager = ();
208
	type MessageExporter = ();
209
	type UniversalAliases = Nothing;
210
	type SafeCallFilter = Everything;
211
	type Aliasers = Nothing;
212
	type TransactionalProcessor = ();
213
	type HrmpNewChannelOpenRequestHandler = ();
214
	type HrmpChannelAcceptedHandler = ();
215
	type HrmpChannelClosingHandler = ();
216
}
217

            
218
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, KusamaNetwork>;
219

            
220
impl pallet_xcm::Config for Runtime {
221
	type RuntimeEvent = RuntimeEvent;
222
	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
223
	type XcmRouter = XcmRouter;
224
	// Anyone can execute XCM messages locally...
225
	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
226
	type XcmExecuteFilter = Nothing;
227
	type XcmExecutor = XcmExecutor<XcmConfig>;
228
	type XcmTeleportFilter = Everything;
229
	type XcmReserveTransferFilter = Everything;
230
	type Weigher = FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;
231
	type UniversalLocation = UniversalLocation;
232
	type RuntimeOrigin = RuntimeOrigin;
233
	type RuntimeCall = RuntimeCall;
234
	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
235
	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
236
	type Currency = Balances;
237
	type CurrencyMatcher = ();
238
	type TrustedLockers = ();
239
	type SovereignAccountOf = ();
240
	type MaxLockers = ConstU32<8>;
241
	type WeightInfo = pallet_xcm::TestWeightInfo;
242
	type MaxRemoteLockConsumers = ConstU32<0>;
243
	type RemoteLockConsumerIdentifier = ();
244
	type AdminOrigin = frame_system::EnsureRoot<AccountId>;
245
}
246

            
247
parameter_types! {
248
	pub const FirstMessageFactorPercent: u64 = 100;
249
}
250

            
251
parameter_types! {
252
	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
253
}
254

            
255
/// A very dumb implementation of `EstimateNextSessionRotation`. At the moment of writing, this
256
/// is more to satisfy type requirements rather than to test anything.
257
pub struct TestNextSessionRotation;
258

            
259
impl frame_support::traits::EstimateNextSessionRotation<u32> for TestNextSessionRotation {
260
	fn average_session_length() -> u32 {
261
		10
262
	}
263

            
264
	fn estimate_current_session_progress(_now: u32) -> (Option<Permill>, Weight) {
265
		(None, Weight::zero())
266
	}
267

            
268
	fn estimate_next_session_rotation(_now: u32) -> (Option<u32>, Weight) {
269
		(None, Weight::zero())
270
	}
271
}
272

            
273
impl paras::Config for Runtime {
274
	type RuntimeEvent = RuntimeEvent;
275
	type WeightInfo = paras::TestWeightInfo;
276
	type UnsignedPriority = ParasUnsignedPriority;
277
	type NextSessionRotation = TestNextSessionRotation;
278
	type QueueFootprinter = ();
279
	type OnNewHead = ();
280
	type AssignCoretime = ();
281
}
282

            
283
impl dmp::Config for Runtime {}
284

            
285
parameter_types! {
286
	pub const DefaultChannelSizeAndCapacityWithSystem: (u32, u32) = (4, 1);
287
}
288

            
289
impl hrmp::Config for Runtime {
290
	type RuntimeOrigin = RuntimeOrigin;
291
	type RuntimeEvent = RuntimeEvent;
292
	type Currency = Balances;
293
	type WeightInfo = TestHrmpWeightInfo;
294
	type ChannelManager = frame_system::EnsureRoot<AccountId>;
295
	type DefaultChannelSizeAndCapacityWithSystem = DefaultChannelSizeAndCapacityWithSystem;
296
}
297

            
298
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
299
where
300
	RuntimeCall: From<C>,
301
{
302
	type Extrinsic = UncheckedExtrinsic;
303
	type OverarchingCall = RuntimeCall;
304
}
305

            
306
impl origin::Config for Runtime {}
307

            
308
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
309
type Block = frame_system::mocking::MockBlockU32<Runtime>;
310

            
311
parameter_types! {
312
	pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000);
313
	pub const MessageQueueHeapSize: u32 = 65_536;
314
	pub const MessageQueueMaxStale: u32 = 16;
315
}
316

            
317
pub struct MessageProcessor;
318
impl ProcessMessage for MessageProcessor {
319
	type Origin = AggregateMessageOrigin;
320

            
321
24
	fn process_message(
322
24
		message: &[u8],
323
24
		origin: Self::Origin,
324
24
		meter: &mut WeightMeter,
325
24
		id: &mut [u8; 32],
326
24
	) -> Result<bool, ProcessMessageError> {
327
24
		let para = match origin {
328
24
			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
329
24
		};
330
24
		ProcessXcmMessage::<Junction, XcmExecutor<XcmConfig>, RuntimeCall>::process_message(
331
24
			message,
332
24
			Junction::Parachain(para.into()),
333
24
			meter,
334
24
			id,
335
24
		)
336
24
	}
337
}
338

            
339
impl pallet_message_queue::Config for Runtime {
340
	type RuntimeEvent = RuntimeEvent;
341
	type Size = u32;
342
	type HeapSize = MessageQueueHeapSize;
343
	type MaxStale = MessageQueueMaxStale;
344
	type ServiceWeight = MessageQueueServiceWeight;
345
	type MessageProcessor = MessageProcessor;
346
	type QueueChangeHandler = ();
347
	type WeightInfo = ();
348
	type QueuePausedQuery = ();
349
	type IdleMaxServiceWeight = MessageQueueServiceWeight;
350
}
351

            
352
6222
construct_runtime!(
353
	pub enum Runtime	{
354
		System: frame_system,
355
		Balances: pallet_balances,
356
		ParasOrigin: origin,
357
		MessageQueue: pallet_message_queue,
358
		XcmPallet: pallet_xcm,
359
		Utility: pallet_utility,
360
		Hrmp: hrmp,
361
		Dmp: dmp,
362
		Paras: paras,
363
		Configuration: configuration,
364
	}
365
22510
);
366

            
367
5
pub(crate) fn relay_events() -> Vec<RuntimeEvent> {
368
5
	System::events()
369
5
		.into_iter()
370
25
		.map(|r| r.event)
371
25
		.filter_map(|e| Some(e))
372
5
		.collect::<Vec<_>>()
373
5
}
374

            
375
use frame_support::traits::{OnFinalize, OnInitialize};
376
1
pub(crate) fn relay_roll_to(n: BlockNumber) {
377
2
	while System::block_number() < n {
378
1
		XcmPallet::on_finalize(System::block_number());
379
1
		Balances::on_finalize(System::block_number());
380
1
		System::on_finalize(System::block_number());
381
1
		System::set_block_number(System::block_number() + 1);
382
1
		System::on_initialize(System::block_number());
383
1
		Balances::on_initialize(System::block_number());
384
1
		XcmPallet::on_initialize(System::block_number());
385
1
	}
386
1
}
387

            
388
/// A weight info that is only suitable for testing.
389
pub struct TestHrmpWeightInfo;
390

            
391
impl hrmp::WeightInfo for TestHrmpWeightInfo {
392
1
	fn hrmp_accept_open_channel() -> Weight {
393
1
		Weight::from_parts(1, 0)
394
1
	}
395
	fn force_clean_hrmp(_: u32, _: u32) -> Weight {
396
		Weight::from_parts(1, 0)
397
	}
398
	fn force_process_hrmp_close(_: u32) -> Weight {
399
		Weight::from_parts(1, 0)
400
	}
401
	fn force_process_hrmp_open(_: u32) -> Weight {
402
		Weight::from_parts(1, 0)
403
	}
404
	fn hrmp_cancel_open_request(_: u32) -> Weight {
405
		Weight::from_parts(1, 0)
406
	}
407
1
	fn hrmp_close_channel() -> Weight {
408
1
		Weight::from_parts(1, 0)
409
1
	}
410
1
	fn hrmp_init_open_channel() -> Weight {
411
1
		Weight::from_parts(1, 0)
412
1
	}
413
	fn clean_open_channel_requests(_: u32) -> Weight {
414
		Weight::from_parts(1, 0)
415
	}
416
1
	fn force_open_hrmp_channel(_: u32) -> Weight {
417
1
		Weight::from_parts(1, 0)
418
1
	}
419
	fn establish_system_channel() -> Weight {
420
		Weight::from_parts(1, 0)
421
	}
422

            
423
	fn poke_channel_deposits() -> Weight {
424
		Weight::from_parts(1, 0)
425
	}
426

            
427
	fn establish_channel_with_system() -> Weight {
428
		Weight::from_parts(1, 0)
429
	}
430
}