1use super::{Junction, MultiLocation, NetworkId};
20use codec::{Decode, Encode, MaxEncodedLen};
21use core::{mem, result};
22use scale_info::TypeInfo;
23
24pub(crate) const MAX_JUNCTIONS: usize = 8;
26
27#[derive(
33 Copy,
34 Clone,
35 Eq,
36 PartialEq,
37 Ord,
38 PartialOrd,
39 Encode,
40 Decode,
41 Debug,
42 TypeInfo,
43 MaxEncodedLen,
44 serde::Serialize,
45 serde::Deserialize,
46)]
47#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
48#[scale_info(replace_segment("staging_xcm", "xcm"))]
49pub enum Junctions {
50 Here,
52 X1(Junction),
54 X2(Junction, Junction),
56 X3(Junction, Junction, Junction),
58 X4(Junction, Junction, Junction, Junction),
60 X5(Junction, Junction, Junction, Junction, Junction),
62 X6(Junction, Junction, Junction, Junction, Junction, Junction),
64 X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
66 X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
68}
69
70macro_rules! impl_junction {
71 ($count:expr, $variant:ident, ($($index:literal),+)) => {
72 impl From<[Junction; $count]> for Junctions {
75 fn from(junctions: [Junction; $count]) -> Self {
76 Self::$variant($(junctions[$index]),*)
77 }
78 }
79 };
80}
81
82impl_junction!(1, X1, (0));
83impl_junction!(2, X2, (0, 1));
84impl_junction!(3, X3, (0, 1, 2));
85impl_junction!(4, X4, (0, 1, 2, 3));
86impl_junction!(5, X5, (0, 1, 2, 3, 4));
87impl_junction!(6, X6, (0, 1, 2, 3, 4, 5));
88impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6));
89impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7));
90
91pub struct JunctionsIterator(Junctions);
92impl Iterator for JunctionsIterator {
93 type Item = Junction;
94 fn next(&mut self) -> Option<Junction> {
95 self.0.take_first()
96 }
97}
98
99impl DoubleEndedIterator for JunctionsIterator {
100 fn next_back(&mut self) -> Option<Junction> {
101 self.0.take_last()
102 }
103}
104
105pub struct JunctionsRefIterator<'a> {
106 junctions: &'a Junctions,
107 next: usize,
108 back: usize,
109}
110
111impl<'a> Iterator for JunctionsRefIterator<'a> {
112 type Item = &'a Junction;
113 fn next(&mut self) -> Option<&'a Junction> {
114 if self.next.saturating_add(self.back) >= self.junctions.len() {
115 return None
116 }
117
118 let result = self.junctions.at(self.next);
119 self.next += 1;
120 result
121 }
122}
123
124impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> {
125 fn next_back(&mut self) -> Option<&'a Junction> {
126 let next_back = self.back.saturating_add(1);
127 let index = self.junctions.len().checked_sub(next_back)?;
129 if self.next > index {
130 return None
131 }
132 self.back = next_back;
133
134 self.junctions.at(index)
135 }
136}
137impl<'a> IntoIterator for &'a Junctions {
138 type Item = &'a Junction;
139 type IntoIter = JunctionsRefIterator<'a>;
140 fn into_iter(self) -> Self::IntoIter {
141 JunctionsRefIterator { junctions: self, next: 0, back: 0 }
142 }
143}
144
145impl IntoIterator for Junctions {
146 type Item = Junction;
147 type IntoIter = JunctionsIterator;
148 fn into_iter(self) -> Self::IntoIter {
149 JunctionsIterator(self)
150 }
151}
152
153impl Junctions {
154 pub const fn into_location(self) -> MultiLocation {
158 MultiLocation { parents: 0, interior: self }
159 }
160
161 pub const fn into_exterior(self, n: u8) -> MultiLocation {
166 MultiLocation { parents: n, interior: self }
167 }
168
169 pub fn remove_network_id(&mut self) {
171 self.for_each_mut(Junction::remove_network_id);
172 }
173
174 pub fn invert_target(mut self, target: &MultiLocation) -> Result<MultiLocation, ()> {
177 let mut junctions = Self::Here;
178 for _ in 0..target.parent_count() {
179 junctions = junctions
180 .pushed_front_with(self.take_last().unwrap_or(Junction::OnlyChild))
181 .map_err(|_| ())?;
182 }
183 let parents = target.interior().len() as u8;
184 Ok(MultiLocation::new(parents, junctions))
185 }
186
187 pub fn for_each_mut(&mut self, mut x: impl FnMut(&mut Junction)) {
190 match self {
191 Junctions::Here => {},
192 Junctions::X1(a) => {
193 x(a);
194 },
195 Junctions::X2(a, b) => {
196 x(a);
197 x(b);
198 },
199 Junctions::X3(a, b, c) => {
200 x(a);
201 x(b);
202 x(c);
203 },
204 Junctions::X4(a, b, c, d) => {
205 x(a);
206 x(b);
207 x(c);
208 x(d);
209 },
210 Junctions::X5(a, b, c, d, e) => {
211 x(a);
212 x(b);
213 x(c);
214 x(d);
215 x(e);
216 },
217 Junctions::X6(a, b, c, d, e, f) => {
218 x(a);
219 x(b);
220 x(c);
221 x(d);
222 x(e);
223 x(f);
224 },
225 Junctions::X7(a, b, c, d, e, f, g) => {
226 x(a);
227 x(b);
228 x(c);
229 x(d);
230 x(e);
231 x(f);
232 x(g);
233 },
234 Junctions::X8(a, b, c, d, e, f, g, h) => {
235 x(a);
236 x(b);
237 x(c);
238 x(d);
239 x(e);
240 x(f);
241 x(g);
242 x(h);
243 },
244 }
245 }
246
247 pub fn global_consensus(&self) -> Result<NetworkId, ()> {
252 if let Some(Junction::GlobalConsensus(network)) = self.first() {
253 Ok(*network)
254 } else {
255 Err(())
256 }
257 }
258
259 pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> {
265 match self.split_first() {
266 (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)),
267 _ => return Err(()),
268 }
269 }
270
271 pub fn within_global(mut self, relative: MultiLocation) -> Result<Self, ()> {
277 if self.len() <= relative.parents as usize {
278 return Err(())
279 }
280 for _ in 0..relative.parents {
281 self.take_last();
282 }
283 for j in relative.interior {
284 self.push(j).map_err(|_| ())?;
285 }
286 Ok(self)
287 }
288
289 pub fn relative_to(mut self, viewer: &Junctions) -> MultiLocation {
291 let mut i = 0;
292 while match (self.first(), viewer.at(i)) {
293 (Some(x), Some(y)) => x == y,
294 _ => false,
295 } {
296 self = self.split_first().0;
297 i += 1;
299 }
300 MultiLocation { parents: (viewer.len() - i) as u8, interior: self }
304 }
305
306 pub fn first(&self) -> Option<&Junction> {
308 match &self {
309 Junctions::Here => None,
310 Junctions::X1(ref a) => Some(a),
311 Junctions::X2(ref a, ..) => Some(a),
312 Junctions::X3(ref a, ..) => Some(a),
313 Junctions::X4(ref a, ..) => Some(a),
314 Junctions::X5(ref a, ..) => Some(a),
315 Junctions::X6(ref a, ..) => Some(a),
316 Junctions::X7(ref a, ..) => Some(a),
317 Junctions::X8(ref a, ..) => Some(a),
318 }
319 }
320
321 pub fn last(&self) -> Option<&Junction> {
323 match &self {
324 Junctions::Here => None,
325 Junctions::X1(ref a) => Some(a),
326 Junctions::X2(.., ref a) => Some(a),
327 Junctions::X3(.., ref a) => Some(a),
328 Junctions::X4(.., ref a) => Some(a),
329 Junctions::X5(.., ref a) => Some(a),
330 Junctions::X6(.., ref a) => Some(a),
331 Junctions::X7(.., ref a) => Some(a),
332 Junctions::X8(.., ref a) => Some(a),
333 }
334 }
335
336 pub fn split_first(self) -> (Junctions, Option<Junction>) {
339 match self {
340 Junctions::Here => (Junctions::Here, None),
341 Junctions::X1(a) => (Junctions::Here, Some(a)),
342 Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
343 Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
344 Junctions::X4(a, b, c, d) => (Junctions::X3(b, c, d), Some(a)),
345 Junctions::X5(a, b, c, d, e) => (Junctions::X4(b, c, d, e), Some(a)),
346 Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)),
347 Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)),
348 Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)),
349 }
350 }
351
352 pub fn split_last(self) -> (Junctions, Option<Junction>) {
355 match self {
356 Junctions::Here => (Junctions::Here, None),
357 Junctions::X1(a) => (Junctions::Here, Some(a)),
358 Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
359 Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
360 Junctions::X4(a, b, c, d) => (Junctions::X3(a, b, c), Some(d)),
361 Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)),
362 Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)),
363 Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)),
364 Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)),
365 }
366 }
367
368 pub fn take_first(&mut self) -> Option<Junction> {
370 let mut d = Junctions::Here;
371 mem::swap(&mut *self, &mut d);
372 let (tail, head) = d.split_first();
373 *self = tail;
374 head
375 }
376
377 pub fn take_last(&mut self) -> Option<Junction> {
379 let mut d = Junctions::Here;
380 mem::swap(&mut *self, &mut d);
381 let (head, tail) = d.split_last();
382 *self = head;
383 tail
384 }
385
386 pub fn push(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
388 let new = new.into();
389 let mut dummy = Junctions::Here;
390 mem::swap(self, &mut dummy);
391 match dummy.pushed_with(new) {
392 Ok(s) => {
393 *self = s;
394 Ok(())
395 },
396 Err((s, j)) => {
397 *self = s;
398 Err(j)
399 },
400 }
401 }
402
403 pub fn push_front(&mut self, new: impl Into<Junction>) -> result::Result<(), Junction> {
405 let new = new.into();
406 let mut dummy = Junctions::Here;
407 mem::swap(self, &mut dummy);
408 match dummy.pushed_front_with(new) {
409 Ok(s) => {
410 *self = s;
411 Ok(())
412 },
413 Err((s, j)) => {
414 *self = s;
415 Err(j)
416 },
417 }
418 }
419
420 pub fn pushed_with(self, new: impl Into<Junction>) -> result::Result<Self, (Self, Junction)> {
423 let new = new.into();
424 Ok(match self {
425 Junctions::Here => Junctions::X1(new),
426 Junctions::X1(a) => Junctions::X2(a, new),
427 Junctions::X2(a, b) => Junctions::X3(a, b, new),
428 Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
429 Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new),
430 Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new),
431 Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new),
432 Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new),
433 s => Err((s, new))?,
434 })
435 }
436
437 pub fn pushed_front_with(
440 self,
441 new: impl Into<Junction>,
442 ) -> result::Result<Self, (Self, Junction)> {
443 let new = new.into();
444 Ok(match self {
445 Junctions::Here => Junctions::X1(new),
446 Junctions::X1(a) => Junctions::X2(new, a),
447 Junctions::X2(a, b) => Junctions::X3(new, a, b),
448 Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
449 Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d),
450 Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e),
451 Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f),
452 Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g),
453 s => Err((s, new))?,
454 })
455 }
456
457 pub fn append_with(&mut self, suffix: impl Into<Junctions>) -> Result<(), Junctions> {
469 let suffix = suffix.into();
470 if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS {
471 return Err(suffix)
472 }
473 for j in suffix.into_iter() {
474 self.push(j).expect("Already checked the sum of the len()s; qed")
475 }
476 Ok(())
477 }
478
479 pub const fn len(&self) -> usize {
481 match &self {
482 Junctions::Here => 0,
483 Junctions::X1(..) => 1,
484 Junctions::X2(..) => 2,
485 Junctions::X3(..) => 3,
486 Junctions::X4(..) => 4,
487 Junctions::X5(..) => 5,
488 Junctions::X6(..) => 6,
489 Junctions::X7(..) => 7,
490 Junctions::X8(..) => 8,
491 }
492 }
493
494 pub fn at(&self, i: usize) -> Option<&Junction> {
497 Some(match (i, self) {
498 (0, Junctions::X1(ref a)) => a,
499 (0, Junctions::X2(ref a, ..)) => a,
500 (0, Junctions::X3(ref a, ..)) => a,
501 (0, Junctions::X4(ref a, ..)) => a,
502 (0, Junctions::X5(ref a, ..)) => a,
503 (0, Junctions::X6(ref a, ..)) => a,
504 (0, Junctions::X7(ref a, ..)) => a,
505 (0, Junctions::X8(ref a, ..)) => a,
506 (1, Junctions::X2(_, ref a)) => a,
507 (1, Junctions::X3(_, ref a, ..)) => a,
508 (1, Junctions::X4(_, ref a, ..)) => a,
509 (1, Junctions::X5(_, ref a, ..)) => a,
510 (1, Junctions::X6(_, ref a, ..)) => a,
511 (1, Junctions::X7(_, ref a, ..)) => a,
512 (1, Junctions::X8(_, ref a, ..)) => a,
513 (2, Junctions::X3(_, _, ref a)) => a,
514 (2, Junctions::X4(_, _, ref a, ..)) => a,
515 (2, Junctions::X5(_, _, ref a, ..)) => a,
516 (2, Junctions::X6(_, _, ref a, ..)) => a,
517 (2, Junctions::X7(_, _, ref a, ..)) => a,
518 (2, Junctions::X8(_, _, ref a, ..)) => a,
519 (3, Junctions::X4(_, _, _, ref a)) => a,
520 (3, Junctions::X5(_, _, _, ref a, ..)) => a,
521 (3, Junctions::X6(_, _, _, ref a, ..)) => a,
522 (3, Junctions::X7(_, _, _, ref a, ..)) => a,
523 (3, Junctions::X8(_, _, _, ref a, ..)) => a,
524 (4, Junctions::X5(_, _, _, _, ref a)) => a,
525 (4, Junctions::X6(_, _, _, _, ref a, ..)) => a,
526 (4, Junctions::X7(_, _, _, _, ref a, ..)) => a,
527 (4, Junctions::X8(_, _, _, _, ref a, ..)) => a,
528 (5, Junctions::X6(_, _, _, _, _, ref a)) => a,
529 (5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a,
530 (5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a,
531 (6, Junctions::X7(_, _, _, _, _, _, ref a)) => a,
532 (6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a,
533 (7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a,
534 _ => return None,
535 })
536 }
537
538 pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
541 Some(match (i, self) {
542 (0, Junctions::X1(ref mut a)) => a,
543 (0, Junctions::X2(ref mut a, ..)) => a,
544 (0, Junctions::X3(ref mut a, ..)) => a,
545 (0, Junctions::X4(ref mut a, ..)) => a,
546 (0, Junctions::X5(ref mut a, ..)) => a,
547 (0, Junctions::X6(ref mut a, ..)) => a,
548 (0, Junctions::X7(ref mut a, ..)) => a,
549 (0, Junctions::X8(ref mut a, ..)) => a,
550 (1, Junctions::X2(_, ref mut a)) => a,
551 (1, Junctions::X3(_, ref mut a, ..)) => a,
552 (1, Junctions::X4(_, ref mut a, ..)) => a,
553 (1, Junctions::X5(_, ref mut a, ..)) => a,
554 (1, Junctions::X6(_, ref mut a, ..)) => a,
555 (1, Junctions::X7(_, ref mut a, ..)) => a,
556 (1, Junctions::X8(_, ref mut a, ..)) => a,
557 (2, Junctions::X3(_, _, ref mut a)) => a,
558 (2, Junctions::X4(_, _, ref mut a, ..)) => a,
559 (2, Junctions::X5(_, _, ref mut a, ..)) => a,
560 (2, Junctions::X6(_, _, ref mut a, ..)) => a,
561 (2, Junctions::X7(_, _, ref mut a, ..)) => a,
562 (2, Junctions::X8(_, _, ref mut a, ..)) => a,
563 (3, Junctions::X4(_, _, _, ref mut a)) => a,
564 (3, Junctions::X5(_, _, _, ref mut a, ..)) => a,
565 (3, Junctions::X6(_, _, _, ref mut a, ..)) => a,
566 (3, Junctions::X7(_, _, _, ref mut a, ..)) => a,
567 (3, Junctions::X8(_, _, _, ref mut a, ..)) => a,
568 (4, Junctions::X5(_, _, _, _, ref mut a)) => a,
569 (4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a,
570 (4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a,
571 (4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a,
572 (5, Junctions::X6(_, _, _, _, _, ref mut a)) => a,
573 (5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a,
574 (5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a,
575 (6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a,
576 (6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
577 (7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a,
578 _ => return None,
579 })
580 }
581
582 pub fn iter(&self) -> JunctionsRefIterator {
584 JunctionsRefIterator { junctions: self, next: 0, back: 0 }
585 }
586
587 pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
598 if prefix.len() + 1 != self.len() {
599 return None
600 }
601 for i in 0..prefix.len() {
602 if prefix.at(i) != self.at(i) {
603 return None
604 }
605 }
606 return self.at(prefix.len())
607 }
608
609 pub fn starts_with(&self, prefix: &Junctions) -> bool {
610 prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y)
611 }
612}
613
614impl TryFrom<MultiLocation> for Junctions {
615 type Error = MultiLocation;
616 fn try_from(x: MultiLocation) -> result::Result<Self, MultiLocation> {
617 if x.parents > 0 {
618 Err(x)
619 } else {
620 Ok(x.interior)
621 }
622 }
623}
624
625impl<T: Into<Junction>> From<T> for Junctions {
626 fn from(x: T) -> Self {
627 Self::X1(x.into())
628 }
629}
630
631impl From<[Junction; 0]> for Junctions {
632 fn from(_: [Junction; 0]) -> Self {
633 Self::Here
634 }
635}
636
637impl From<()> for Junctions {
638 fn from(_: ()) -> Self {
639 Self::Here
640 }
641}
642
643xcm_procedural::impl_conversion_functions_for_junctions_v3!();
644
645#[cfg(test)]
646mod tests {
647 use super::{super::prelude::*, *};
648
649 #[test]
650 fn inverting_works() {
651 let context: InteriorMultiLocation = (Parachain(1000), PalletInstance(42)).into();
652 let target = (Parent, PalletInstance(69)).into();
653 let expected = (Parent, PalletInstance(42)).into();
654 let inverted = context.invert_target(&target).unwrap();
655 assert_eq!(inverted, expected);
656
657 let context: InteriorMultiLocation =
658 (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into();
659 let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into();
660 let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into();
661 let inverted = context.invert_target(&target).unwrap();
662 assert_eq!(inverted, expected);
663 }
664
665 #[test]
666 fn relative_to_works() {
667 use Junctions::*;
668 use NetworkId::*;
669 assert_eq!(X1(Polkadot.into()).relative_to(&X1(Kusama.into())), (Parent, Polkadot).into());
670 let base = X3(Kusama.into(), Parachain(1), PalletInstance(1));
671
672 assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into());
674 assert_eq!(X1(Kusama.into()).relative_to(&base), (Parent, Parent).into());
675 assert_eq!(X2(Kusama.into(), Parachain(1)).relative_to(&base), (Parent,).into());
676 assert_eq!(
677 X3(Kusama.into(), Parachain(1), PalletInstance(1)).relative_to(&base),
678 Here.into()
679 );
680
681 assert_eq!(
683 X1(Polkadot.into()).relative_to(&base),
684 (Parent, Parent, Parent, Polkadot).into()
685 );
686 assert_eq!(
687 X2(Kusama.into(), Parachain(2)).relative_to(&base),
688 (Parent, Parent, Parachain(2)).into()
689 );
690 assert_eq!(
691 X3(Kusama.into(), Parachain(1), PalletInstance(2)).relative_to(&base),
692 (Parent, PalletInstance(2)).into()
693 );
694 assert_eq!(
695 X4(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()).relative_to(&base),
696 ([1u8; 32],).into()
697 );
698
699 assert_eq!(
701 X2(Polkadot.into(), Parachain(1)).relative_to(&base),
702 (Parent, Parent, Parent, Polkadot, Parachain(1)).into()
703 );
704 assert_eq!(
705 X3(Kusama.into(), Parachain(2), PalletInstance(1)).relative_to(&base),
706 (Parent, Parent, Parachain(2), PalletInstance(1)).into()
707 );
708 assert_eq!(
709 X4(Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()).relative_to(&base),
710 (Parent, PalletInstance(2), [1u8; 32]).into()
711 );
712 assert_eq!(
713 X5(Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into(), 1u128.into())
714 .relative_to(&base),
715 ([1u8; 32], 1u128).into()
716 );
717 }
718
719 #[test]
720 fn global_consensus_works() {
721 use Junctions::*;
722 use NetworkId::*;
723 assert_eq!(X1(Polkadot.into()).global_consensus(), Ok(Polkadot));
724 assert_eq!(X2(Kusama.into(), 1u64.into()).global_consensus(), Ok(Kusama));
725 assert_eq!(Here.global_consensus(), Err(()));
726 assert_eq!(X1(1u64.into()).global_consensus(), Err(()));
727 assert_eq!(X2(1u64.into(), Kusama.into()).global_consensus(), Err(()));
728 }
729
730 #[test]
731 fn test_conversion() {
732 use super::{Junction::*, Junctions::*, NetworkId::*};
733 let x: Junctions = GlobalConsensus(Polkadot).into();
734 assert_eq!(x, X1(GlobalConsensus(Polkadot)));
735 let x: Junctions = Polkadot.into();
736 assert_eq!(x, X1(GlobalConsensus(Polkadot)));
737 let x: Junctions = (Polkadot, Kusama).into();
738 assert_eq!(x, X2(GlobalConsensus(Polkadot), GlobalConsensus(Kusama)));
739 }
740}