ibc_middleware_module/
lib.rs

1//! IBC module to facilitate middleware implementations.
2
3#![no_std]
4
5use ibc_core_channel_types::acknowledgement::Acknowledgement;
6use ibc_core_channel_types::channel::{Counterparty, Order};
7use ibc_core_channel_types::error::ChannelError;
8use ibc_core_channel_types::packet::Packet;
9use ibc_core_channel_types::Version;
10use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId};
11use ibc_core_router::module::Module;
12use ibc_core_router_types::module::ModuleExtras;
13use ibc_primitives::Signer;
14
15pub trait MiddlewareModule {
16    type NextMiddleware: Module;
17
18    fn next_middleware(&self) -> &Self::NextMiddleware;
19
20    fn next_middleware_mut(&mut self) -> &mut Self::NextMiddleware;
21
22    #[inline(always)]
23    fn middleware_on_chan_open_init_validate(
24        &self,
25        order: Order,
26        connection_hops: &[ConnectionId],
27        port_id: &PortId,
28        channel_id: &ChannelId,
29        counterparty: &Counterparty,
30        version: &Version,
31    ) -> Result<Version, ChannelError> {
32        self.next_middleware().on_chan_open_init_validate(
33            order,
34            connection_hops,
35            port_id,
36            channel_id,
37            counterparty,
38            version,
39        )
40    }
41
42    #[inline(always)]
43    fn middleware_on_chan_open_init_execute(
44        &mut self,
45        order: Order,
46        connection_hops: &[ConnectionId],
47        port_id: &PortId,
48        channel_id: &ChannelId,
49        counterparty: &Counterparty,
50        version: &Version,
51    ) -> Result<(ModuleExtras, Version), ChannelError> {
52        self.next_middleware_mut().on_chan_open_init_execute(
53            order,
54            connection_hops,
55            port_id,
56            channel_id,
57            counterparty,
58            version,
59        )
60    }
61
62    #[inline(always)]
63    fn middleware_on_chan_open_try_validate(
64        &self,
65        order: Order,
66        connection_hops: &[ConnectionId],
67        port_id: &PortId,
68        channel_id: &ChannelId,
69        counterparty: &Counterparty,
70        counterparty_version: &Version,
71    ) -> Result<Version, ChannelError> {
72        self.next_middleware().on_chan_open_try_validate(
73            order,
74            connection_hops,
75            port_id,
76            channel_id,
77            counterparty,
78            counterparty_version,
79        )
80    }
81
82    #[inline(always)]
83    fn middleware_on_chan_open_try_execute(
84        &mut self,
85        order: Order,
86        connection_hops: &[ConnectionId],
87        port_id: &PortId,
88        channel_id: &ChannelId,
89        counterparty: &Counterparty,
90        counterparty_version: &Version,
91    ) -> Result<(ModuleExtras, Version), ChannelError> {
92        self.next_middleware_mut().on_chan_open_try_execute(
93            order,
94            connection_hops,
95            port_id,
96            channel_id,
97            counterparty,
98            counterparty_version,
99        )
100    }
101
102    #[inline(always)]
103    fn middleware_on_chan_open_ack_validate(
104        &self,
105        port_id: &PortId,
106        channel_id: &ChannelId,
107        counterparty_version: &Version,
108    ) -> Result<(), ChannelError> {
109        self.next_middleware()
110            .on_chan_open_ack_validate(port_id, channel_id, counterparty_version)
111    }
112
113    #[inline(always)]
114    fn middleware_on_chan_open_ack_execute(
115        &mut self,
116        port_id: &PortId,
117        channel_id: &ChannelId,
118        counterparty_version: &Version,
119    ) -> Result<ModuleExtras, ChannelError> {
120        self.next_middleware_mut().on_chan_open_ack_execute(
121            port_id,
122            channel_id,
123            counterparty_version,
124        )
125    }
126
127    #[inline(always)]
128    fn middleware_on_chan_open_confirm_validate(
129        &self,
130        port_id: &PortId,
131        channel_id: &ChannelId,
132    ) -> Result<(), ChannelError> {
133        self.next_middleware()
134            .on_chan_open_confirm_validate(port_id, channel_id)
135    }
136
137    #[inline(always)]
138    fn middleware_on_chan_open_confirm_execute(
139        &mut self,
140        port_id: &PortId,
141        channel_id: &ChannelId,
142    ) -> Result<ModuleExtras, ChannelError> {
143        self.next_middleware_mut()
144            .on_chan_open_confirm_execute(port_id, channel_id)
145    }
146
147    #[inline(always)]
148    fn middleware_on_chan_close_init_validate(
149        &self,
150        port_id: &PortId,
151        channel_id: &ChannelId,
152    ) -> Result<(), ChannelError> {
153        self.next_middleware()
154            .on_chan_close_init_validate(port_id, channel_id)
155    }
156
157    #[inline(always)]
158    fn middleware_on_chan_close_init_execute(
159        &mut self,
160        port_id: &PortId,
161        channel_id: &ChannelId,
162    ) -> Result<ModuleExtras, ChannelError> {
163        self.next_middleware_mut()
164            .on_chan_close_init_execute(port_id, channel_id)
165    }
166
167    #[inline(always)]
168    fn middleware_on_chan_close_confirm_validate(
169        &self,
170        port_id: &PortId,
171        channel_id: &ChannelId,
172    ) -> Result<(), ChannelError> {
173        self.next_middleware()
174            .on_chan_close_confirm_validate(port_id, channel_id)
175    }
176
177    #[inline(always)]
178    fn middleware_on_chan_close_confirm_execute(
179        &mut self,
180        port_id: &PortId,
181        channel_id: &ChannelId,
182    ) -> Result<ModuleExtras, ChannelError> {
183        self.next_middleware_mut()
184            .on_chan_close_confirm_execute(port_id, channel_id)
185    }
186
187    #[inline(always)]
188    fn middleware_on_recv_packet_execute(
189        &mut self,
190        packet: &Packet,
191        relayer: &Signer,
192    ) -> (ModuleExtras, Option<Acknowledgement>) {
193        self.next_middleware_mut()
194            .on_recv_packet_execute(packet, relayer)
195    }
196
197    #[inline(always)]
198    fn middleware_on_acknowledgement_packet_validate(
199        &self,
200        packet: &Packet,
201        acknowledgement: &Acknowledgement,
202        relayer: &Signer,
203    ) -> Result<(), ChannelError> {
204        self.next_middleware()
205            .on_acknowledgement_packet_validate(packet, acknowledgement, relayer)
206    }
207
208    #[inline(always)]
209    fn middleware_on_acknowledgement_packet_execute(
210        &mut self,
211        packet: &Packet,
212        acknowledgement: &Acknowledgement,
213        relayer: &Signer,
214    ) -> (ModuleExtras, Result<(), ChannelError>) {
215        self.next_middleware_mut()
216            .on_acknowledgement_packet_execute(packet, acknowledgement, relayer)
217    }
218
219    #[inline(always)]
220    fn middleware_on_timeout_packet_validate(
221        &self,
222        packet: &Packet,
223        relayer: &Signer,
224    ) -> Result<(), ChannelError> {
225        self.next_middleware()
226            .on_timeout_packet_validate(packet, relayer)
227    }
228
229    #[inline(always)]
230    fn middleware_on_timeout_packet_execute(
231        &mut self,
232        packet: &Packet,
233        relayer: &Signer,
234    ) -> (ModuleExtras, Result<(), ChannelError>) {
235        self.next_middleware_mut()
236            .on_timeout_packet_execute(packet, relayer)
237    }
238}
239
240#[cfg(test)]
241mod tests {
242    use ibc_middleware_module_macros::from_middleware;
243    use ibc_testkit::testapp::ibc::applications::transfer::types::DummyTransferModule;
244
245    use super::*;
246
247    #[derive(Debug)]
248    struct DummyMiddleware<M>(M);
249
250    from_middleware! {
251        impl<M: Module> Module for DummyMiddleware<M>
252    }
253
254    impl<M> MiddlewareModule for DummyMiddleware<M>
255    where
256        M: Module,
257    {
258        type NextMiddleware = M;
259
260        fn next_middleware(&self) -> &Self::NextMiddleware {
261            &self.0
262        }
263
264        fn next_middleware_mut(&mut self) -> &mut Self::NextMiddleware {
265            &mut self.0
266        }
267
268        fn middleware_on_chan_close_init_validate(
269            &self,
270            _: &PortId,
271            _: &ChannelId,
272        ) -> Result<(), ChannelError> {
273            panic!("panicked from middleware")
274        }
275    }
276
277    fn assert_module_impl<M: Module>() {}
278
279    #[test]
280    fn dummy_middleware_is_module() {
281        assert_module_impl::<DummyMiddleware<DummyTransferModule>>();
282    }
283
284    #[test]
285    #[should_panic = "panicked from middleware"]
286    fn dummy_middleware_overrides_method() {
287        _ = DummyMiddleware(DummyTransferModule)
288            .on_chan_close_init_validate(&PortId::transfer(), &ChannelId::new(0));
289    }
290}