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

            
20
use {
21
    crate::Runtime,
22
    frame_support::{weights::Weight, BoundedVec},
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::*, AssetTransferFilter, Weight as XCMWeight},
28
        DoubleEncoded,
29
    },
30
};
31

            
32
const MAX_ASSETS: u64 = 1;
33

            
34
trait WeighAssets {
35
    fn weigh_multi_assets(&self, weight: Weight) -> XCMWeight;
36
}
37

            
38
impl WeighAssets for AssetFilter {
39
168
    fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight {
40
168
        match self {
41
            Self::Definite(assets) => assets.weigh_multi_assets(balances_weight),
42
            Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight,
43
132
            Self::Wild(AllCounted(count)) => {
44
132
                balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64))
45
            }
46
36
            Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS),
47
        }
48
168
    }
49
}
50

            
51
impl WeighAssets for Assets {
52
309
    fn weigh_multi_assets(&self, weight: Weight) -> XCMWeight {
53
309
        weight.saturating_mul(self.inner().iter().count() as u64)
54
309
    }
55
}
56

            
57
// For now we are returning benchmarked weights only for generic XCM instructions.
58
// Fungible XCM instructions will return a fixed weight value of
59
// 200_000_000 ref_time and its proper PoV weight taken from statemint benchmarks.
60
//
61
// TODO: add the fungible benchmarked values once these are calculated.
62
pub struct XcmWeight<RuntimeCall>(core::marker::PhantomData<RuntimeCall>);
63
impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for XcmWeight<RuntimeCall>
64
where
65
    Runtime: frame_system::Config,
66
{
67
40
    fn withdraw_asset(assets: &Assets) -> XCMWeight {
68
40
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::withdraw_asset())
69
40
    }
70
61
    fn reserve_asset_deposited(assets: &Assets) -> XCMWeight {
71
61
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::reserve_asset_deposited())
72
61
    }
73
6
    fn receive_teleported_asset(_assets: &Assets) -> XCMWeight {
74
6
        XCMWeight::MAX
75
6
    }
76
10
    fn query_response(
77
10
        _query_id: &u64,
78
10
        _response: &Response,
79
10
        _max_weight: &Weight,
80
10
        _querier: &Option<Location>,
81
10
    ) -> XCMWeight {
82
10
        XcmGeneric::<Runtime>::query_response()
83
10
    }
84
44
    fn transfer_asset(assets: &Assets, _dest: &Location) -> XCMWeight {
85
44
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::transfer_asset())
86
44
    }
87
    fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
88
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::transfer_reserve_asset())
89
    }
90
41
    fn transact(
91
41
        _origin_type: &OriginKind,
92
41
        _require_weight_at_most: &Option<Weight>,
93
41
        _call: &DoubleEncoded<RuntimeCall>,
94
41
    ) -> XCMWeight {
95
41
        XcmGeneric::<Runtime>::transact()
96
41
    }
97
    fn hrmp_new_channel_open_request(
98
        _sender: &u32,
99
        _max_message_size: &u32,
100
        _max_capacity: &u32,
101
    ) -> XCMWeight {
102
        // XCM Executor does not currently support HRMP channel operations
103
        Weight::MAX
104
    }
105
    fn hrmp_channel_accepted(_recipient: &u32) -> XCMWeight {
106
        // XCM Executor does not currently support HRMP channel operations
107
        Weight::MAX
108
    }
109
    fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> XCMWeight {
110
        // XCM Executor does not currently support HRMP channel operations
111
        Weight::MAX
112
    }
113
61
    fn clear_origin() -> XCMWeight {
114
61
        XcmGeneric::<Runtime>::clear_origin()
115
61
    }
116
27
    fn descend_origin(_who: &InteriorLocation) -> XCMWeight {
117
27
        XcmGeneric::<Runtime>::descend_origin()
118
27
    }
119
    fn report_error(_query_response_info: &QueryResponseInfo) -> XCMWeight {
120
        XcmGeneric::<Runtime>::report_error()
121
    }
122
94
    fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> XCMWeight {
123
94
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::deposit_asset())
124
94
    }
125
    fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
126
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::deposit_reserve_asset())
127
    }
128
    fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> XCMWeight {
129
        Weight::MAX
130
    }
131
2
    fn initiate_reserve_withdraw(
132
2
        assets: &AssetFilter,
133
2
        _reserve: &Location,
134
2
        _xcm: &Xcm<()>,
135
2
    ) -> XCMWeight {
136
2
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::initiate_reserve_withdraw())
137
2
    }
138
    fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> XCMWeight {
139
        assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::initiate_teleport())
140
    }
141
    fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight {
142
        XcmGeneric::<Runtime>::report_holding()
143
    }
144
103
    fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> XCMWeight {
145
103
        XcmGeneric::<Runtime>::buy_execution()
146
103
    }
147
2
    fn refund_surplus() -> XCMWeight {
148
2
        XcmGeneric::<Runtime>::refund_surplus()
149
2
    }
150
18
    fn set_error_handler(_xcm: &Xcm<RuntimeCall>) -> XCMWeight {
151
18
        XcmGeneric::<Runtime>::set_error_handler()
152
18
    }
153
12
    fn set_appendix(_xcm: &Xcm<RuntimeCall>) -> XCMWeight {
154
12
        XcmGeneric::<Runtime>::set_appendix()
155
12
    }
156
    fn clear_error() -> XCMWeight {
157
        XcmGeneric::<Runtime>::clear_error()
158
    }
159
    fn claim_asset(assets: &Assets, _ticket: &Location) -> XCMWeight {
160
        assets.weigh_multi_assets(XcmGeneric::<Runtime>::claim_asset())
161
    }
162
13
    fn trap(_code: &u64) -> XCMWeight {
163
13
        XcmGeneric::<Runtime>::trap()
164
13
    }
165
    fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> XCMWeight {
166
        XcmGeneric::<Runtime>::subscribe_version()
167
    }
168
    fn unsubscribe_version() -> XCMWeight {
169
        XcmGeneric::<Runtime>::unsubscribe_version()
170
    }
171
2
    fn burn_asset(assets: &Assets) -> Weight {
172
2
        assets.weigh_multi_assets(XcmGeneric::<Runtime>::burn_asset())
173
2
    }
174
    fn expect_asset(assets: &Assets) -> Weight {
175
        assets.weigh_multi_assets(XcmGeneric::<Runtime>::expect_asset())
176
    }
177
    fn expect_origin(_origin: &Option<Location>) -> Weight {
178
        XcmGeneric::<Runtime>::expect_origin()
179
    }
180
    fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
181
        XcmGeneric::<Runtime>::expect_error()
182
    }
183
    fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
184
        XcmGeneric::<Runtime>::expect_transact_status()
185
    }
186
    fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
187
        XcmGeneric::<Runtime>::query_pallet()
188
    }
189
    fn expect_pallet(
190
        _index: &u32,
191
        _name: &Vec<u8>,
192
        _module_name: &Vec<u8>,
193
        _crate_major: &u32,
194
        _min_crate_minor: &u32,
195
    ) -> Weight {
196
        XcmGeneric::<Runtime>::expect_pallet()
197
    }
198
    fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight {
199
        XcmGeneric::<Runtime>::report_transact_status()
200
    }
201
    fn clear_transact_status() -> Weight {
202
        XcmGeneric::<Runtime>::clear_transact_status()
203
    }
204
    fn universal_origin(_: &Junction) -> Weight {
205
        Weight::MAX
206
    }
207
    fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight {
208
        Weight::MAX
209
    }
210
    fn lock_asset(_: &Asset, _: &Location) -> Weight {
211
        Weight::MAX
212
    }
213
    fn unlock_asset(_: &Asset, _: &Location) -> Weight {
214
        Weight::MAX
215
    }
216
    fn note_unlockable(_: &Asset, _: &Location) -> Weight {
217
        Weight::MAX
218
    }
219
    fn request_unlock(_: &Asset, _: &Location) -> Weight {
220
        Weight::MAX
221
    }
222
2
    fn set_fees_mode(_: &bool) -> Weight {
223
2
        XcmGeneric::<Runtime>::set_fees_mode()
224
2
    }
225
24
    fn set_topic(_topic: &[u8; 32]) -> Weight {
226
24
        XcmGeneric::<Runtime>::set_topic()
227
24
    }
228
    fn clear_topic() -> Weight {
229
        XcmGeneric::<Runtime>::clear_topic()
230
    }
231
    fn alias_origin(_: &Location) -> Weight {
232
        // XCM Executor does not currently support alias origin operations
233
        Weight::MAX
234
    }
235
1
    fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
236
1
        XcmGeneric::<Runtime>::unpaid_execution()
237
1
    }
238

            
239
    fn pay_fees(_: &Asset) -> Weight {
240
        XcmGeneric::<Runtime>::pay_fees()
241
    }
242

            
243
    fn initiate_transfer(
244
        _dest: &Location,
245
        remote_fees: &Option<AssetTransferFilter>,
246
        _preserve_origin: &bool,
247
        assets: &Vec<AssetTransferFilter>,
248
        _xcm: &Xcm<()>,
249
    ) -> Weight {
250
        let mut weight = if let Some(remote_fees) = remote_fees {
251
            let fees = remote_fees.inner();
252
            fees.weigh_multi_assets(XcmBalancesWeight::<Runtime>::initiate_transfer())
253
        } else {
254
            Weight::zero()
255
        };
256
        for asset_filter in assets {
257
            let assets = asset_filter.inner();
258
            let extra =
259
                assets.weigh_multi_assets(XcmBalancesWeight::<Runtime>::initiate_transfer());
260
            weight = weight.saturating_add(extra);
261
        }
262
        weight
263
    }
264

            
265
    fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<RuntimeCall>) -> Weight {
266
        XcmGeneric::<Runtime>::execute_with_origin()
267
    }
268

            
269
    fn set_hints(hints: &BoundedVec<Hint, HintNumVariants>) -> Weight {
270
        let mut weight = Weight::zero();
271
        for hint in hints {
272
            match hint {
273
                AssetClaimer { .. } => {
274
                    weight = weight.saturating_add(XcmGeneric::<Runtime>::asset_claimer());
275
                }
276
            }
277
        }
278
        weight
279
    }
280
}