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
	type ExtensionsWeightInfo = ();
88
}
89

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

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

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

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

            
124
impl configuration::Config for Runtime {
125
	type WeightInfo = configuration::TestWeightInfo;
126
}
127

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

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

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

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

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

            
161
pub type XcmRouter = super::RelayChainXcmRouter;
162

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

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

            
186
pub type TrustedTeleporters = xcm_builder::Case<KusamaForStatemine>;
187

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

            
221
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, KusamaNetwork>;
222

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

            
250
parameter_types! {
251
	pub const FirstMessageFactorPercent: u64 = 100;
252
}
253

            
254
parameter_types! {
255
	pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
256
}
257

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

            
262
impl frame_support::traits::EstimateNextSessionRotation<u32> for TestNextSessionRotation {
263
	fn average_session_length() -> u32 {
264
		10
265
	}
266

            
267
	fn estimate_current_session_progress(_now: u32) -> (Option<Permill>, Weight) {
268
		(None, Weight::zero())
269
	}
270

            
271
	fn estimate_next_session_rotation(_now: u32) -> (Option<u32>, Weight) {
272
		(None, Weight::zero())
273
	}
274
}
275

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

            
286
impl dmp::Config for Runtime {}
287

            
288
parameter_types! {
289
	pub const DefaultChannelSizeAndCapacityWithSystem: (u32, u32) = (4, 1);
290
}
291

            
292
impl hrmp::Config for Runtime {
293
	type RuntimeOrigin = RuntimeOrigin;
294
	type RuntimeEvent = RuntimeEvent;
295
	type Currency = Balances;
296
	type WeightInfo = TestHrmpWeightInfo;
297
	type ChannelManager = frame_system::EnsureRoot<AccountId>;
298
	type DefaultChannelSizeAndCapacityWithSystem = DefaultChannelSizeAndCapacityWithSystem;
299
	type VersionWrapper = XcmPallet;
300
}
301

            
302
impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
303
where
304
	RuntimeCall: From<C>,
305
{
306
	type Extrinsic = UncheckedExtrinsic;
307
	type RuntimeCall = RuntimeCall;
308
}
309

            
310
impl origin::Config for Runtime {}
311

            
312
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
313
type Block = frame_system::mocking::MockBlockU32<Runtime>;
314

            
315
impl<C> frame_system::offchain::CreateInherent<C> for Runtime
316
where
317
	RuntimeCall: From<C>,
318
{
319
	fn create_inherent(call: RuntimeCall) -> UncheckedExtrinsic {
320
		UncheckedExtrinsic::new_bare(call)
321
	}
322
}
323

            
324
parameter_types! {
325
	pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000);
326
	pub const MessageQueueHeapSize: u32 = 65_536;
327
	pub const MessageQueueMaxStale: u32 = 16;
328
}
329

            
330
pub struct MessageProcessor;
331
impl ProcessMessage for MessageProcessor {
332
	type Origin = AggregateMessageOrigin;
333

            
334
23
	fn process_message(
335
23
		message: &[u8],
336
23
		origin: Self::Origin,
337
23
		meter: &mut WeightMeter,
338
23
		id: &mut [u8; 32],
339
23
	) -> Result<bool, ProcessMessageError> {
340
23
		let para = match origin {
341
23
			AggregateMessageOrigin::Ump(UmpQueueId::Para(para)) => para,
342
23
		};
343
23
		ProcessXcmMessage::<Junction, XcmExecutor<XcmConfig>, RuntimeCall>::process_message(
344
23
			message,
345
23
			Junction::Parachain(para.into()),
346
23
			meter,
347
23
			id,
348
23
		)
349
23
	}
350
}
351

            
352
impl pallet_message_queue::Config for Runtime {
353
	type RuntimeEvent = RuntimeEvent;
354
	type Size = u32;
355
	type HeapSize = MessageQueueHeapSize;
356
	type MaxStale = MessageQueueMaxStale;
357
	type ServiceWeight = MessageQueueServiceWeight;
358
	type MessageProcessor = MessageProcessor;
359
	type QueueChangeHandler = ();
360
	type WeightInfo = ();
361
	type QueuePausedQuery = ();
362
	type IdleMaxServiceWeight = MessageQueueServiceWeight;
363
}
364

            
365
6870
construct_runtime!(
366
628
	pub enum Runtime	{
367
628
		System: frame_system,
368
628
		Balances: pallet_balances,
369
628
		ParasOrigin: origin,
370
628
		MessageQueue: pallet_message_queue,
371
628
		XcmPallet: pallet_xcm,
372
628
		Utility: pallet_utility,
373
628
		Hrmp: hrmp,
374
628
		Dmp: dmp,
375
628
		Paras: paras,
376
628
		Configuration: configuration,
377
628
	}
378
6925
);
379

            
380
5
pub(crate) fn relay_events() -> Vec<RuntimeEvent> {
381
5
	System::events()
382
5
		.into_iter()
383
25
		.map(|r| r.event)
384
25
		.filter_map(|e| Some(e))
385
5
		.collect::<Vec<_>>()
386
5
}
387

            
388
use frame_support::traits::{OnFinalize, OnInitialize};
389
1
pub(crate) fn relay_roll_to(n: BlockNumber) {
390
2
	while System::block_number() < n {
391
1
		XcmPallet::on_finalize(System::block_number());
392
1
		Balances::on_finalize(System::block_number());
393
1
		System::on_finalize(System::block_number());
394
1
		System::set_block_number(System::block_number() + 1);
395
1
		System::on_initialize(System::block_number());
396
1
		Balances::on_initialize(System::block_number());
397
1
		XcmPallet::on_initialize(System::block_number());
398
1
	}
399
1
}
400

            
401
/// A weight info that is only suitable for testing.
402
pub struct TestHrmpWeightInfo;
403

            
404
impl hrmp::WeightInfo for TestHrmpWeightInfo {
405
2
	fn hrmp_accept_open_channel() -> Weight {
406
2
		Weight::from_parts(1, 0)
407
2
	}
408
	fn force_clean_hrmp(_: u32, _: u32) -> Weight {
409
		Weight::from_parts(1, 0)
410
	}
411
	fn force_process_hrmp_close(_: u32) -> Weight {
412
		Weight::from_parts(1, 0)
413
	}
414
	fn force_process_hrmp_open(_: u32) -> Weight {
415
		Weight::from_parts(1, 0)
416
	}
417
	fn hrmp_cancel_open_request(_: u32) -> Weight {
418
		Weight::from_parts(1, 0)
419
	}
420
2
	fn hrmp_close_channel() -> Weight {
421
2
		Weight::from_parts(1, 0)
422
2
	}
423
2
	fn hrmp_init_open_channel() -> Weight {
424
2
		Weight::from_parts(1, 0)
425
2
	}
426
	fn clean_open_channel_requests(_: u32) -> Weight {
427
		Weight::from_parts(1, 0)
428
	}
429
1
	fn force_open_hrmp_channel(_: u32) -> Weight {
430
1
		Weight::from_parts(1, 0)
431
1
	}
432
	fn establish_system_channel() -> Weight {
433
		Weight::from_parts(1, 0)
434
	}
435

            
436
	fn poke_channel_deposits() -> Weight {
437
		Weight::from_parts(1, 0)
438
	}
439

            
440
	fn establish_channel_with_system() -> Weight {
441
		Weight::from_parts(1, 0)
442
	}
443
}