1 //! Utilities for supporting custom peer-to-peer messages in LDK.
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.
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.
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.
15 //! # extern crate bitcoin;
16 //! extern crate lightning;
18 //! extern crate lightning_custom_message;
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;
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.
34 //! macro_rules! foo_type_id {
38 //! impl wire::Type for Foo {
39 //! fn type_id(&self) -> u16 { foo_type_id!() }
41 //! impl Writeable for Foo {
43 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
44 //! # unimplemented!()
48 //! pub struct FooHandler;
50 //! impl CustomMessageReader for FooHandler {
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!()
59 //! impl CustomMessageHandler for FooHandler {
61 //! # fn handle_custom_message(
62 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
63 //! # ) -> Result<(), LightningError> {
64 //! # unimplemented!()
66 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
67 //! # unimplemented!()
74 //! macro_rules! bar_type_id {
78 //! impl wire::Type for Bar {
79 //! fn type_id(&self) -> u16 { bar_type_id!() }
81 //! impl Writeable for Bar {
83 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
84 //! # unimplemented!()
88 //! pub struct BarHandler;
90 //! impl CustomMessageReader for BarHandler {
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!()
99 //! impl CustomMessageHandler for BarHandler {
101 //! # fn handle_custom_message(
102 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
103 //! # ) -> Result<(), LightningError> {
104 //! # unimplemented!()
106 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
107 //! # unimplemented!()
114 //! macro_rules! baz_type_id {
118 //! impl wire::Type for Baz {
119 //! fn type_id(&self) -> u16 { baz_type_id!() }
121 //! impl Writeable for Baz {
123 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
124 //! # unimplemented!()
128 //! pub struct BazHandler;
130 //! impl CustomMessageReader for BazHandler {
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!()
139 //! impl CustomMessageHandler for BazHandler {
141 //! # fn handle_custom_message(
142 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
143 //! # ) -> Result<(), LightningError> {
144 //! # unimplemented!()
146 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
147 //! # unimplemented!()
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.
155 //! composite_custom_message_handler!(
156 //! pub struct FooBarHandler {
161 //! pub enum FooBarMessage {
162 //! Foo(foo_type_id!()),
163 //! Bar(bar_type_id!()),
168 //! macro_rules! foo_bar_type_ids {
169 //! () => { foo_type_id!() | bar_type_id!() }
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.
175 //! composite_custom_message_handler!(
176 //! pub struct FooBarBazHandler {
177 //! foo_bar: FooBarHandler,
181 //! pub enum FooBarBazMessage {
182 //! FooBar(foo_bar_type_ids!()),
183 //! Baz(baz_type_id!()),
188 //! macro_rules! foo_bar_baz_type_ids {
189 //! () => { foo_bar_type_ids!() | baz_type_id!() }
194 //! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
195 //! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
197 #![doc(test(no_crate_inject, attr(deny(warnings))))]
199 pub extern crate bitcoin;
200 pub extern crate lightning;
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.
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.
211 /// See [crate documentation] for example usage.
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
219 macro_rules! composite_custom_message_handler {
221 $handler_visibility:vis struct $handler:ident {
222 $($field_visibility:vis $field:ident: $type:ty),* $(,)*
225 $message_visibility:vis enum $message:ident {
226 $($variant:ident($pattern:pat)),* $(,)*
229 #[allow(missing_docs)]
230 $handler_visibility struct $handler {
232 $field_visibility $field: $type,
236 #[allow(missing_docs)]
238 $message_visibility enum $message {
240 $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
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> {
250 $message::$variant(message) => {
251 $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
252 &self.$field, message, sender_node_id
259 fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
264 .get_and_clear_pending_msg()
266 .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
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> {
280 $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
281 None => unreachable!(),
282 Some(message) => Ok(Some($message::$variant(message))),
290 impl $crate::lightning::ln::wire::Type for $message {
291 fn type_id(&self) -> u16 {
294 Self::$variant(message) => message.type_id(),
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> {
304 Self::$variant(message) => message.write(writer),