referrerpolicy=no-referrer-when-downgrade

staging_xcm_builder/
controller.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot 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// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! A set of traits that define how a pallet interface with XCM.
18//! Controller traits defined in this module are high-level traits that will rely on other traits
19//! from `xcm-executor` to perform their tasks.
20
21use alloc::boxed::Box;
22use frame_support::{
23	dispatch::{DispatchErrorWithPostInfo, WithPostDispatchInfo},
24	pallet_prelude::DispatchError,
25};
26use xcm::prelude::*;
27pub use xcm_executor::traits::QueryHandler;
28
29/// Umbrella trait for all Controller traits.
30pub trait Controller<Origin, RuntimeCall, Timeout>:
31	ExecuteController<Origin, RuntimeCall> + SendController<Origin> + QueryController<Origin, Timeout>
32{
33}
34
35impl<T, Origin, RuntimeCall, Timeout> Controller<Origin, RuntimeCall, Timeout> for T where
36	T: ExecuteController<Origin, RuntimeCall>
37		+ SendController<Origin>
38		+ QueryController<Origin, Timeout>
39{
40}
41
42/// Weight functions needed for [`ExecuteController`].
43pub trait ExecuteControllerWeightInfo {
44	/// Weight for [`ExecuteController::execute`]
45	fn execute() -> Weight;
46}
47
48/// Execute an XCM locally, for a given origin.
49///
50/// An implementation of that trait will handle the low-level details of the execution, such as:
51/// - Validating and Converting the origin to a Location.
52/// - Handling versioning.
53/// - Calling  the internal executor, which implements [`ExecuteXcm`].
54pub trait ExecuteController<Origin, RuntimeCall> {
55	/// Weight information for ExecuteController functions.
56	type WeightInfo: ExecuteControllerWeightInfo;
57
58	/// Attempt to execute an XCM locally, returns Ok with the weight consumed if the execution
59	/// complete successfully, Err otherwise.
60	///
61	/// # Parameters
62	///
63	/// - `origin`: the origin of the call.
64	/// - `message`: the XCM program to be executed.
65	/// - `max_weight`: the maximum weight that can be consumed by the execution.
66	fn execute(
67		origin: Origin,
68		message: Box<VersionedXcm<RuntimeCall>>,
69		max_weight: Weight,
70	) -> Result<Weight, DispatchErrorWithPostInfo>;
71}
72
73/// Weight functions needed for [`SendController`].
74pub trait SendControllerWeightInfo {
75	/// Weight for [`SendController::send`]
76	fn send() -> Weight;
77}
78
79/// Send an XCM from a given origin.
80///
81/// An implementation of that trait will handle the low-level details of dispatching an XCM, such
82/// as:
83/// - Validating and Converting the origin to an interior location.
84/// - Handling versioning.
85/// - Calling the internal router, which implements [`SendXcm`].
86pub trait SendController<Origin> {
87	/// Weight information for SendController functions.
88	type WeightInfo: SendControllerWeightInfo;
89
90	/// Send an XCM to be executed by a remote location.
91	///
92	/// # Parameters
93	///
94	/// - `origin`: the origin of the call.
95	/// - `dest`: the destination of the message.
96	/// - `msg`: the XCM to be sent.
97	fn send(
98		origin: Origin,
99		dest: Box<VersionedLocation>,
100		message: Box<VersionedXcm<()>>,
101	) -> Result<XcmHash, DispatchError>;
102}
103
104/// Weight functions needed for [`QueryController`].
105pub trait QueryControllerWeightInfo {
106	/// Weight for [`QueryController::query`]
107	fn query() -> Weight;
108
109	/// Weight for [`QueryHandler::take_response`]
110	fn take_response() -> Weight;
111}
112
113/// Query a remote location, from a given origin.
114///
115/// An implementation of that trait will handle the low-level details of querying a remote location,
116/// such as:
117/// - Validating and Converting the origin to an interior location.
118/// - Handling versioning.
119/// - Calling the [`QueryHandler`] to register the query.
120pub trait QueryController<Origin, Timeout>: QueryHandler {
121	/// Weight information for QueryController functions.
122	type WeightInfo: QueryControllerWeightInfo;
123
124	/// Query a remote location.
125	///
126	/// # Parameters
127	///
128	/// - `origin`: the origin of the call, used to determine the responder.
129	/// - `timeout`: the maximum block number that the query should be responded to.
130	/// - `match_querier`: the querier that the query should be responded to.
131	fn query(
132		origin: Origin,
133		timeout: Timeout,
134		match_querier: VersionedLocation,
135	) -> Result<QueryId, DispatchError>;
136}
137
138impl<Origin, RuntimeCall> ExecuteController<Origin, RuntimeCall> for () {
139	type WeightInfo = ();
140	fn execute(
141		_origin: Origin,
142		_message: Box<VersionedXcm<RuntimeCall>>,
143		_max_weight: Weight,
144	) -> Result<Weight, DispatchErrorWithPostInfo> {
145		Err(DispatchError::Other("ExecuteController::execute not implemented")
146			.with_weight(Weight::zero()))
147	}
148}
149
150impl ExecuteControllerWeightInfo for () {
151	fn execute() -> Weight {
152		Weight::zero()
153	}
154}
155
156impl<Origin> SendController<Origin> for () {
157	type WeightInfo = ();
158	fn send(
159		_origin: Origin,
160		_dest: Box<VersionedLocation>,
161		_message: Box<VersionedXcm<()>>,
162	) -> Result<XcmHash, DispatchError> {
163		Ok(Default::default())
164	}
165}
166
167impl SendControllerWeightInfo for () {
168	fn send() -> Weight {
169		Weight::zero()
170	}
171}
172
173impl QueryControllerWeightInfo for () {
174	fn query() -> Weight {
175		Weight::zero()
176	}
177	fn take_response() -> Weight {
178		Weight::zero()
179	}
180}
181
182impl<Origin, Timeout> QueryController<Origin, Timeout> for () {
183	type WeightInfo = ();
184
185	fn query(
186		_origin: Origin,
187		_timeout: Timeout,
188		_match_querier: VersionedLocation,
189	) -> Result<QueryId, DispatchError> {
190		Ok(Default::default())
191	}
192}