a6e43978d47ded2e1c9efd58c50fe234d7a02564
[rust-lightning] / lightning-custom-message / src / lib.rs
1 //! Utilities for supporting custom peer-to-peer messages in LDK.
2 //!
3 //! [BOLT 1] specifies a custom message type range for use with experimental or application-specific
4 //! messages. While a [`CustomMessageHandler`] can be defined to support more than one message type,
5 //! defining such a handler requires a significant amount of boilerplate and can be error prone.
6 //!
7 //! This crate provides the [`composite_custom_message_handler`] macro for easily composing
8 //! pre-defined custom message handlers into one handler. The resulting handler can be further
9 //! composed with other custom message handlers using the same macro.
10 //!
11 //! The following example demonstrates defining a `FooBarHandler` to compose separate handlers for
12 //! `Foo` and `Bar` messages, and further composing it with a handler for `Baz` messages.
13 //!
14 //!```
15 //! # extern crate bitcoin;
16 //! extern crate lightning;
17 //! #[macro_use]
18 //! extern crate lightning_custom_message;
19 //!
20 //! # use bitcoin::secp256k1::PublicKey;
21 //! # use lightning::io;
22 //! # use lightning::ln::msgs::{DecodeError, LightningError};
23 //! use lightning::ln::peer_handler::CustomMessageHandler;
24 //! use lightning::ln::wire::{CustomMessageReader, self};
25 //! use lightning::util::ser::Writeable;
26 //! # use lightning::util::ser::Writer;
27 //!
28 //! // Assume that `FooHandler` and `BarHandler` are defined in one crate and `BazHandler` is
29 //! // defined in another crate, handling messages `Foo`, `Bar`, and `Baz`, respectively.
30 //!
31 //! #[derive(Debug)]
32 //! pub struct Foo;
33 //!
34 //! macro_rules! foo_type_id {
35 //!     () => { 32768 }
36 //! }
37 //!
38 //! impl wire::Type for Foo {
39 //!     fn type_id(&self) -> u16 { foo_type_id!() }
40 //! }
41 //! impl Writeable for Foo {
42 //!     // ...
43 //! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
44 //! #         unimplemented!()
45 //! #     }
46 //! }
47 //!
48 //! pub struct FooHandler;
49 //!
50 //! impl CustomMessageReader for FooHandler {
51 //!     // ...
52 //! #     type CustomMessage = Foo;
53 //! #     fn read<R: io::Read>(
54 //! #         &self, _message_type: u16, _buffer: &mut R
55 //! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
56 //! #         unimplemented!()
57 //! #     }
58 //! }
59 //! impl CustomMessageHandler for FooHandler {
60 //!     // ...
61 //! #     fn handle_custom_message(
62 //! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
63 //! #     ) -> Result<(), LightningError> {
64 //! #         unimplemented!()
65 //! #     }
66 //! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
67 //! #         unimplemented!()
68 //! #     }
69 //! }
70 //!
71 //! #[derive(Debug)]
72 //! pub struct Bar;
73 //!
74 //! macro_rules! bar_type_id {
75 //!     () => { 32769 }
76 //! }
77 //!
78 //! impl wire::Type for Bar {
79 //!     fn type_id(&self) -> u16 { bar_type_id!() }
80 //! }
81 //! impl Writeable for Bar {
82 //!     // ...
83 //! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
84 //! #         unimplemented!()
85 //! #     }
86 //! }
87 //!
88 //! pub struct BarHandler;
89 //!
90 //! impl CustomMessageReader for BarHandler {
91 //!     // ...
92 //! #     type CustomMessage = Bar;
93 //! #     fn read<R: io::Read>(
94 //! #         &self, _message_type: u16, _buffer: &mut R
95 //! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
96 //! #         unimplemented!()
97 //! #     }
98 //! }
99 //! impl CustomMessageHandler for BarHandler {
100 //!     // ...
101 //! #     fn handle_custom_message(
102 //! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
103 //! #     ) -> Result<(), LightningError> {
104 //! #         unimplemented!()
105 //! #     }
106 //! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
107 //! #         unimplemented!()
108 //! #     }
109 //! }
110 //!
111 //! #[derive(Debug)]
112 //! pub struct Baz;
113 //!
114 //! macro_rules! baz_type_id {
115 //!     () => { 32770 }
116 //! }
117 //!
118 //! impl wire::Type for Baz {
119 //!     fn type_id(&self) -> u16 { baz_type_id!() }
120 //! }
121 //! impl Writeable for Baz {
122 //!     // ...
123 //! #     fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
124 //! #         unimplemented!()
125 //! #     }
126 //! }
127 //!
128 //! pub struct BazHandler;
129 //!
130 //! impl CustomMessageReader for BazHandler {
131 //!     // ...
132 //! #     type CustomMessage = Baz;
133 //! #     fn read<R: io::Read>(
134 //! #         &self, _message_type: u16, _buffer: &mut R
135 //! #     ) -> Result<Option<Self::CustomMessage>, DecodeError> {
136 //! #         unimplemented!()
137 //! #     }
138 //! }
139 //! impl CustomMessageHandler for BazHandler {
140 //!     // ...
141 //! #     fn handle_custom_message(
142 //! #         &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
143 //! #     ) -> Result<(), LightningError> {
144 //! #         unimplemented!()
145 //! #     }
146 //! #     fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
147 //! #         unimplemented!()
148 //! #     }
149 //! }
150 //!
151 //! # fn main() {
152 //! // The first crate may define a handler composing `FooHandler` and `BarHandler` and export the
153 //! // corresponding message type ids as a macro to use in further composition.
154 //!
155 //! composite_custom_message_handler!(
156 //!     pub struct FooBarHandler {
157 //!         foo: FooHandler,
158 //!         bar: BarHandler,
159 //!     }
160 //!
161 //!     pub enum FooBarMessage {
162 //!         Foo(foo_type_id!()),
163 //!         Bar(bar_type_id!()),
164 //!     }
165 //! );
166 //!
167 //! #[macro_export]
168 //! macro_rules! foo_bar_type_ids {
169 //!     () => { foo_type_id!() | bar_type_id!() }
170 //! }
171 //!
172 //! // Another crate can then define a handler further composing `FooBarHandler` with `BazHandler`
173 //! // and similarly export the composition of message type ids as a macro.
174 //!
175 //! composite_custom_message_handler!(
176 //!     pub struct FooBarBazHandler {
177 //!         foo_bar: FooBarHandler,
178 //!         baz: BazHandler,
179 //!     }
180 //!
181 //!     pub enum FooBarBazMessage {
182 //!         FooBar(foo_bar_type_ids!()),
183 //!         Baz(baz_type_id!()),
184 //!     }
185 //! );
186 //!
187 //! #[macro_export]
188 //! macro_rules! foo_bar_baz_type_ids {
189 //!     () => { foo_bar_type_ids!() | baz_type_id!() }
190 //! }
191 //! # }
192 //!```
193 //!
194 //! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
195 //! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
196
197 #![doc(test(no_crate_inject, attr(deny(warnings))))]
198
199 pub extern crate bitcoin;
200 pub extern crate lightning;
201
202 /// Defines a composite type implementing [`CustomMessageHandler`] (and therefore also implementing
203 /// [`CustomMessageReader`]), along with a corresponding enumerated custom message [`Type`], from
204 /// one or more previously defined custom message handlers.
205 ///
206 /// Useful for parameterizing [`PeerManager`] with custom message handling for one or more sets of
207 /// custom messages. Message type ids may be given as a valid `match` pattern, including ranges,
208 /// though using OR-ed literal patterns is preferred in order to catch unreachable code for
209 /// conflicting handlers.
210 ///
211 /// See [crate documentation] for example usage.
212 ///
213 /// [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
214 /// [`CustomMessageReader`]: crate::lightning::ln::wire::CustomMessageReader
215 /// [`Type`]: crate::lightning::ln::wire::Type
216 /// [`PeerManager`]: crate::lightning::ln::peer_handler::PeerManager
217 /// [crate documentation]: self
218 #[macro_export]
219 macro_rules! composite_custom_message_handler {
220         (
221                 $handler_visibility:vis struct $handler:ident {
222                         $($field_visibility:vis $field:ident: $type:ty),* $(,)*
223                 }
224
225                 $message_visibility:vis enum $message:ident {
226                         $($variant:ident($pattern:pat)),* $(,)*
227                 }
228         ) => {
229                 #[allow(missing_docs)]
230                 $handler_visibility struct $handler {
231                         $(
232                                 $field_visibility $field: $type,
233                         )*
234                 }
235
236                 #[allow(missing_docs)]
237                 #[derive(Debug)]
238                 $message_visibility enum $message {
239                         $(
240                                 $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
241                         )*
242                 }
243
244                 impl $crate::lightning::ln::peer_handler::CustomMessageHandler for $handler {
245                         fn handle_custom_message(
246                                 &self, msg: Self::CustomMessage, sender_node_id: &$crate::bitcoin::secp256k1::PublicKey
247                         ) -> Result<(), $crate::lightning::ln::msgs::LightningError> {
248                                 match msg {
249                                         $(
250                                                 $message::$variant(message) => {
251                                                         $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
252                                                                 &self.$field, message, sender_node_id
253                                                         )
254                                                 },
255                                         )*
256                                 }
257                         }
258
259                         fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
260                                 vec![].into_iter()
261                                         $(
262                                                 .chain(
263                                                         self.$field
264                                                                 .get_and_clear_pending_msg()
265                                                                 .into_iter()
266                                                                 .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
267                                                 )
268                                         )*
269                                         .collect()
270                         }
271                 }
272
273                 impl $crate::lightning::ln::wire::CustomMessageReader for $handler {
274                         type CustomMessage = $message;
275                         fn read<R: $crate::lightning::io::Read>(
276                                 &self, message_type: u16, buffer: &mut R
277                         ) -> Result<Option<Self::CustomMessage>, $crate::lightning::ln::msgs::DecodeError> {
278                                 match message_type {
279                                         $(
280                                                 $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
281                                                         None => unreachable!(),
282                                                         Some(message) => Ok(Some($message::$variant(message))),
283                                                 },
284                                         )*
285                                         _ => Ok(None),
286                                 }
287                         }
288                 }
289
290                 impl $crate::lightning::ln::wire::Type for $message {
291                         fn type_id(&self) -> u16 {
292                                 match self {
293                                         $(
294                                                 Self::$variant(message) => message.type_id(),
295                                         )*
296                                 }
297                         }
298                 }
299
300                 impl $crate::lightning::util::ser::Writeable for $message {
301                         fn write<W: $crate::lightning::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::lightning::io::Error> {
302                                 match self {
303                                         $(
304                                                 Self::$variant(message) => message.write(writer),
305                                         )*
306                                 }
307                         }
308                 }
309         }
310 }