weight.rs 3.5 KB
Newer Older
Gavin Wood's avatar
Gavin Wood committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot 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.

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

use sp_std::result::Result;
18
use xcm::v0::{Xcm, MultiAsset, MultiLocation, Error};
Gavin Wood's avatar
Gavin Wood committed
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
use frame_support::weights::Weight;
use crate::Assets;

/// Determine the weight of an XCM message.
pub trait WeightBounds<Call> {
	/// Return the minimum amount of weight that an attempted execution of this message would definitely
	/// consume.
	///
	/// This is useful to gauge how many fees should be paid up front to begin execution of the message.
	/// It is not useful for determining whether execution should begin lest it result in surpassing weight
	/// limits - in that case `deep` is the function to use.
	fn shallow(message: &mut Xcm<Call>) -> Result<Weight, ()>;

	/// Return the deep amount of weight, over `shallow` that complete, successful and worst-case execution of
	/// `message` would incur.
	///
	/// This is perhaps overly pessimistic for determining how many fees should be paid for up-front since
	/// fee payment (or any other way of offsetting the execution costs such as an voucher-style NFT) may
	/// happen in stages throughout execution of the XCM.
	///
	/// A reminder: if it is possible that `message` may have alternative means of successful completion
	/// (perhaps a conditional path), then the *worst case* weight must be reported.
	///
	/// This is guaranteed equal to the eventual sum of all `shallow` XCM messages that get executed through
	/// any internal effects. Inner XCM messages may be executed by:
Denis_P's avatar
Denis_P committed
44
	/// - `Order::BuyExecution`
Gavin Wood's avatar
Gavin Wood committed
45
	fn deep(message: &mut Xcm<Call>) -> Result<Weight, ()>;
46
47
48
49
50
51
52
53
54
55
56
57

	/// Return the total weight for executing `message`.
	fn weight(message: &mut Xcm<Call>) -> Result<Weight, ()> {
		Self::shallow(message)?.checked_add(Self::deep(message)?).ok_or(())
	}
}

/// A means of getting approximate weight consumption for a given destination message executor and a
/// message.
pub trait UniversalWeigher {
	/// Get the upper limit of weight required for `dest` to execute `message`.
	fn weigh(dest: MultiLocation, message: Xcm<()>) -> Result<Weight, ()>;
Gavin Wood's avatar
Gavin Wood committed
58
59
60
}

/// Charge for weight in order to execute XCM.
61
pub trait WeightTrader: Sized {
Gavin Wood's avatar
Gavin Wood committed
62
63
64
65
66
67
	/// Create a new trader instance.
	fn new() -> Self;

	/// Purchase execution weight credit in return for up to a given `fee`. If less of the fee is required
	/// then the surplus is returned. If the `fee` cannot be used to pay for the `weight`, then an error is
	/// returned.
68
	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error>;
Gavin Wood's avatar
Gavin Wood committed
69
70
71
72
73
74
75

	/// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was
	/// purchased using `buy_weight`.
	///
	/// Default implementation refunds nothing.
	fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None }
}
76
77
78
79
80
81
82

impl WeightTrader for () {
	fn new() -> Self { () }
	fn buy_weight(&mut self, _: Weight, _: Assets) -> Result<Assets, Error> {
		Err(Error::Unimplemented)
	}
}