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
mod pallet_xcm_benchmarks_fungible;
18
mod pallet_xcm_benchmarks_generic;
19

            
20
use {
21
    crate::Runtime,
22
    frame_support::weights::Weight,
23
    pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight,
24
    pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric,
25
    sp_std::prelude::*,
26
    xcm::{
27
        latest::{prelude::*, Weight as XCMWeight},
28
        DoubleEncoded,
29
    },
30
};
31

            
32
const MAX_ASSETS: u64 = 1;
33

            
34
pub enum AssetTypes {
35
    Balances,
36
    Unknown,
37
}
38

            
39
impl From<&Asset> for AssetTypes {
40
1
    fn from(asset: &Asset) -> Self {
41
1
        match asset {
42
            Asset {
43
                id:
44
                    AssetId(Location {
45
                        parents: 0,
46
                        interior: Here,
47
                    }),
48
                ..
49
1
            } => AssetTypes::Balances,
50
            _ => AssetTypes::Unknown,
51
        }
52
1
    }
53
}
54

            
55
trait WeighAssets {
56
    fn weigh_assets(&self, balances_weight: Weight) -> Weight;
57
}
58

            
59
impl WeighAssets for AssetFilter {
60
    fn weigh_assets(&self, balances_weight: Weight) -> Weight {
61
        match self {
62
            Self::Definite(assets) => assets
63
                .inner()
64
                .into_iter()
65
                .map(From::from)
66
                .map(|t| match t {
67
                    AssetTypes::Balances => balances_weight,
68
                    AssetTypes::Unknown => Weight::MAX,
69
                })
70
                .fold(Weight::zero(), |acc, x| acc.saturating_add(x)),
71
            Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight,
72
            Self::Wild(AllCounted(count)) => {
73
                balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64))
74
            }
75
            Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS),
76
        }
77
    }
78
}
79

            
80
impl WeighAssets for Assets {
81
1
    fn weigh_assets(&self, balances_weight: Weight) -> Weight {
82
1
        self.inner()
83
1
            .into_iter()
84
1
            .map(|m| <AssetTypes as From<&Asset>>::from(m))
85
1
            .map(|t| match t {
86
1
                AssetTypes::Balances => balances_weight,
87
                AssetTypes::Unknown => Weight::MAX,
88
1
            })
89
1
            .fold(Weight::zero(), |acc, x| acc.saturating_add(x))
90
1
    }
91
}
92

            
93
// For now we are returning benchmarked weights only for generic XCM instructions.
94
// Fungible XCM instructions will return a fixed weight value of
95
// 200_000_000 ref_time and its proper PoV weight taken from statemint benchmarks.
96
//
97
// TODO: add the fungible benchmarked values once these are calculated.
98
pub struct XcmWeight<RuntimeCall>(core::marker::PhantomData<RuntimeCall>);
99
impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for XcmWeight<RuntimeCall>
100
where
101
    Runtime: frame_system::Config,
102
{
103
    fn withdraw_asset(assets: &Assets) -> XCMWeight {
104
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::withdraw_asset())
105
    }
106
    fn reserve_asset_deposited(assets: &Assets) -> XCMWeight {
107
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::reserve_asset_deposited())
108
    }
109
    fn receive_teleported_asset(assets: &Assets) -> XCMWeight {
110
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::receive_teleported_asset())
111
    }
112
    fn query_response(
113
        _query_id: &u64,
114
        _response: &Response,
115
        _max_weight: &Weight,
116
        _querier: &Option<Location>,
117
    ) -> XCMWeight {
118
        XcmGeneric::<Runtime>::query_response()
119
    }
120
1
    fn transfer_asset(assets: &Assets, _dest: &Location) -> XCMWeight {
121
1
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::transfer_asset())
122
1
    }
123
    fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
124
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::transfer_reserve_asset())
125
    }
126
    fn transact(
127
        _origin_type: &OriginKind,
128
        _require_weight_at_most: &Weight,
129
        _call: &DoubleEncoded<RuntimeCall>,
130
    ) -> XCMWeight {
131
        XcmGeneric::<Runtime>::transact()
132
    }
133
    fn hrmp_new_channel_open_request(
134
        _sender: &u32,
135
        _max_message_size: &u32,
136
        _max_capacity: &u32,
137
    ) -> XCMWeight {
138
        // XCM Executor does not currently support HRMP channel operations
139
        Weight::MAX
140
    }
141
    fn hrmp_channel_accepted(_recipient: &u32) -> XCMWeight {
142
        // XCM Executor does not currently support HRMP channel operations
143
        Weight::MAX
144
    }
145
    fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> XCMWeight {
146
        // XCM Executor does not currently support HRMP channel operations
147
        Weight::MAX
148
    }
149
    fn clear_origin() -> XCMWeight {
150
        XcmGeneric::<Runtime>::clear_origin()
151
    }
152
    fn descend_origin(_who: &InteriorLocation) -> XCMWeight {
153
        XcmGeneric::<Runtime>::descend_origin()
154
    }
155
    fn report_error(_query_response_info: &QueryResponseInfo) -> XCMWeight {
156
        XcmGeneric::<Runtime>::report_error()
157
    }
158
    fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> XCMWeight {
159
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::deposit_asset())
160
    }
161
    fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
162
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::deposit_reserve_asset())
163
    }
164
    fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> XCMWeight {
165
        Weight::MAX
166
    }
167
    fn initiate_reserve_withdraw(
168
        assets: &AssetFilter,
169
        _reserve: &Location,
170
        _xcm: &Xcm<()>,
171
    ) -> XCMWeight {
172
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::initiate_reserve_withdraw())
173
    }
174
    fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
175
        assets.weigh_assets(XcmBalancesWeight::<Runtime>::initiate_teleport())
176
    }
177
    fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight {
178
        XcmGeneric::<Runtime>::report_holding()
179
    }
180
    fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> XCMWeight {
181
        XcmGeneric::<Runtime>::buy_execution()
182
    }
183
    fn refund_surplus() -> XCMWeight {
184
        XcmGeneric::<Runtime>::refund_surplus()
185
    }
186
    fn set_error_handler(_xcm: &Xcm<RuntimeCall>) -> XCMWeight {
187
        XcmGeneric::<Runtime>::set_error_handler()
188
    }
189
    fn set_appendix(_xcm: &Xcm<RuntimeCall>) -> XCMWeight {
190
        XcmGeneric::<Runtime>::set_appendix()
191
    }
192
    fn clear_error() -> XCMWeight {
193
        XcmGeneric::<Runtime>::clear_error()
194
    }
195
    fn claim_asset(_assets: &Assets, _ticket: &Location) -> XCMWeight {
196
        XcmGeneric::<Runtime>::claim_asset()
197
    }
198
    fn trap(_code: &u64) -> XCMWeight {
199
        XcmGeneric::<Runtime>::trap()
200
    }
201
    fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> XCMWeight {
202
        XcmGeneric::<Runtime>::subscribe_version()
203
    }
204
    fn unsubscribe_version() -> XCMWeight {
205
        XcmGeneric::<Runtime>::unsubscribe_version()
206
    }
207
    fn burn_asset(assets: &Assets) -> Weight {
208
        assets.weigh_assets(XcmGeneric::<Runtime>::burn_asset())
209
    }
210
    fn expect_asset(assets: &Assets) -> Weight {
211
        assets.weigh_assets(XcmGeneric::<Runtime>::expect_asset())
212
    }
213
    fn expect_origin(_origin: &Option<Location>) -> Weight {
214
        XcmGeneric::<Runtime>::expect_origin()
215
    }
216
    fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
217
        XcmGeneric::<Runtime>::expect_error()
218
    }
219
    fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
220
        XcmGeneric::<Runtime>::expect_transact_status()
221
    }
222
    fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
223
        XcmGeneric::<Runtime>::query_pallet()
224
    }
225
    fn expect_pallet(
226
        _index: &u32,
227
        _name: &Vec<u8>,
228
        _module_name: &Vec<u8>,
229
        _crate_major: &u32,
230
        _min_crate_minor: &u32,
231
    ) -> Weight {
232
        XcmGeneric::<Runtime>::expect_pallet()
233
    }
234
    fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight {
235
        XcmGeneric::<Runtime>::report_transact_status()
236
    }
237
    fn clear_transact_status() -> Weight {
238
        XcmGeneric::<Runtime>::clear_transact_status()
239
    }
240
    fn universal_origin(_: &Junction) -> Weight {
241
        Weight::MAX
242
    }
243
1
    fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight {
244
1
        Weight::MAX
245
1
    }
246
    fn lock_asset(_: &Asset, _: &Location) -> Weight {
247
        Weight::MAX
248
    }
249
    fn unlock_asset(_: &Asset, _: &Location) -> Weight {
250
        Weight::MAX
251
    }
252
    fn note_unlockable(_: &Asset, _: &Location) -> Weight {
253
        Weight::MAX
254
    }
255
    fn request_unlock(_: &Asset, _: &Location) -> Weight {
256
        Weight::MAX
257
    }
258
    fn set_fees_mode(_: &bool) -> Weight {
259
        XcmGeneric::<Runtime>::set_fees_mode()
260
    }
261
    fn set_topic(_topic: &[u8; 32]) -> Weight {
262
        XcmGeneric::<Runtime>::set_topic()
263
    }
264
    fn clear_topic() -> Weight {
265
        XcmGeneric::<Runtime>::clear_topic()
266
    }
267
    fn alias_origin(_: &Location) -> Weight {
268
        // XCM Executor does not currently support alias origin operations
269
        Weight::MAX
270
    }
271
    fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
272
        XcmGeneric::<Runtime>::unpaid_execution()
273
    }
274
}