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