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(1000).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
	type XcmRecorder = XcmPallet;
217
}
218

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

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

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

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

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

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

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

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

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

            
284
impl dmp::Config for Runtime {}
285

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

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

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

            
308
impl origin::Config for Runtime {}
309

            
310
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
311
type Block = frame_system::mocking::MockBlockU32<Runtime>;
312

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

            
319
pub struct MessageProcessor;
320
impl ProcessMessage for MessageProcessor {
321
	type Origin = AggregateMessageOrigin;
322

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

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

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

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

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

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

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

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

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