1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

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

            
17
// We want to avoid including the rococo-runtime here.
18
// TODO: whenever a conclusion is taken from https://github.com/paritytech/substrate/issues/8158
19

            
20
use cumulus_primitives_core::{relay_chain::HrmpChannelId, ParaId};
21
use pallet_xcm_transactor::relay_indices::RelayChainIndices;
22
use parity_scale_codec::{Decode, Encode};
23
use sp_runtime::traits::{AccountIdLookup, StaticLookup};
24
use sp_runtime::AccountId32;
25
use sp_std::vec::Vec;
26

            
27
#[derive(Encode, Decode)]
28
pub enum RelayCall {
29
	#[codec(index = 16u8)]
30
	// the index should match the position of the module in `construct_runtime!`
31
	Utility(UtilityCall),
32

            
33
	#[codec(index = 6u8)]
34
	Stake(StakeCall),
35
	#[codec(index = 51u8)]
36
	// the index should match the position of the module in `construct_runtime!`
37
	Hrmp(HrmpCall),
38
}
39

            
40
#[derive(Encode, Decode)]
41
pub enum StakeCall {
42
	#[codec(index = 0u16)]
43
	// the index should match the position of the dispatchable in the target pallet
44
	Bond(
45
		#[codec(compact)] cumulus_primitives_core::relay_chain::Balance,
46
		pallet_staking::RewardDestination<AccountId32>,
47
	),
48
	#[codec(index = 1u16)]
49
	BondExtra(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
50
	#[codec(index = 2u16)]
51
	Unbond(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
52
	#[codec(index = 3u16)]
53
	WithdrawUnbonded(u32),
54
	#[codec(index = 4u16)]
55
	Validate(pallet_staking::ValidatorPrefs),
56
	#[codec(index = 5u16)]
57
	Nominate(Vec<<AccountIdLookup<AccountId32, ()> as StaticLookup>::Source>),
58
	#[codec(index = 6u16)]
59
	Chill,
60
	#[codec(index = 7u16)]
61
	SetPayee(pallet_staking::RewardDestination<AccountId32>),
62
	#[codec(index = 8u16)]
63
	SetController,
64
	#[codec(index = 19u16)]
65
	Rebond(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
66
}
67

            
68
// Utility call encoding, needed for xcm transactor pallet
69
#[derive(Encode, Decode)]
70
pub enum UtilityCall {
71
	#[codec(index = 1u8)]
72
	AsDerivative(u16),
73
}
74

            
75
// HRMP call encoding, needed for xcm transactor pallet
76
#[derive(Encode, Decode)]
77
pub enum HrmpCall {
78
	#[codec(index = 0u8)]
79
	InitOpenChannel(ParaId, u32, u32),
80
	#[codec(index = 1u8)]
81
	AcceptOpenChannel(ParaId),
82
	#[codec(index = 2u8)]
83
	CloseChannel(HrmpChannelId),
84
	#[codec(index = 6u8)]
85
	CancelOpenRequest(HrmpChannelId, u32),
86
}
87

            
88
pub struct WestendEncoder;
89

            
90
impl xcm_primitives::UtilityEncodeCall for WestendEncoder {
91
1
	fn encode_call(self, call: xcm_primitives::UtilityAvailableCalls) -> Vec<u8> {
92
1
		match call {
93
1
			xcm_primitives::UtilityAvailableCalls::AsDerivative(a, b) => {
94
1
				let mut call = RelayCall::Utility(UtilityCall::AsDerivative(a.clone())).encode();
95
1
				// If we encode directly we inject the call length,
96
1
				// so we just append the inner call after encoding the outer
97
1
				call.append(&mut b.clone());
98
1
				call
99
1
			}
100
1
		}
101
1
	}
102
}
103

            
104
impl xcm_primitives::HrmpEncodeCall for WestendEncoder {
105
4
	fn hrmp_encode_call(
106
4
		call: xcm_primitives::HrmpAvailableCalls,
107
4
	) -> Result<Vec<u8>, xcm::latest::Error> {
108
4
		match call {
109
1
			xcm_primitives::HrmpAvailableCalls::InitOpenChannel(a, b, c) => Ok(RelayCall::Hrmp(
110
1
				HrmpCall::InitOpenChannel(a.clone(), b.clone(), c.clone()),
111
1
			)
112
1
			.encode()),
113
1
			xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(a) => {
114
1
				Ok(RelayCall::Hrmp(HrmpCall::AcceptOpenChannel(a.clone())).encode())
115
			}
116
1
			xcm_primitives::HrmpAvailableCalls::CloseChannel(a) => {
117
1
				Ok(RelayCall::Hrmp(HrmpCall::CloseChannel(a.clone())).encode())
118
			}
119
1
			xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(a, b) => {
120
1
				Ok(RelayCall::Hrmp(HrmpCall::CancelOpenRequest(a.clone(), b.clone())).encode())
121
			}
122
		}
123
4
	}
124
}
125
impl xcm_primitives::StakeEncodeCall for WestendEncoder {
126
11
	fn encode_call(call: xcm_primitives::AvailableStakeCalls) -> Vec<u8> {
127
11
		match call {
128
1
			xcm_primitives::AvailableStakeCalls::Bond(b, c) => {
129
1
				RelayCall::Stake(StakeCall::Bond(b, c)).encode()
130
			}
131

            
132
1
			xcm_primitives::AvailableStakeCalls::BondExtra(a) => {
133
1
				RelayCall::Stake(StakeCall::BondExtra(a)).encode()
134
			}
135

            
136
1
			xcm_primitives::AvailableStakeCalls::Unbond(a) => {
137
1
				RelayCall::Stake(StakeCall::Unbond(a)).encode()
138
			}
139

            
140
1
			xcm_primitives::AvailableStakeCalls::WithdrawUnbonded(a) => {
141
1
				RelayCall::Stake(StakeCall::WithdrawUnbonded(a)).encode()
142
			}
143

            
144
1
			xcm_primitives::AvailableStakeCalls::Validate(a) => {
145
1
				RelayCall::Stake(StakeCall::Validate(a)).encode()
146
			}
147

            
148
			xcm_primitives::AvailableStakeCalls::Chill => {
149
2
				RelayCall::Stake(StakeCall::Chill).encode()
150
			}
151

            
152
1
			xcm_primitives::AvailableStakeCalls::SetPayee(a) => {
153
1
				RelayCall::Stake(StakeCall::SetPayee(a.into())).encode()
154
			}
155

            
156
			xcm_primitives::AvailableStakeCalls::SetController => {
157
1
				RelayCall::Stake(StakeCall::SetController).encode()
158
			}
159

            
160
1
			xcm_primitives::AvailableStakeCalls::Rebond(a) => {
161
1
				RelayCall::Stake(StakeCall::Rebond(a.into())).encode()
162
			}
163

            
164
1
			xcm_primitives::AvailableStakeCalls::Nominate(a) => {
165
1
				let nominated: Vec<<AccountIdLookup<AccountId32, ()> as StaticLookup>::Source> =
166
1
					a.iter().map(|add| (*add).clone().into()).collect();
167
1

            
168
1
				RelayCall::Stake(StakeCall::Nominate(nominated)).encode()
169
			}
170
		}
171
11
	}
172
}
173

            
174
/// Westend pallet and extrinsic indices
175
pub const WESTEND_RELAY_INDICES: RelayChainIndices = RelayChainIndices {
176
	staking: 6u8,
177
	utility: 16u8,
178
	hrmp: 51u8,
179
	bond: 0u8,
180
	bond_extra: 1u8,
181
	unbond: 2u8,
182
	withdraw_unbonded: 3u8,
183
	validate: 4u8,
184
	nominate: 5u8,
185
	chill: 6u8,
186
	set_payee: 7u8,
187
	set_controller: 8u8,
188
	rebond: 19u8,
189
	as_derivative: 1u8,
190
	init_open_channel: 0u8,
191
	accept_open_channel: 1u8,
192
	close_channel: 2u8,
193
	cancel_open_request: 6u8,
194
};
195

            
196
#[cfg(test)]
197
mod tests {
198
	use super::*;
199
	use crate::westend::WestendEncoder;
200
	use frame_support::traits::PalletInfo;
201
	use sp_runtime::Perbill;
202
	use xcm_primitives::{StakeEncodeCall, UtilityEncodeCall};
203

            
204
	#[test]
205
1
	fn test_as_derivative() {
206
1
		let mut expected_encoded: Vec<u8> = Vec::new();
207
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
208
1
			westend_runtime::Utility,
209
1
		>()
210
1
		.unwrap() as u8;
211
1
		expected_encoded.push(index);
212
1

            
213
1
		let mut expected = pallet_utility::Call::<westend_runtime::Runtime>::as_derivative {
214
1
			index: 1,
215
1
			call: westend_runtime::RuntimeCall::Staking(pallet_staking::Call::<
216
1
				westend_runtime::Runtime,
217
1
			>::chill {})
218
1
			.into(),
219
1
		}
220
1
		.encode();
221
1
		expected_encoded.append(&mut expected);
222
1

            
223
1
		let call_bytes = <WestendEncoder as StakeEncodeCall>::encode_call(
224
1
			xcm_primitives::AvailableStakeCalls::Chill,
225
1
		);
226
1

            
227
1
		expected_encoded.append(&mut expected);
228
1

            
229
1
		assert_eq!(
230
1
			xcm_primitives::UtilityEncodeCall::encode_call(
231
1
				WestendEncoder,
232
1
				xcm_primitives::UtilityAvailableCalls::AsDerivative(1, call_bytes.clone())
233
1
			),
234
1
			expected_encoded.clone()
235
1
		);
236
1
		sp_io::TestExternalities::default().execute_with(|| {
237
1
			// Pallet-xcm-transactor default encoder returns same result
238
1
			// insert storage item as per migration to set the storage item
239
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
240
1
				WESTEND_RELAY_INDICES,
241
1
			);
242
1
			assert_eq!(
243
1
				<pallet_xcm_transactor::Pallet::<
244
1
					moonbase_runtime::Runtime> as UtilityEncodeCall
245
1
				>::encode_call(
246
1
					pallet_xcm_transactor::Pallet(
247
1
						sp_std::marker::PhantomData::<moonbase_runtime::Runtime>::default()
248
1
					),
249
1
					xcm_primitives::UtilityAvailableCalls::AsDerivative(1, call_bytes)
250
1
				),
251
1
				expected_encoded
252
1
			);
253
1
		});
254
1
	}
255

            
256
	#[test]
257
1
	fn test_stake_bond() {
258
1
		let mut expected_encoded: Vec<u8> = Vec::new();
259
1
		let controller: AccountId32 = [1u8; 32].into();
260
1

            
261
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
262
1
			westend_runtime::Staking,
263
1
		>()
264
1
		.unwrap() as u8;
265
1
		expected_encoded.push(index);
266
1

            
267
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::bond {
268
1
			value: 100u32.into(),
269
1
			payee: pallet_staking::RewardDestination::Account(controller.clone()),
270
1
		}
271
1
		.encode();
272
1
		expected_encoded.append(&mut expected);
273
1

            
274
1
		assert_eq!(
275
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
276
1
				xcm_primitives::AvailableStakeCalls::Bond(
277
1
					100u32.into(),
278
1
					pallet_staking::RewardDestination::Account(controller.clone()),
279
1
				)
280
1
			),
281
1
			expected_encoded.clone()
282
1
		);
283
1
		sp_io::TestExternalities::default().execute_with(|| {
284
1
			// Pallet-xcm-transactor default encoder returns same result
285
1
			// insert storage item as per migration to set the storage item
286
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
287
1
				WESTEND_RELAY_INDICES,
288
1
			);
289
1
			assert_eq!(
290
1
				<pallet_xcm_transactor::Pallet::<
291
1
					moonbase_runtime::Runtime> as StakeEncodeCall
292
1
				>::encode_call(
293
1
					xcm_primitives::AvailableStakeCalls::Bond(
294
1
						100u32.into(),
295
1
						pallet_staking::RewardDestination::Account(controller)
296
1
					)
297
1
				),
298
1
				expected_encoded
299
1
			);
300
1
		});
301
1
	}
302
	#[test]
303
1
	fn test_stake_bond_extra() {
304
1
		let mut expected_encoded: Vec<u8> = Vec::new();
305
1

            
306
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
307
1
			westend_runtime::Staking,
308
1
		>()
309
1
		.unwrap() as u8;
310
1
		expected_encoded.push(index);
311
1

            
312
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::bond_extra {
313
1
			max_additional: 100u32.into(),
314
1
		}
315
1
		.encode();
316
1
		expected_encoded.append(&mut expected);
317
1

            
318
1
		assert_eq!(
319
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
320
1
				xcm_primitives::AvailableStakeCalls::BondExtra(100u32.into(),)
321
1
			),
322
1
			expected_encoded.clone()
323
1
		);
324
1
		sp_io::TestExternalities::default().execute_with(|| {
325
1
			// Pallet-xcm-transactor default encoder returns same result
326
1
			// insert storage item as per migration to set the storage item
327
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
328
1
				WESTEND_RELAY_INDICES,
329
1
			);
330
1
			assert_eq!(
331
1
				<pallet_xcm_transactor::Pallet::<
332
1
					moonbase_runtime::Runtime> as StakeEncodeCall
333
1
				>::encode_call(
334
1
					xcm_primitives::AvailableStakeCalls::BondExtra(100u32.into(),)
335
1
				),
336
1
				expected_encoded
337
1
			);
338
1
		});
339
1
	}
340
	#[test]
341
1
	fn test_stake_unbond() {
342
1
		let mut expected_encoded: Vec<u8> = Vec::new();
343
1

            
344
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
345
1
			westend_runtime::Staking,
346
1
		>()
347
1
		.unwrap() as u8;
348
1
		expected_encoded.push(index);
349
1

            
350
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::unbond {
351
1
			value: 100u32.into(),
352
1
		}
353
1
		.encode();
354
1
		expected_encoded.append(&mut expected);
355
1

            
356
1
		assert_eq!(
357
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
358
1
				xcm_primitives::AvailableStakeCalls::Unbond(100u32.into(),)
359
1
			),
360
1
			expected_encoded.clone()
361
1
		);
362
1
		sp_io::TestExternalities::default().execute_with(|| {
363
1
			// Pallet-xcm-transactor default encoder returns same result
364
1
			// insert storage item as per migration to set the storage item
365
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
366
1
				WESTEND_RELAY_INDICES,
367
1
			);
368
1
			assert_eq!(
369
1
				<pallet_xcm_transactor::Pallet::<
370
1
					moonbase_runtime::Runtime> as StakeEncodeCall
371
1
				>::encode_call(
372
1
					xcm_primitives::AvailableStakeCalls::Unbond(100u32.into(),)
373
1
				),
374
1
				expected_encoded
375
1
			);
376
1
		});
377
1
	}
378
	#[test]
379
1
	fn test_stake_withdraw_unbonded() {
380
1
		let mut expected_encoded: Vec<u8> = Vec::new();
381
1

            
382
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
383
1
			westend_runtime::Staking,
384
1
		>()
385
1
		.unwrap() as u8;
386
1
		expected_encoded.push(index);
387
1

            
388
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::withdraw_unbonded {
389
1
			num_slashing_spans: 100u32,
390
1
		}
391
1
		.encode();
392
1
		expected_encoded.append(&mut expected);
393
1

            
394
1
		assert_eq!(
395
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
396
1
				xcm_primitives::AvailableStakeCalls::WithdrawUnbonded(100u32,)
397
1
			),
398
1
			expected_encoded.clone()
399
1
		);
400
1
		sp_io::TestExternalities::default().execute_with(|| {
401
1
			// Pallet-xcm-transactor default encoder returns same result
402
1
			// insert storage item as per migration to set the storage item
403
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
404
1
				WESTEND_RELAY_INDICES,
405
1
			);
406
1
			assert_eq!(
407
1
				<pallet_xcm_transactor::Pallet::<
408
1
					moonbase_runtime::Runtime> as StakeEncodeCall
409
1
				>::encode_call(
410
1
					xcm_primitives::AvailableStakeCalls::WithdrawUnbonded(100u32,)
411
1
				),
412
1
				expected_encoded
413
1
			);
414
1
		});
415
1
	}
416
	#[test]
417
1
	fn test_stake_validate() {
418
1
		let mut expected_encoded: Vec<u8> = Vec::new();
419
1

            
420
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
421
1
			westend_runtime::Staking,
422
1
		>()
423
1
		.unwrap() as u8;
424
1
		expected_encoded.push(index);
425
1

            
426
1
		let validator_prefs = pallet_staking::ValidatorPrefs {
427
1
			commission: Perbill::from_percent(5),
428
1
			blocked: true,
429
1
		};
430
1

            
431
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::validate {
432
1
			prefs: validator_prefs.clone(),
433
1
		}
434
1
		.encode();
435
1
		expected_encoded.append(&mut expected);
436
1

            
437
1
		assert_eq!(
438
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
439
1
				xcm_primitives::AvailableStakeCalls::Validate(validator_prefs.clone())
440
1
			),
441
1
			expected_encoded.clone()
442
1
		);
443
1
		sp_io::TestExternalities::default().execute_with(|| {
444
1
			// Pallet-xcm-transactor default encoder returns same result
445
1
			// insert storage item as per migration to set the storage item
446
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
447
1
				WESTEND_RELAY_INDICES,
448
1
			);
449
1
			assert_eq!(
450
1
				<pallet_xcm_transactor::Pallet::<
451
1
					moonbase_runtime::Runtime> as StakeEncodeCall
452
1
				>::encode_call(
453
1
					xcm_primitives::AvailableStakeCalls::Validate(validator_prefs)
454
1
				),
455
1
				expected_encoded
456
1
			);
457
1
		});
458
1
	}
459
	#[test]
460
1
	fn test_stake_nominate() {
461
1
		let mut expected_encoded: Vec<u8> = Vec::new();
462
1
		let relay_account: AccountId32 = [1u8; 32].into();
463
1

            
464
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
465
1
			westend_runtime::Staking,
466
1
		>()
467
1
		.unwrap() as u8;
468
1
		expected_encoded.push(index);
469
1

            
470
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::nominate {
471
1
			targets: vec![relay_account.clone().into()],
472
1
		}
473
1
		.encode();
474
1
		expected_encoded.append(&mut expected);
475
1

            
476
1
		assert_eq!(
477
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
478
1
				xcm_primitives::AvailableStakeCalls::Nominate(vec![relay_account.clone().into()])
479
1
			),
480
1
			expected_encoded.clone()
481
1
		);
482
1
		sp_io::TestExternalities::default().execute_with(|| {
483
1
			// Pallet-xcm-transactor default encoder returns same result
484
1
			// insert storage item as per migration to set the storage item
485
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
486
1
				WESTEND_RELAY_INDICES,
487
1
			);
488
1
			assert_eq!(
489
1
				<pallet_xcm_transactor::Pallet::<
490
1
					moonbase_runtime::Runtime> as StakeEncodeCall
491
1
				>::encode_call(
492
1
					xcm_primitives::AvailableStakeCalls::Nominate(vec![
493
1
						relay_account.into()
494
1
					])
495
1
				),
496
1
				expected_encoded
497
1
			);
498
1
		});
499
1
	}
500
	#[test]
501
1
	fn test_stake_chill() {
502
1
		let mut expected_encoded: Vec<u8> = Vec::new();
503
1

            
504
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
505
1
			westend_runtime::Staking,
506
1
		>()
507
1
		.unwrap() as u8;
508
1
		expected_encoded.push(index);
509
1

            
510
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::chill {}.encode();
511
1
		expected_encoded.append(&mut expected);
512
1

            
513
1
		assert_eq!(
514
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
515
1
				xcm_primitives::AvailableStakeCalls::Chill
516
1
			),
517
1
			expected_encoded.clone()
518
1
		);
519
1
		sp_io::TestExternalities::default().execute_with(|| {
520
1
			// Pallet-xcm-transactor default encoder returns same result
521
1
			// insert storage item as per migration to set the storage item
522
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
523
1
				WESTEND_RELAY_INDICES,
524
1
			);
525
1
			assert_eq!(
526
1
				<pallet_xcm_transactor::Pallet::<
527
1
					moonbase_runtime::Runtime> as StakeEncodeCall
528
1
				>::encode_call(
529
1
					xcm_primitives::AvailableStakeCalls::Chill
530
1
				),
531
1
				expected_encoded
532
1
			);
533
1
		});
534
1
	}
535

            
536
	#[test]
537
1
	fn test_set_payee() {
538
1
		let mut expected_encoded: Vec<u8> = Vec::new();
539
1
		let controller: AccountId32 = [1u8; 32].into();
540
1

            
541
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
542
1
			westend_runtime::Staking,
543
1
		>()
544
1
		.unwrap() as u8;
545
1
		expected_encoded.push(index);
546
1

            
547
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::set_payee {
548
1
			payee: pallet_staking::RewardDestination::Account(controller.clone()),
549
1
		}
550
1
		.encode();
551
1
		expected_encoded.append(&mut expected);
552
1

            
553
1
		assert_eq!(
554
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
555
1
				xcm_primitives::AvailableStakeCalls::SetPayee(
556
1
					pallet_staking::RewardDestination::Account(controller.clone())
557
1
				)
558
1
			),
559
1
			expected_encoded.clone()
560
1
		);
561
1
		sp_io::TestExternalities::default().execute_with(|| {
562
1
			// Pallet-xcm-transactor default encoder returns same result
563
1
			// insert storage item as per migration to set the storage item
564
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
565
1
				WESTEND_RELAY_INDICES,
566
1
			);
567
1
			assert_eq!(
568
1
				<pallet_xcm_transactor::Pallet::<
569
1
					moonbase_runtime::Runtime> as StakeEncodeCall
570
1
				>::encode_call(
571
1
					xcm_primitives::AvailableStakeCalls::SetPayee(
572
1
						pallet_staking::RewardDestination::Account(controller)
573
1
					)
574
1
				),
575
1
				expected_encoded
576
1
			);
577
1
		});
578
1
	}
579

            
580
	#[test]
581
1
	fn test_set_controller() {
582
1
		let mut expected_encoded: Vec<u8> = Vec::new();
583
1

            
584
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
585
1
			westend_runtime::Staking,
586
1
		>()
587
1
		.unwrap() as u8;
588
1
		expected_encoded.push(index);
589
1

            
590
1
		let mut expected =
591
1
			pallet_staking::Call::<westend_runtime::Runtime>::set_controller {}.encode();
592
1
		expected_encoded.append(&mut expected);
593
1

            
594
1
		assert_eq!(
595
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
596
1
				xcm_primitives::AvailableStakeCalls::SetController
597
1
			),
598
1
			expected_encoded.clone()
599
1
		);
600
1
		sp_io::TestExternalities::default().execute_with(|| {
601
1
			// Pallet-xcm-transactor default encoder returns same result
602
1
			// insert storage item as per migration to set the storage item
603
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
604
1
				WESTEND_RELAY_INDICES,
605
1
			);
606
1
			assert_eq!(
607
1
				<pallet_xcm_transactor::Pallet::<
608
1
					moonbase_runtime::Runtime> as StakeEncodeCall
609
1
				>::encode_call(
610
1
					xcm_primitives::AvailableStakeCalls::SetController
611
1
				),
612
1
				expected_encoded
613
1
			);
614
1
		});
615
1
	}
616
	#[test]
617
1
	fn test_rebond() {
618
1
		let mut expected_encoded: Vec<u8> = Vec::new();
619
1

            
620
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
621
1
			westend_runtime::Staking,
622
1
		>()
623
1
		.unwrap() as u8;
624
1
		expected_encoded.push(index);
625
1

            
626
1
		let mut expected = pallet_staking::Call::<westend_runtime::Runtime>::rebond {
627
1
			value: 100u32.into(),
628
1
		}
629
1
		.encode();
630
1
		expected_encoded.append(&mut expected);
631
1

            
632
1
		assert_eq!(
633
1
			<WestendEncoder as StakeEncodeCall>::encode_call(
634
1
				xcm_primitives::AvailableStakeCalls::Rebond(100u32.into())
635
1
			),
636
1
			expected_encoded.clone()
637
1
		);
638
1
		sp_io::TestExternalities::default().execute_with(|| {
639
1
			// Pallet-xcm-transactor default encoder returns same result
640
1
			// insert storage item as per migration to set the storage item
641
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
642
1
				WESTEND_RELAY_INDICES,
643
1
			);
644
1
			assert_eq!(
645
1
				<pallet_xcm_transactor::Pallet::<
646
1
					moonbase_runtime::Runtime> as StakeEncodeCall
647
1
				>::encode_call(
648
1
					xcm_primitives::AvailableStakeCalls::Rebond(100u32.into())
649
1
				),
650
1
				expected_encoded
651
1
			);
652
1
		});
653
1
	}
654

            
655
	#[test]
656
1
	fn test_hrmp_init() {
657
1
		let mut expected_encoded: Vec<u8> = Vec::new();
658
1

            
659
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
660
1
			westend_runtime::Hrmp,
661
1
		>()
662
1
		.unwrap() as u8;
663
1
		expected_encoded.push(index);
664
1

            
665
1
		let mut expected = polkadot_runtime_parachains::hrmp::Call::<
666
1
			westend_runtime::Runtime
667
1
		>::hrmp_init_open_channel {
668
1
			recipient: 1000u32.into(),
669
1
			proposed_max_capacity: 100u32,
670
1
			proposed_max_message_size: 100u32,
671
1
		}
672
1
		.encode();
673
1
		expected_encoded.append(&mut expected);
674
1

            
675
1
		assert_eq!(
676
1
			<WestendEncoder as xcm_primitives::HrmpEncodeCall>::hrmp_encode_call(
677
1
				xcm_primitives::HrmpAvailableCalls::InitOpenChannel(
678
1
					1000u32.into(),
679
1
					100u32.into(),
680
1
					100u32.into()
681
1
				)
682
1
			),
683
1
			Ok(expected_encoded.clone())
684
1
		);
685
1
		sp_io::TestExternalities::default().execute_with(|| {
686
1
			// Pallet-xcm-transactor default encoder returns same result
687
1
			// insert storage item as per migration to set the storage item
688
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
689
1
				WESTEND_RELAY_INDICES,
690
1
			);
691
1
			assert_eq!(
692
1
				<pallet_xcm_transactor::Pallet::<
693
1
					moonbase_runtime::Runtime> as xcm_primitives::HrmpEncodeCall
694
1
				>::hrmp_encode_call(
695
1
					xcm_primitives::HrmpAvailableCalls::InitOpenChannel(
696
1
						1000u32.into(),
697
1
						100u32.into(),
698
1
						100u32.into()
699
1
					)
700
1
				),
701
1
				Ok(expected_encoded)
702
1
			);
703
1
		});
704
1
	}
705

            
706
	#[test]
707
1
	fn test_hrmp_accept() {
708
1
		let mut expected_encoded: Vec<u8> = Vec::new();
709
1

            
710
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
711
1
			westend_runtime::Hrmp,
712
1
		>()
713
1
		.unwrap() as u8;
714
1
		expected_encoded.push(index);
715
1

            
716
1
		let mut expected = polkadot_runtime_parachains::hrmp::Call::<
717
1
			westend_runtime::Runtime
718
1
		>::hrmp_accept_open_channel {
719
1
			sender: 1000u32.into()
720
1
		}
721
1
		.encode();
722
1
		expected_encoded.append(&mut expected);
723
1

            
724
1
		assert_eq!(
725
1
			<WestendEncoder as xcm_primitives::HrmpEncodeCall>::hrmp_encode_call(
726
1
				xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(1000u32.into(),)
727
1
			),
728
1
			Ok(expected_encoded.clone())
729
1
		);
730
1
		sp_io::TestExternalities::default().execute_with(|| {
731
1
			// Pallet-xcm-transactor default encoder returns same result
732
1
			// insert storage item as per migration to set the storage item
733
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
734
1
				WESTEND_RELAY_INDICES,
735
1
			);
736
1
			assert_eq!(
737
1
				<pallet_xcm_transactor::Pallet::<
738
1
					moonbase_runtime::Runtime> as xcm_primitives::HrmpEncodeCall
739
1
				>::hrmp_encode_call(
740
1
					xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(1000u32.into(),)
741
1
				),
742
1
				Ok(expected_encoded)
743
1
			);
744
1
		});
745
1
	}
746

            
747
	#[test]
748
1
	fn test_hrmp_close() {
749
1
		let mut expected_encoded: Vec<u8> = Vec::new();
750
1

            
751
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
752
1
			westend_runtime::Hrmp,
753
1
		>()
754
1
		.unwrap() as u8;
755
1
		expected_encoded.push(index);
756
1

            
757
1
		let mut expected = polkadot_runtime_parachains::hrmp::Call::<
758
1
			westend_runtime::Runtime
759
1
		>::hrmp_close_channel {
760
1
			channel_id: HrmpChannelId {
761
1
				sender: 1000u32.into(),
762
1
				recipient: 1001u32.into()
763
1
			}
764
1
		}
765
1
		.encode();
766
1
		expected_encoded.append(&mut expected);
767
1

            
768
1
		assert_eq!(
769
1
			<WestendEncoder as xcm_primitives::HrmpEncodeCall>::hrmp_encode_call(
770
1
				xcm_primitives::HrmpAvailableCalls::CloseChannel(HrmpChannelId {
771
1
					sender: 1000u32.into(),
772
1
					recipient: 1001u32.into()
773
1
				})
774
1
			),
775
1
			Ok(expected_encoded.clone())
776
1
		);
777
1
		sp_io::TestExternalities::default().execute_with(|| {
778
1
			// Pallet-xcm-transactor default encoder returns same result
779
1
			// insert storage item as per migration to set the storage item
780
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
781
1
				WESTEND_RELAY_INDICES,
782
1
			);
783
1
			assert_eq!(
784
1
				<pallet_xcm_transactor::Pallet::<
785
1
					moonbase_runtime::Runtime> as xcm_primitives::HrmpEncodeCall
786
1
				>::hrmp_encode_call(
787
1
					xcm_primitives::HrmpAvailableCalls::CloseChannel(HrmpChannelId {
788
1
						sender: 1000u32.into(),
789
1
						recipient: 1001u32.into()
790
1
					})
791
1
				),
792
1
				Ok(expected_encoded)
793
1
			);
794
1
		});
795
1
	}
796

            
797
	#[test]
798
1
	fn test_hrmp_cancel() {
799
1
		let mut expected_encoded: Vec<u8> = Vec::new();
800
1

            
801
1
		let index = <westend_runtime::Runtime as frame_system::Config>::PalletInfo::index::<
802
1
			westend_runtime::Hrmp,
803
1
		>()
804
1
		.unwrap() as u8;
805
1
		expected_encoded.push(index);
806
1

            
807
1
		let channel_id = HrmpChannelId {
808
1
			sender: 1u32.into(),
809
1
			recipient: 1u32.into(),
810
1
		};
811
1
		let open_requests: u32 = 1;
812
1

            
813
1
		let mut expected = polkadot_runtime_parachains::hrmp::Call::<
814
1
			westend_runtime::Runtime
815
1
		>::hrmp_cancel_open_request {
816
1
			channel_id: channel_id.clone(),
817
1
			open_requests
818
1
		}
819
1
		.encode();
820
1
		expected_encoded.append(&mut expected);
821
1

            
822
1
		assert_eq!(
823
1
			<WestendEncoder as xcm_primitives::HrmpEncodeCall>::hrmp_encode_call(
824
1
				xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(
825
1
					channel_id.clone(),
826
1
					open_requests
827
1
				)
828
1
			),
829
1
			Ok(expected_encoded.clone())
830
1
		);
831
1
		sp_io::TestExternalities::default().execute_with(|| {
832
1
			// Pallet-xcm-transactor default encoder returns same result
833
1
			// insert storage item as per migration to set the storage item
834
1
			pallet_xcm_transactor::RelayIndices::<moonbase_runtime::Runtime>::put(
835
1
				WESTEND_RELAY_INDICES,
836
1
			);
837
1
			assert_eq!(
838
1
				<pallet_xcm_transactor::Pallet::<
839
1
					moonbase_runtime::Runtime> as xcm_primitives::HrmpEncodeCall
840
1
				>::hrmp_encode_call(
841
1
					xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(
842
1
						channel_id.clone(),
843
1
						open_requests
844
1
					)
845
1
				),
846
1
				Ok(expected_encoded)
847
1
			);
848
1
		});
849
1
	}
850
}