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 //! # fn main() {} // Avoid #[macro_export] generating an in-function warning
16 //! # extern crate bitcoin;
17 //! extern crate lightning;
19 //! extern crate lightning_custom_message;
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;
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.
36 //! macro_rules! foo_type_id {
40 //! impl wire::Type for Foo {
41 //! fn type_id(&self) -> u16 { foo_type_id!() }
43 //! impl Writeable for Foo {
45 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
46 //! # unimplemented!()
50 //! pub struct FooHandler;
52 //! impl CustomMessageReader for FooHandler {
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!()
61 //! impl CustomMessageHandler for FooHandler {
63 //! # fn handle_custom_message(
64 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
65 //! # ) -> Result<(), LightningError> {
66 //! # unimplemented!()
68 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
69 //! # unimplemented!()
71 //! # fn provided_node_features(&self) -> NodeFeatures {
72 //! # unimplemented!()
74 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
75 //! # unimplemented!()
82 //! macro_rules! bar_type_id {
86 //! impl wire::Type for Bar {
87 //! fn type_id(&self) -> u16 { bar_type_id!() }
89 //! impl Writeable for Bar {
91 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
92 //! # unimplemented!()
96 //! pub struct BarHandler;
98 //! impl CustomMessageReader for BarHandler {
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!()
107 //! impl CustomMessageHandler for BarHandler {
109 //! # fn handle_custom_message(
110 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
111 //! # ) -> Result<(), LightningError> {
112 //! # unimplemented!()
114 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
115 //! # unimplemented!()
117 //! # fn provided_node_features(&self) -> NodeFeatures {
118 //! # unimplemented!()
120 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
121 //! # unimplemented!()
128 //! macro_rules! baz_type_id {
132 //! impl wire::Type for Baz {
133 //! fn type_id(&self) -> u16 { baz_type_id!() }
135 //! impl Writeable for Baz {
137 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
138 //! # unimplemented!()
142 //! pub struct BazHandler;
144 //! impl CustomMessageReader for BazHandler {
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!()
153 //! impl CustomMessageHandler for BazHandler {
155 //! # fn handle_custom_message(
156 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
157 //! # ) -> Result<(), LightningError> {
158 //! # unimplemented!()
160 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
161 //! # unimplemented!()
163 //! # fn provided_node_features(&self) -> NodeFeatures {
164 //! # unimplemented!()
166 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
167 //! # 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!() }
212 //! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
213 //! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
215 #![doc(test(no_crate_inject, attr(deny(warnings))))]
217 pub extern crate bitcoin;
218 pub extern crate lightning;
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.
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.
229 /// See [crate documentation] for example usage.
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
237 macro_rules! composite_custom_message_handler {
239 $handler_visibility:vis struct $handler:ident {
240 $($field_visibility:vis $field:ident: $type:ty),* $(,)*
243 $message_visibility:vis enum $message:ident {
244 $($variant:ident($pattern:pat)),* $(,)*
247 #[allow(missing_docs)]
248 $handler_visibility struct $handler {
250 $field_visibility $field: $type,
254 #[allow(missing_docs)]
256 $message_visibility enum $message {
258 $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
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> {
268 $message::$variant(message) => {
269 $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
270 &self.$field, message, sender_node_id
277 fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
282 .get_and_clear_pending_msg()
284 .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
290 fn provided_node_features(&self) -> $crate::lightning::ln::features::NodeFeatures {
291 $crate::lightning::ln::features::NodeFeatures::empty()
293 | self.$field.provided_node_features()
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()
302 | self.$field.provided_init_features(their_node_id)
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> {
314 $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
315 None => unreachable!(),
316 Some(message) => Ok(Some($message::$variant(message))),
324 impl $crate::lightning::ln::wire::Type for $message {
325 fn type_id(&self) -> u16 {
328 Self::$variant(message) => message.type_id(),
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> {
338 Self::$variant(message) => message.write(writer),