sp_messenger/
endpoint.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#[cfg(not(feature = "std"))]
extern crate alloc;

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use frame_support::weights::Weight;
use frame_support::Parameter;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_domains::ChainId;
use sp_runtime::traits::Member;
use sp_runtime::{DispatchError, DispatchResult};

/// Represents a particular endpoint in a given Execution environment.
pub type EndpointId = u64;

/// Endpoint as defined in the formal spec.
/// Endpoint is an application that can send and receive messages from other chains.
#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub enum Endpoint {
    /// Id of the endpoint on a specific chain.
    Id(EndpointId),
}

/// Endpoint request or response payload.
pub type EndpointPayload = Vec<u8>;

/// Fee collected on src_chain for execution of XDM on both the src and dst chains.
#[derive(Default, Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub struct CollectedFee<Balance> {
    /// Collected execution fee for src_chain.
    pub src_chain_fee: Balance,
    /// Collected execution fee for dst_chain.
    pub dst_chain_fee: Balance,
}

/// Request sent by src_endpoint to dst_endpoint.
#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub struct EndpointRequest {
    pub src_endpoint: Endpoint,
    pub dst_endpoint: Endpoint,
    pub payload: EndpointPayload,
}

/// Request sent by src_endpoint to dst_endpoint with collected Fee
#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub struct EndpointRequestWithCollectedFee<Balance> {
    pub req: EndpointRequest,
    pub collected_fee: CollectedFee<Balance>,
}

impl<Balance> From<EndpointRequestWithCollectedFee<Balance>> for EndpointRequest {
    fn from(value: EndpointRequestWithCollectedFee<Balance>) -> Self {
        value.req
    }
}

impl<Balance: Default> From<EndpointRequest> for EndpointRequestWithCollectedFee<Balance> {
    fn from(value: EndpointRequest) -> Self {
        EndpointRequestWithCollectedFee {
            req: value,
            collected_fee: CollectedFee::default(),
        }
    }
}

/// Response for the message request.
pub type EndpointResponse = Result<EndpointPayload, DispatchError>;

/// Sender provides abstraction on sending messages to other chains.
pub trait Sender<AccountId> {
    /// Unique Id of the message between dst_chain and src_chain.
    type MessageId: Parameter + Member + Copy + Default;
    /// Sends a message to dst_chain_id.
    fn send_message(
        sender: &AccountId,
        dst_chain_id: ChainId,
        req: EndpointRequest,
    ) -> Result<Self::MessageId, DispatchError>;

    /// Only used in benchmark to prepare for a upcoming `send_message` call to
    /// ensure it will succeed.
    #[cfg(feature = "runtime-benchmarks")]
    fn unchecked_open_channel(dst_chain_id: ChainId) -> Result<(), DispatchError>;
}

/// Handler to
///  - handle message request from other chains.
///  - handle requested message responses from other chains.
pub trait EndpointHandler<MessageId> {
    /// Triggered by pallet-messenger when a new inbox message is received and bound for this handler.
    fn message(
        &self,
        src_chain_id: ChainId,
        message_id: MessageId,
        req: EndpointRequest,
    ) -> EndpointResponse;

    /// Return the maximal possible consume weight of `message`
    fn message_weight(&self) -> Weight;

    /// Triggered by pallet-messenger when a response for a request is received from dst_chain_id.
    fn message_response(
        &self,
        dst_chain_id: ChainId,
        message_id: MessageId,
        req: EndpointRequest,
        resp: EndpointResponse,
    ) -> DispatchResult;

    /// Return the maximal possible consume weight of `message_response`
    fn message_response_weight(&self) -> Weight;
}

#[cfg(feature = "runtime-benchmarks")]
pub struct BenchmarkEndpointHandler;

#[cfg(feature = "runtime-benchmarks")]
impl<MessageId> EndpointHandler<MessageId> for BenchmarkEndpointHandler {
    fn message(
        &self,
        _src_chain_id: ChainId,
        _message_id: MessageId,
        _req: EndpointRequest,
    ) -> EndpointResponse {
        Ok(Vec::new())
    }

    fn message_weight(&self) -> Weight {
        Weight::zero()
    }

    fn message_response(
        &self,
        _dst_chain_id: ChainId,
        _message_id: MessageId,
        _req: EndpointRequest,
        _resp: EndpointResponse,
    ) -> DispatchResult {
        Ok(())
    }

    fn message_response_weight(&self) -> Weight {
        Weight::zero()
    }
}