-
Notifications
You must be signed in to change notification settings - Fork 47
/
xcm_config.rs
162 lines (145 loc) · 5.35 KB
/
xcm_config.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// KILT Blockchain – https://botlabs.org
// Copyright (C) 2019-2024 BOTLabs GmbH
// The KILT Blockchain is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The KILT Blockchain is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// If you feel like getting in touch with us, you can do so at info@botlabs.org
use core::{marker::PhantomData, ops::ControlFlow};
use frame_support::{match_types, parameter_types, traits::ProcessMessageError, weights::Weight};
use polkadot_parachain::primitives::Sibling;
use xcm::v3::prelude::*;
use xcm_builder::{AccountId32Aliases, CurrencyAdapter, IsConcrete, ParentIsPreset, SiblingParachainConvertsVia};
use xcm_executor::traits::{Properties, ShouldExecute};
use crate::AccountId;
parameter_types! {
// One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer.
pub UnitWeightCost: Weight = Weight::from_parts(200_000_000, 0);
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
}
match_types! {
pub type ParentLocation: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here}
};
pub type ParentOrSiblings: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here } |
MultiLocation { parents: 1, interior: X1(_) }
};
}
// Note: This might move to polkadot's xcm module.
/// Deny executing the xcm message if it matches any of the Deny filter
/// regardless of anything else. If it passes the Deny and matches one of the
/// Allow cases, then it is let through.
pub struct DenyThenTry<Deny, Allow>(PhantomData<(Deny, Allow)>);
impl<Deny, Allow> ShouldExecute for DenyThenTry<Deny, Allow>
where
Deny: ShouldExecute,
Allow: ShouldExecute,
{
fn should_execute<Call>(
origin: &MultiLocation,
instructions: &mut [Instruction<Call>],
max_weight: Weight,
properties: &mut Properties,
) -> Result<(), ProcessMessageError> {
Deny::should_execute(origin, instructions, max_weight, properties)?;
Allow::should_execute(origin, instructions, max_weight, properties)
}
}
/// Reserved funds to the relay chain can't return. See <https://github.com/paritytech/polkadot/issues/5233>
/// Usage of the new xcm matcher. See <https://github.com/paritytech/polkadot/pull/7098>
pub struct DenyReserveTransferToRelayChain;
impl ShouldExecute for DenyReserveTransferToRelayChain {
fn should_execute<RuntimeCall>(
origin: &MultiLocation,
message: &mut [Instruction<RuntimeCall>],
_max_weight: Weight,
_properties: &mut Properties,
) -> Result<(), ProcessMessageError> {
xcm_builder::MatchXcm::match_next_inst_while(
xcm_builder::CreateMatcher::matcher(message),
|_| true,
|inst| match inst {
InitiateReserveWithdraw {
reserve: MultiLocation {
parents: 1,
interior: Here,
},
..
}
| DepositReserveAsset {
dest: MultiLocation {
parents: 1,
interior: Here,
},
..
}
| TransferReserveAsset {
dest: MultiLocation {
parents: 1,
interior: Here,
},
..
} => {
Err(ProcessMessageError::Unsupported) // Deny
}
// An unexpected reserve transfer has arrived from the Relay Chain. Generally,
// `IsReserve` should not allow this, but we just log it here.
ReserveAssetDeposited { .. }
if matches!(
origin,
MultiLocation {
parents: 1,
interior: Here
}
) =>
{
log::warn!(
target: "xcm::barrier",
"Unexpected ReserveAssetDeposited from the Relay Chain",
);
Ok(ControlFlow::Continue(()))
}
_ => Ok(ControlFlow::Continue(())),
},
)?;
// Permit everything else
Ok(())
}
}
parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
pub const HereLocation: MultiLocation = MultiLocation::here();
}
/// Type for specifying how a `MultiLocation` can be converted into an
/// `AccountId`. This is used when determining ownership of accounts for asset
/// transacting and when attempting to use XCM `Transact` in order to determine
/// the dispatch Origin.
pub type LocationToAccountId<NetworkId> = (
// The parent (Relay-chain) origin converts to the b"parent" `AccountId`.
ParentIsPreset<AccountId>,
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<NetworkId, AccountId>,
);
/// Means for transacting assets on this chain.
pub type LocalAssetTransactor<Currency, NetworkId> = CurrencyAdapter<
// Use this currency:
Currency,
// Use this currency when it is a fungible asset matching the given location or name:
IsConcrete<HereLocation>,
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
LocationToAccountId<NetworkId>,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
// We don't track any teleports.
(),
>;