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::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;
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.
35 //! macro_rules! foo_type_id {
39 //! impl wire::Type for Foo {
40 //! fn type_id(&self) -> u16 { foo_type_id!() }
42 //! impl Writeable for Foo {
44 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
45 //! # unimplemented!()
49 //! pub struct FooHandler;
51 //! impl CustomMessageReader for FooHandler {
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!()
60 //! impl CustomMessageHandler for FooHandler {
62 //! # fn handle_custom_message(
63 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
64 //! # ) -> Result<(), LightningError> {
65 //! # unimplemented!()
67 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
68 //! # unimplemented!()
70 //! # fn provided_node_features(&self) -> NodeFeatures {
71 //! # unimplemented!()
73 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
74 //! # unimplemented!()
81 //! macro_rules! bar_type_id {
85 //! impl wire::Type for Bar {
86 //! fn type_id(&self) -> u16 { bar_type_id!() }
88 //! impl Writeable for Bar {
90 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
91 //! # unimplemented!()
95 //! pub struct BarHandler;
97 //! impl CustomMessageReader for BarHandler {
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!()
106 //! impl CustomMessageHandler for BarHandler {
108 //! # fn handle_custom_message(
109 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
110 //! # ) -> Result<(), LightningError> {
111 //! # unimplemented!()
113 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
114 //! # unimplemented!()
116 //! # fn provided_node_features(&self) -> NodeFeatures {
117 //! # unimplemented!()
119 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
120 //! # unimplemented!()
127 //! macro_rules! baz_type_id {
131 //! impl wire::Type for Baz {
132 //! fn type_id(&self) -> u16 { baz_type_id!() }
134 //! impl Writeable for Baz {
136 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
137 //! # unimplemented!()
141 //! pub struct BazHandler;
143 //! impl CustomMessageReader for BazHandler {
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!()
152 //! impl CustomMessageHandler for BazHandler {
154 //! # fn handle_custom_message(
155 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
156 //! # ) -> Result<(), LightningError> {
157 //! # unimplemented!()
159 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
160 //! # unimplemented!()
162 //! # fn provided_node_features(&self) -> NodeFeatures {
163 //! # unimplemented!()
165 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
166 //! # unimplemented!()
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.
174 //! composite_custom_message_handler!(
175 //! pub struct FooBarHandler {
180 //! pub enum FooBarMessage {
181 //! Foo(foo_type_id!()),
182 //! Bar(bar_type_id!()),
187 //! macro_rules! foo_bar_type_ids {
188 //! () => { foo_type_id!() | bar_type_id!() }
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.
194 //! composite_custom_message_handler!(
195 //! pub struct FooBarBazHandler {
196 //! foo_bar: FooBarHandler,
200 //! pub enum FooBarBazMessage {
201 //! FooBar(foo_bar_type_ids!()),
202 //! Baz(baz_type_id!()),
207 //! macro_rules! foo_bar_baz_type_ids {
208 //! () => { foo_bar_type_ids!() | baz_type_id!() }
213 //! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
214 //! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
216 #![doc(test(no_crate_inject, attr(deny(warnings))))]
218 pub extern crate bitcoin;
219 pub extern crate lightning;
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.
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.
230 /// See [crate documentation] for example usage.
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
238 macro_rules! composite_custom_message_handler {
240 $handler_visibility:vis struct $handler:ident {
241 $($field_visibility:vis $field:ident: $type:ty),* $(,)*
244 $message_visibility:vis enum $message:ident {
245 $($variant:ident($pattern:pat)),* $(,)*
248 #[allow(missing_docs)]
249 $handler_visibility struct $handler {
251 $field_visibility $field: $type,
255 #[allow(missing_docs)]
257 $message_visibility enum $message {
259 $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
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> {
269 $message::$variant(message) => {
270 $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
271 &self.$field, message, sender_node_id
278 fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
283 .get_and_clear_pending_msg()
285 .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
291 fn provided_node_features(&self) -> $crate::lightning::ln::features::NodeFeatures {
292 $crate::lightning::ln::features::NodeFeatures::empty()
294 | self.$field.provided_node_features()
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()
303 | self.$field.provided_init_features(their_node_id)
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> {
315 $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
316 None => unreachable!(),
317 Some(message) => Ok(Some($message::$variant(message))),
325 impl $crate::lightning::ln::wire::Type for $message {
326 fn type_id(&self) -> u16 {
329 Self::$variant(message) => message.type_id(),
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> {
339 Self::$variant(message) => message.write(writer),