1
// Copyright 2019-2022 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
//! The XCM primitive trait implementations
18

            
19
#![cfg_attr(not(feature = "std"), no_std)]
20

            
21
mod asset_id_conversions;
22
pub use asset_id_conversions::*;
23

            
24
mod constants;
25
pub use constants::*;
26

            
27
pub mod get_by_key;
28
pub use get_by_key::*;
29

            
30
mod ethereum_xcm;
31
pub use ethereum_xcm::*;
32

            
33
mod filter_asset_max_fee;
34
pub use filter_asset_max_fee::*;
35

            
36
mod origin_conversion;
37
pub use origin_conversion::*;
38

            
39
mod transactor_traits;
40
pub use transactor_traits::*;
41

            
42
use xcm::latest::{Junction, Junctions, Location};
43

            
44
3060
pub fn split_location_into_chain_part_and_beneficiary(
45
3060
	mut location: Location,
46
3060
) -> Option<(Location, Location)> {
47
3060
	let mut beneficiary_junctions = Junctions::Here;
48

            
49
	// start popping junctions until we reach chain identifier
50
6120
	while let Some(j) = location.last() {
51
4658
		if matches!(j, Junction::Parachain(_) | Junction::GlobalConsensus(_)) {
52
			// return chain subsection
53
1598
			return Some((location, beneficiary_junctions.into_location()));
54
		} else {
55
3060
			let (location_prefix, maybe_last_junction) = location.split_last_interior();
56
3060
			location = location_prefix;
57
3060
			if let Some(junction) = maybe_last_junction {
58
3060
				beneficiary_junctions.push(junction).ok()?;
59
			}
60
		}
61
	}
62

            
63
1462
	if location.parent_count() == 1 {
64
1462
		Some((Location::parent(), beneficiary_junctions.into_location()))
65
	} else {
66
		None
67
	}
68
3060
}