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