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