1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

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

            
17
#![cfg_attr(not(feature = "std"), no_std)]
18

            
19
use xcm::latest::prelude::*;
20
trait Parse {
21
    /// Returns the "chain" location part. It could be parent, sibling
22
    /// parachain, or child parachain.
23
    fn chain_part(&self) -> Option<Location>;
24
}
25

            
26
impl Parse for Location {
27
432
    fn chain_part(&self) -> Option<Location> {
28
432
        match (self.parents, self.first_interior()) {
29
            // sibling parachain
30
120
            (1, Some(Parachain(id))) => Some(Location::new(1, [Parachain(*id)])),
31
            // parent
32
300
            (1, _) => Some(Location::parent()),
33
            // children parachain
34
            (0, Some(Parachain(id))) => Some(Location::new(0, [Parachain(*id)])),
35
12
            _ => None,
36
        }
37
432
    }
38
}
39

            
40
pub struct NativeAssetReserve;
41
impl frame_support::traits::ContainsPair<Asset, Location> for NativeAssetReserve {
42
648
    fn contains(asset: &Asset, origin: &Location) -> bool {
43
648
        log::trace!(target: "xcm::contains", "NativeAssetReserve asset: {:?}, origin: {:?}", asset, origin);
44
648
        let reserve = if asset.id.0.parents == 0
45
216
            && !matches!(asset.id.0.first_interior(), Some(Parachain(_)))
46
        {
47
216
            Some(Location::here())
48
        } else {
49
432
            asset.id.0.chain_part()
50
        };
51

            
52
648
        if let Some(ref reserve) = reserve {
53
636
            if reserve == origin {
54
384
                return true;
55
252
            }
56
12
        }
57
264
        false
58
648
    }
59
}