1
// Copyright (C) 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
//! XCM `Junctions`/`InteriorLocation` datatype.
18

            
19
use super::{Junction, Location, NetworkId};
20
use alloc::sync::Arc;
21
use codec::{Decode, Encode, MaxEncodedLen};
22
use core::{mem, ops::Range, result};
23
use scale_info::TypeInfo;
24

            
25
/// Maximum number of `Junction`s that a `Junctions` can contain.
26
pub(crate) const MAX_JUNCTIONS: usize = 8;
27

            
28
/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions`
29
/// implementation uses a Rust `enum` in order to make pattern matching easier.
30
///
31
/// Parent junctions cannot be constructed with this type. Refer to `Location` for
32
/// instructions on constructing parent junctions.
33
#[derive(
34
	Clone,
35
	Eq,
36
	PartialEq,
37
	Ord,
38
	PartialOrd,
39
	Encode,
40
444
	Decode,
41
	Debug,
42
	TypeInfo,
43
	MaxEncodedLen,
44
	serde::Serialize,
45
	serde::Deserialize,
46
)]
47
pub enum Junctions {
48
23943
	/// The interpreting consensus system.
49
23943
	Here,
50
4905
	/// A relative path comprising 1 junction.
51
4905
	X1(Arc<[Junction; 1]>),
52
1020
	/// A relative path comprising 2 junctions.
53
1020
	X2(Arc<[Junction; 2]>),
54
474
	/// A relative path comprising 3 junctions.
55
474
	X3(Arc<[Junction; 3]>),
56
1398
	/// A relative path comprising 4 junctions.
57
1398
	X4(Arc<[Junction; 4]>),
58
1215
	/// A relative path comprising 5 junctions.
59
1215
	X5(Arc<[Junction; 5]>),
60
891
	/// A relative path comprising 6 junctions.
61
891
	X6(Arc<[Junction; 6]>),
62
501
	/// A relative path comprising 7 junctions.
63
501
	X7(Arc<[Junction; 7]>),
64
855
	/// A relative path comprising 8 junctions.
65
855
	X8(Arc<[Junction; 8]>),
66
}
67

            
68
macro_rules! impl_junctions {
69
	($count:expr, $variant:ident) => {
70
		impl From<[Junction; $count]> for Junctions {
71
30680
			fn from(junctions: [Junction; $count]) -> Self {
72
30680
				Self::$variant(Arc::new(junctions))
73
30680
			}
74
		}
75
		impl PartialEq<[Junction; $count]> for Junctions {
76
			fn eq(&self, rhs: &[Junction; $count]) -> bool {
77
				self.as_slice() == rhs
78
			}
79
		}
80
	};
81
}
82

            
83
impl_junctions!(1, X1);
84
impl_junctions!(2, X2);
85
impl_junctions!(3, X3);
86
impl_junctions!(4, X4);
87
impl_junctions!(5, X5);
88
impl_junctions!(6, X6);
89
impl_junctions!(7, X7);
90
impl_junctions!(8, X8);
91

            
92
pub struct JunctionsIterator {
93
	junctions: Junctions,
94
	range: Range<usize>,
95
}
96

            
97
impl Iterator for JunctionsIterator {
98
	type Item = Junction;
99
	fn next(&mut self) -> Option<Junction> {
100
		self.junctions.at(self.range.next()?).cloned()
101
	}
102
}
103

            
104
impl DoubleEndedIterator for JunctionsIterator {
105
1980
	fn next_back(&mut self) -> Option<Junction> {
106
1980
		self.junctions.at(self.range.next_back()?).cloned()
107
1980
	}
108
}
109

            
110
pub struct JunctionsRefIterator<'a> {
111
	junctions: &'a Junctions,
112
	range: Range<usize>,
113
}
114

            
115
impl<'a> Iterator for JunctionsRefIterator<'a> {
116
	type Item = &'a Junction;
117
522
	fn next(&mut self) -> Option<&'a Junction> {
118
522
		self.junctions.at(self.range.next()?)
119
522
	}
120
}
121

            
122
impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> {
123
	fn next_back(&mut self) -> Option<&'a Junction> {
124
		self.junctions.at(self.range.next_back()?)
125
	}
126
}
127
impl<'a> IntoIterator for &'a Junctions {
128
	type Item = &'a Junction;
129
	type IntoIter = JunctionsRefIterator<'a>;
130
260
	fn into_iter(self) -> Self::IntoIter {
131
260
		JunctionsRefIterator { junctions: self, range: 0..self.len() }
132
260
	}
133
}
134

            
135
impl IntoIterator for Junctions {
136
	type Item = Junction;
137
	type IntoIter = JunctionsIterator;
138
1048
	fn into_iter(self) -> Self::IntoIter {
139
1048
		JunctionsIterator { range: 0..self.len(), junctions: self }
140
1048
	}
141
}
142

            
143
impl Junctions {
144
	/// Convert `self` into a `Location` containing 0 parents.
145
	///
146
	/// Similar to `Into::into`, except that this method can be used in a const evaluation context.
147
9856
	pub const fn into_location(self) -> Location {
148
9856
		Location { parents: 0, interior: self }
149
9856
	}
150

            
151
	/// Convert `self` into a `Location` containing `n` parents.
152
	///
153
	/// Similar to `Self::into_location`, with the added ability to specify the number of parent
154
	/// junctions.
155
	pub const fn into_exterior(self, n: u8) -> Location {
156
		Location { parents: n, interior: self }
157
	}
158

            
159
	/// Casts `self` into a slice containing `Junction`s.
160
30378
	pub fn as_slice(&self) -> &[Junction] {
161
30378
		match self {
162
8787
			Junctions::Here => &[],
163
17820
			Junctions::X1(ref a) => &a[..],
164
576
			Junctions::X2(ref a) => &a[..],
165
477
			Junctions::X3(ref a) => &a[..],
166
561
			Junctions::X4(ref a) => &a[..],
167
330
			Junctions::X5(ref a) => &a[..],
168
888
			Junctions::X6(ref a) => &a[..],
169
552
			Junctions::X7(ref a) => &a[..],
170
387
			Junctions::X8(ref a) => &a[..],
171
		}
172
30378
	}
173

            
174
	/// Casts `self` into a mutable slice containing `Junction`s.
175
	pub fn as_slice_mut(&mut self) -> &mut [Junction] {
176
		match self {
177
			Junctions::Here => &mut [],
178
			Junctions::X1(ref mut a) => &mut Arc::make_mut(a)[..],
179
			Junctions::X2(ref mut a) => &mut Arc::make_mut(a)[..],
180
			Junctions::X3(ref mut a) => &mut Arc::make_mut(a)[..],
181
			Junctions::X4(ref mut a) => &mut Arc::make_mut(a)[..],
182
			Junctions::X5(ref mut a) => &mut Arc::make_mut(a)[..],
183
			Junctions::X6(ref mut a) => &mut Arc::make_mut(a)[..],
184
			Junctions::X7(ref mut a) => &mut Arc::make_mut(a)[..],
185
			Junctions::X8(ref mut a) => &mut Arc::make_mut(a)[..],
186
		}
187
	}
188

            
189
	/// Remove the `NetworkId` value in any `Junction`s.
190
	pub fn remove_network_id(&mut self) {
191
		self.for_each_mut(Junction::remove_network_id);
192
	}
193

            
194
	/// Treating `self` as the universal context, return the location of the local consensus system
195
	/// from the point of view of the given `target`.
196
1086
	pub fn invert_target(&self, target: &Location) -> Result<Location, ()> {
197
1086
		let mut itself = self.clone();
198
1086
		let mut junctions = Self::Here;
199
1086
		for _ in 0..target.parent_count() {
200
3184
			junctions = junctions
201
3184
				.pushed_front_with(itself.take_last().unwrap_or(Junction::OnlyChild))
202
3184
				.map_err(|_| ())?;
203
		}
204
890
		let parents = target.interior().len() as u8;
205
890
		Ok(Location::new(parents, junctions))
206
1086
	}
207

            
208
	/// Execute a function `f` on every junction. We use this since we cannot implement a mutable
209
	/// `Iterator` without unsafe code.
210
	pub fn for_each_mut(&mut self, x: impl FnMut(&mut Junction)) {
211
		self.as_slice_mut().iter_mut().for_each(x)
212
	}
213

            
214
	/// Extract the network ID treating this value as a universal location.
215
	///
216
	/// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate
217
	/// that this value is not a universal location.
218
	pub fn global_consensus(&self) -> Result<NetworkId, ()> {
219
		if let Some(Junction::GlobalConsensus(network)) = self.first() {
220
			Ok(*network)
221
		} else {
222
			Err(())
223
		}
224
	}
225

            
226
	/// Extract the network ID and the interior consensus location, treating this value as a
227
	/// universal location.
228
	///
229
	/// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate
230
	/// that this value is not a universal location.
231
	pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> {
232
		match self.split_first() {
233
			(location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)),
234
			_ => return Err(()),
235
		}
236
	}
237

            
238
	/// Treat `self` as a universal location and the context of `relative`, returning the universal
239
	/// location of relative.
240
	///
241
	/// This will return an error if `relative` has as many (or more) parents than there are
242
	/// junctions in `self`, implying that relative refers into a different global consensus.
243
260
	pub fn within_global(mut self, relative: Location) -> Result<Self, ()> {
244
260
		if self.len() <= relative.parent_count() as usize {
245
			return Err(())
246
260
		}
247
260
		for _ in 0..relative.parent_count() {
248
			self.take_last();
249
		}
250
262
		for j in relative.interior() {
251
262
			self.push(*j).map_err(|_| ())?;
252
		}
253
260
		Ok(self)
254
260
	}
255

            
256
	/// Consumes `self` and returns how `viewer` would address it locally.
257
	pub fn relative_to(mut self, viewer: &Junctions) -> Location {
258
		let mut i = 0;
259
		while match (self.first(), viewer.at(i)) {
260
			(Some(x), Some(y)) => x == y,
261
			_ => false,
262
		} {
263
			self = self.split_first().0;
264
			// NOTE: Cannot overflow as loop can only iterate at most `MAX_JUNCTIONS` times.
265
			i += 1;
266
		}
267
		// AUDIT NOTES:
268
		// - above loop ensures that `i <= viewer.len()`.
269
		// - `viewer.len()` is at most `MAX_JUNCTIONS`, so won't overflow a `u8`.
270
		Location::new((viewer.len() - i) as u8, self)
271
	}
272

            
273
	/// Returns first junction, or `None` if the location is empty.
274
520
	pub fn first(&self) -> Option<&Junction> {
275
520
		self.as_slice().first()
276
520
	}
277

            
278
	/// Returns last junction, or `None` if the location is empty.
279
184
	pub fn last(&self) -> Option<&Junction> {
280
184
		self.as_slice().last()
281
184
	}
282

            
283
	/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the
284
	/// first element (second item in tuple) or `None` if it was empty.
285
64
	pub fn split_first(self) -> (Junctions, Option<Junction>) {
286
64
		match self {
287
			Junctions::Here => (Junctions::Here, None),
288
8
			Junctions::X1(xs) => {
289
8
				let [a] = *xs;
290
8
				(Junctions::Here, Some(a))
291
			},
292
4
			Junctions::X2(xs) => {
293
4
				let [a, b] = *xs;
294
4
				([b].into(), Some(a))
295
			},
296
4
			Junctions::X3(xs) => {
297
4
				let [a, b, c] = *xs;
298
4
				([b, c].into(), Some(a))
299
			},
300
14
			Junctions::X4(xs) => {
301
14
				let [a, b, c, d] = *xs;
302
14
				([b, c, d].into(), Some(a))
303
			},
304
6
			Junctions::X5(xs) => {
305
6
				let [a, b, c, d, e] = *xs;
306
6
				([b, c, d, e].into(), Some(a))
307
			},
308
8
			Junctions::X6(xs) => {
309
8
				let [a, b, c, d, e, f] = *xs;
310
8
				([b, c, d, e, f].into(), Some(a))
311
			},
312
10
			Junctions::X7(xs) => {
313
10
				let [a, b, c, d, e, f, g] = *xs;
314
10
				([b, c, d, e, f, g].into(), Some(a))
315
			},
316
10
			Junctions::X8(xs) => {
317
10
				let [a, b, c, d, e, f, g, h] = *xs;
318
10
				([b, c, d, e, f, g, h].into(), Some(a))
319
			},
320
		}
321
64
	}
322

            
323
	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the
324
	/// last element (second item in tuple) or `None` if it was empty.
325
3660
	pub fn split_last(self) -> (Junctions, Option<Junction>) {
326
3660
		match self {
327
2740
			Junctions::Here => (Junctions::Here, None),
328
660
			Junctions::X1(xs) => {
329
660
				let [a] = *xs;
330
660
				(Junctions::Here, Some(a))
331
			},
332
50
			Junctions::X2(xs) => {
333
50
				let [a, b] = *xs;
334
50
				([a].into(), Some(b))
335
			},
336
50
			Junctions::X3(xs) => {
337
50
				let [a, b, c] = *xs;
338
50
				([a, b].into(), Some(c))
339
			},
340
48
			Junctions::X4(xs) => {
341
48
				let [a, b, c, d] = *xs;
342
48
				([a, b, c].into(), Some(d))
343
			},
344
38
			Junctions::X5(xs) => {
345
38
				let [a, b, c, d, e] = *xs;
346
38
				([a, b, c, d].into(), Some(e))
347
			},
348
42
			Junctions::X6(xs) => {
349
42
				let [a, b, c, d, e, f] = *xs;
350
42
				([a, b, c, d, e].into(), Some(f))
351
			},
352
16
			Junctions::X7(xs) => {
353
16
				let [a, b, c, d, e, f, g] = *xs;
354
16
				([a, b, c, d, e, f].into(), Some(g))
355
			},
356
16
			Junctions::X8(xs) => {
357
16
				let [a, b, c, d, e, f, g, h] = *xs;
358
16
				([a, b, c, d, e, f, g].into(), Some(h))
359
			},
360
		}
361
3660
	}
362

            
363
	/// Removes the first element from `self`, returning it (or `None` if it was empty).
364
34
	pub fn take_first(&mut self) -> Option<Junction> {
365
34
		let mut d = Junctions::Here;
366
34
		mem::swap(&mut *self, &mut d);
367
34
		let (tail, head) = d.split_first();
368
34
		*self = tail;
369
34
		head
370
34
	}
371

            
372
	/// Removes the last element from `self`, returning it (or `None` if it was empty).
373
3580
	pub fn take_last(&mut self) -> Option<Junction> {
374
3580
		let mut d = Junctions::Here;
375
3580
		mem::swap(&mut *self, &mut d);
376
3580
		let (head, tail) = d.split_last();
377
3580
		*self = head;
378
3580
		tail
379
3580
	}
380

            
381
	/// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow.
382
262
	pub fn push(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
383
262
		let new = new.into();
384
262
		let mut dummy = Junctions::Here;
385
262
		mem::swap(self, &mut dummy);
386
262
		match dummy.pushed_with(new) {
387
262
			Ok(s) => {
388
262
				*self = s;
389
262
				Ok(())
390
			},
391
			Err((s, j)) => {
392
				*self = s;
393
				Err(j)
394
			},
395
		}
396
262
	}
397

            
398
	/// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow.
399
1080
	pub fn push_front(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
400
1080
		let new = new.into();
401
1080
		let mut dummy = Junctions::Here;
402
1080
		mem::swap(self, &mut dummy);
403
1080
		match dummy.pushed_front_with(new) {
404
1080
			Ok(s) => {
405
1080
				*self = s;
406
1080
				Ok(())
407
			},
408
			Err((s, j)) => {
409
				*self = s;
410
				Err(j)
411
			},
412
		}
413
1080
	}
414

            
415
	/// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the
416
	/// original value of `self` and `new` in case of overflow.
417
262
	pub fn pushed_with(self, new: impl Into<Junction>) -> result::Result<Self, (Self, Junction)> {
418
262
		let new = new.into();
419
262
		Ok(match self {
420
			Junctions::Here => [new].into(),
421
260
			Junctions::X1(xs) => {
422
260
				let [a] = *xs;
423
260
				[a, new].into()
424
			},
425
2
			Junctions::X2(xs) => {
426
2
				let [a, b] = *xs;
427
2
				[a, b, new].into()
428
			},
429
			Junctions::X3(xs) => {
430
				let [a, b, c] = *xs;
431
				[a, b, c, new].into()
432
			},
433
			Junctions::X4(xs) => {
434
				let [a, b, c, d] = *xs;
435
				[a, b, c, d, new].into()
436
			},
437
			Junctions::X5(xs) => {
438
				let [a, b, c, d, e] = *xs;
439
				[a, b, c, d, e, new].into()
440
			},
441
			Junctions::X6(xs) => {
442
				let [a, b, c, d, e, f] = *xs;
443
				[a, b, c, d, e, f, new].into()
444
			},
445
			Junctions::X7(xs) => {
446
				let [a, b, c, d, e, f, g] = *xs;
447
				[a, b, c, d, e, f, g, new].into()
448
			},
449
			s => Err((s, new))?,
450
		})
451
262
	}
452

            
453
	/// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the
454
	/// original value of `self` and `new` in case of overflow.
455
4264
	pub fn pushed_front_with(
456
4264
		self,
457
4264
		new: impl Into<Junction>,
458
4264
	) -> result::Result<Self, (Self, Junction)> {
459
4264
		let new = new.into();
460
4264
		Ok(match self {
461
735
			Junctions::Here => [new].into(),
462
682
			Junctions::X1(xs) => {
463
682
				let [a] = *xs;
464
682
				[new, a].into()
465
			},
466
579
			Junctions::X2(xs) => {
467
579
				let [a, b] = *xs;
468
579
				[new, a, b].into()
469
			},
470
534
			Junctions::X3(xs) => {
471
534
				let [a, b, c] = *xs;
472
534
				[new, a, b, c].into()
473
			},
474
470
			Junctions::X4(xs) => {
475
470
				let [a, b, c, d] = *xs;
476
470
				[new, a, b, c, d].into()
477
			},
478
429
			Junctions::X5(xs) => {
479
429
				let [a, b, c, d, e] = *xs;
480
429
				[new, a, b, c, d, e].into()
481
			},
482
343
			Junctions::X6(xs) => {
483
343
				let [a, b, c, d, e, f] = *xs;
484
343
				[new, a, b, c, d, e, f].into()
485
			},
486
296
			Junctions::X7(xs) => {
487
296
				let [a, b, c, d, e, f, g] = *xs;
488
296
				[new, a, b, c, d, e, f, g].into()
489
			},
490
196
			s => Err((s, new))?,
491
		})
492
4264
	}
493

            
494
	/// Mutate `self` so that it is suffixed with `suffix`.
495
	///
496
	/// Does not modify `self` and returns `Err` with `suffix` in case of overflow.
497
	///
498
	/// # Example
499
	/// ```rust
500
	/// # use staging_xcm::v4::{Junctions, Junction::*, Location};
501
	/// # fn main() {
502
	/// let mut m = Junctions::from([Parachain(21)]);
503
	/// assert_eq!(m.append_with([PalletInstance(3)]), Ok(()));
504
	/// assert_eq!(m, [Parachain(21), PalletInstance(3)]);
505
	/// # }
506
	/// ```
507
	pub fn append_with(&mut self, suffix: impl Into<Junctions>) -> Result<(), Junctions> {
508
		let suffix = suffix.into();
509
		if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS {
510
			return Err(suffix)
511
		}
512
		for j in suffix.into_iter() {
513
			self.push(j).expect("Already checked the sum of the len()s; qed")
514
		}
515
		Ok(())
516
	}
517

            
518
	/// Returns the number of junctions in `self`.
519
6878
	pub fn len(&self) -> usize {
520
6878
		self.as_slice().len()
521
6878
	}
522

            
523
	/// Returns the junction at index `i`, or `None` if the location doesn't contain that many
524
	/// elements.
525
1506
	pub fn at(&self, i: usize) -> Option<&Junction> {
526
1506
		self.as_slice().get(i)
527
1506
	}
528

            
529
	/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't
530
	/// contain that many elements.
531
	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
532
		self.as_slice_mut().get_mut(i)
533
	}
534

            
535
	/// Returns a reference iterator over the junctions.
536
	pub fn iter(&self) -> JunctionsRefIterator {
537
		JunctionsRefIterator { junctions: self, range: 0..self.len() }
538
	}
539

            
540
	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
541
	/// If so, returns a reference to this `Junction` item.
542
	///
543
	/// # Example
544
	/// ```rust
545
	/// # use staging_xcm::v4::{Junctions, Junction::*};
546
	/// # fn main() {
547
	/// let mut m = Junctions::from([Parachain(2), PalletInstance(3), OnlyChild]);
548
	/// assert_eq!(m.match_and_split(&[Parachain(2), PalletInstance(3)].into()), Some(&OnlyChild));
549
	/// assert_eq!(m.match_and_split(&[Parachain(2)].into()), None);
550
	/// # }
551
	/// ```
552
	pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
553
		if prefix.len() + 1 != self.len() {
554
			return None
555
		}
556
		for i in 0..prefix.len() {
557
			if prefix.at(i) != self.at(i) {
558
				return None
559
			}
560
		}
561
		return self.at(prefix.len())
562
	}
563

            
564
	pub fn starts_with(&self, prefix: &Junctions) -> bool {
565
		prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y)
566
	}
567
}
568

            
569
impl TryFrom<Location> for Junctions {
570
	type Error = Location;
571
1778
	fn try_from(x: Location) -> result::Result<Self, Location> {
572
1778
		if x.parent_count() > 0 {
573
			Err(x)
574
		} else {
575
1778
			Ok(x.interior().clone())
576
		}
577
1778
	}
578
}
579

            
580
impl<T: Into<Junction>> From<T> for Junctions {
581
5316
	fn from(x: T) -> Self {
582
5316
		[x.into()].into()
583
5316
	}
584
}
585

            
586
impl From<[Junction; 0]> for Junctions {
587
	fn from(_: [Junction; 0]) -> Self {
588
		Self::Here
589
	}
590
}
591

            
592
impl From<()> for Junctions {
593
	fn from(_: ()) -> Self {
594
		Self::Here
595
	}
596
}
597

            
598
15910
xcm_procedural::impl_conversion_functions_for_junctions_v4!();
599

            
600
#[cfg(test)]
601
mod tests {
602
	use super::{super::prelude::*, *};
603

            
604
	#[test]
605
	fn inverting_works() {
606
		let context: InteriorLocation = (Parachain(1000), PalletInstance(42)).into();
607
		let target = (Parent, PalletInstance(69)).into();
608
		let expected = (Parent, PalletInstance(42)).into();
609
		let inverted = context.invert_target(&target).unwrap();
610
		assert_eq!(inverted, expected);
611

            
612
		let context: InteriorLocation =
613
			(Parachain(1000), PalletInstance(42), GeneralIndex(1)).into();
614
		let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into();
615
		let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into();
616
		let inverted = context.invert_target(&target).unwrap();
617
		assert_eq!(inverted, expected);
618
	}
619

            
620
	#[test]
621
	fn relative_to_works() {
622
		use NetworkId::*;
623
		assert_eq!(
624
			Junctions::from([Polkadot.into()]).relative_to(&Junctions::from([Kusama.into()])),
625
			(Parent, Polkadot).into()
626
		);
627
		let base = Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]);
628

            
629
		// Ancestors.
630
		assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into());
631
		assert_eq!(Junctions::from([Kusama.into()]).relative_to(&base), (Parent, Parent).into());
632
		assert_eq!(
633
			Junctions::from([Kusama.into(), Parachain(1)]).relative_to(&base),
634
			(Parent,).into()
635
		);
636
		assert_eq!(
637
			Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]).relative_to(&base),
638
			Here.into()
639
		);
640

            
641
		// Ancestors with one child.
642
		assert_eq!(
643
			Junctions::from([Polkadot.into()]).relative_to(&base),
644
			(Parent, Parent, Parent, Polkadot).into()
645
		);
646
		assert_eq!(
647
			Junctions::from([Kusama.into(), Parachain(2)]).relative_to(&base),
648
			(Parent, Parent, Parachain(2)).into()
649
		);
650
		assert_eq!(
651
			Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2)]).relative_to(&base),
652
			(Parent, PalletInstance(2)).into()
653
		);
654
		assert_eq!(
655
			Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()])
656
				.relative_to(&base),
657
			([1u8; 32],).into()
658
		);
659

            
660
		// Ancestors with grandchildren.
661
		assert_eq!(
662
			Junctions::from([Polkadot.into(), Parachain(1)]).relative_to(&base),
663
			(Parent, Parent, Parent, Polkadot, Parachain(1)).into()
664
		);
665
		assert_eq!(
666
			Junctions::from([Kusama.into(), Parachain(2), PalletInstance(1)]).relative_to(&base),
667
			(Parent, Parent, Parachain(2), PalletInstance(1)).into()
668
		);
669
		assert_eq!(
670
			Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()])
671
				.relative_to(&base),
672
			(Parent, PalletInstance(2), [1u8; 32]).into()
673
		);
674
		assert_eq!(
675
			Junctions::from([
676
				Kusama.into(),
677
				Parachain(1),
678
				PalletInstance(1),
679
				[1u8; 32].into(),
680
				1u128.into()
681
			])
682
			.relative_to(&base),
683
			([1u8; 32], 1u128).into()
684
		);
685
	}
686

            
687
	#[test]
688
	fn global_consensus_works() {
689
		use NetworkId::*;
690
		assert_eq!(Junctions::from([Polkadot.into()]).global_consensus(), Ok(Polkadot));
691
		assert_eq!(Junctions::from([Kusama.into(), 1u64.into()]).global_consensus(), Ok(Kusama));
692
		assert_eq!(Here.global_consensus(), Err(()));
693
		assert_eq!(Junctions::from([1u64.into()]).global_consensus(), Err(()));
694
		assert_eq!(Junctions::from([1u64.into(), Kusama.into()]).global_consensus(), Err(()));
695
	}
696

            
697
	#[test]
698
	fn test_conversion() {
699
		use super::{Junction::*, NetworkId::*};
700
		let x: Junctions = GlobalConsensus(Polkadot).into();
701
		assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)]));
702
		let x: Junctions = Polkadot.into();
703
		assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)]));
704
		let x: Junctions = (Polkadot, Kusama).into();
705
		assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot), GlobalConsensus(Kusama)]));
706
	}
707

            
708
	#[test]
709
	fn encode_decode_junctions_works() {
710
		let original = Junctions::from([
711
			Polkadot.into(),
712
			Kusama.into(),
713
			1u64.into(),
714
			GlobalConsensus(Polkadot),
715
			Parachain(123),
716
			PalletInstance(45),
717
		]);
718
		let encoded = original.encode();
719
		assert_eq!(encoded, &[6, 9, 2, 9, 3, 2, 0, 4, 9, 2, 0, 237, 1, 4, 45]);
720
		let decoded = Junctions::decode(&mut &encoded[..]).unwrap();
721
		assert_eq!(decoded, original);
722
	}
723
}