sp_messenger/
endpoint.rs

1#[cfg(not(feature = "std"))]
2extern crate alloc;
3
4#[cfg(not(feature = "std"))]
5use alloc::vec::Vec;
6use frame_support::weights::Weight;
7use frame_support::Parameter;
8use parity_scale_codec::{Decode, Encode};
9use scale_info::TypeInfo;
10use sp_domains::ChainId;
11use sp_runtime::traits::Member;
12use sp_runtime::{DispatchError, DispatchResult};
13
14/// Represents a particular endpoint in a given Execution environment.
15pub type EndpointId = u64;
16
17/// Endpoint as defined in the formal spec.
18/// Endpoint is an application that can send and receive messages from other chains.
19#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
20pub enum Endpoint {
21    /// Id of the endpoint on a specific chain.
22    Id(EndpointId),
23}
24
25/// Endpoint request or response payload.
26pub type EndpointPayload = Vec<u8>;
27
28/// Fee collected on src_chain for execution of XDM on both the src and dst chains.
29#[derive(Default, Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
30pub struct CollectedFee<Balance> {
31    /// Collected execution fee for src_chain.
32    pub src_chain_fee: Balance,
33    /// Collected execution fee for dst_chain.
34    pub dst_chain_fee: Balance,
35}
36
37/// Request sent by src_endpoint to dst_endpoint.
38#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
39pub struct EndpointRequest {
40    pub src_endpoint: Endpoint,
41    pub dst_endpoint: Endpoint,
42    pub payload: EndpointPayload,
43}
44
45/// Request sent by src_endpoint to dst_endpoint with collected Fee
46#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
47pub struct EndpointRequestWithCollectedFee<Balance> {
48    pub req: EndpointRequest,
49    pub collected_fee: CollectedFee<Balance>,
50}
51
52impl<Balance> From<EndpointRequestWithCollectedFee<Balance>> for EndpointRequest {
53    fn from(value: EndpointRequestWithCollectedFee<Balance>) -> Self {
54        value.req
55    }
56}
57
58impl<Balance: Default> From<EndpointRequest> for EndpointRequestWithCollectedFee<Balance> {
59    fn from(value: EndpointRequest) -> Self {
60        EndpointRequestWithCollectedFee {
61            req: value,
62            collected_fee: CollectedFee::default(),
63        }
64    }
65}
66
67/// Response for the message request.
68pub type EndpointResponse = Result<EndpointPayload, DispatchError>;
69
70/// Sender provides abstraction on sending messages to other chains.
71pub trait Sender<AccountId> {
72    /// Unique Id of the message between dst_chain and src_chain.
73    type MessageId: Parameter + Member + Copy + Default;
74    /// Sends a message to dst_chain_id.
75    fn send_message(
76        sender: &AccountId,
77        dst_chain_id: ChainId,
78        req: EndpointRequest,
79    ) -> Result<Self::MessageId, DispatchError>;
80
81    /// Only used in benchmark to prepare for a upcoming `send_message` call to
82    /// ensure it will succeed.
83    #[cfg(feature = "runtime-benchmarks")]
84    fn unchecked_open_channel(dst_chain_id: ChainId) -> Result<(), DispatchError>;
85}
86
87/// Handler to
88///  - handle message request from other chains.
89///  - handle requested message responses from other chains.
90pub trait EndpointHandler<MessageId> {
91    /// Triggered by pallet-messenger when a new inbox message is received and bound for this handler.
92    fn message(
93        &self,
94        src_chain_id: ChainId,
95        message_id: MessageId,
96        req: EndpointRequest,
97        // if pre_checks failed, implementation should reject the transfer
98        pre_check_result: DispatchResult,
99    ) -> EndpointResponse;
100
101    /// Return the maximal possible consume weight of `message`
102    fn message_weight(&self) -> Weight;
103
104    /// Triggered by pallet-messenger when a response for a request is received from dst_chain_id.
105    fn message_response(
106        &self,
107        dst_chain_id: ChainId,
108        message_id: MessageId,
109        req: EndpointRequest,
110        resp: EndpointResponse,
111    ) -> DispatchResult;
112
113    /// Return the maximal possible consume weight of `message_response`
114    fn message_response_weight(&self) -> Weight;
115}
116
117#[cfg(feature = "runtime-benchmarks")]
118pub struct BenchmarkEndpointHandler;
119
120#[cfg(feature = "runtime-benchmarks")]
121impl<MessageId> EndpointHandler<MessageId> for BenchmarkEndpointHandler {
122    fn message(
123        &self,
124        _src_chain_id: ChainId,
125        _message_id: MessageId,
126        _req: EndpointRequest,
127        _pre_check_result: DispatchResult,
128    ) -> EndpointResponse {
129        Ok(Vec::new())
130    }
131
132    fn message_weight(&self) -> Weight {
133        Weight::zero()
134    }
135
136    fn message_response(
137        &self,
138        _dst_chain_id: ChainId,
139        _message_id: MessageId,
140        _req: EndpointRequest,
141        _resp: EndpointResponse,
142    ) -> DispatchResult {
143        Ok(())
144    }
145
146    fn message_response_weight(&self) -> Weight {
147        Weight::zero()
148    }
149}