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, Init, 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 peer_disconnected(&self, _their_node_id: &PublicKey) {
72 //! # unimplemented!()
74 //! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
75 //! # unimplemented!()
77 //! # fn provided_node_features(&self) -> NodeFeatures {
78 //! # unimplemented!()
80 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
81 //! # unimplemented!()
88 //! macro_rules! bar_type_id {
92 //! impl wire::Type for Bar {
93 //! fn type_id(&self) -> u16 { bar_type_id!() }
95 //! impl Writeable for Bar {
97 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
98 //! # unimplemented!()
102 //! pub struct BarHandler;
104 //! impl CustomMessageReader for BarHandler {
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!()
113 //! impl CustomMessageHandler for BarHandler {
115 //! # fn handle_custom_message(
116 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
117 //! # ) -> Result<(), LightningError> {
118 //! # unimplemented!()
120 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
121 //! # unimplemented!()
123 //! # fn peer_disconnected(&self, _their_node_id: &PublicKey) {
124 //! # unimplemented!()
126 //! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
127 //! # unimplemented!()
129 //! # fn provided_node_features(&self) -> NodeFeatures {
130 //! # unimplemented!()
132 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
133 //! # unimplemented!()
140 //! macro_rules! baz_type_id {
144 //! impl wire::Type for Baz {
145 //! fn type_id(&self) -> u16 { baz_type_id!() }
147 //! impl Writeable for Baz {
149 //! # fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
150 //! # unimplemented!()
154 //! pub struct BazHandler;
156 //! impl CustomMessageReader for BazHandler {
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!()
165 //! impl CustomMessageHandler for BazHandler {
167 //! # fn handle_custom_message(
168 //! # &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
169 //! # ) -> Result<(), LightningError> {
170 //! # unimplemented!()
172 //! # fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
173 //! # unimplemented!()
175 //! # fn peer_disconnected(&self, _their_node_id: &PublicKey) {
176 //! # unimplemented!()
178 //! # fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
179 //! # unimplemented!()
181 //! # fn provided_node_features(&self) -> NodeFeatures {
182 //! # unimplemented!()
184 //! # fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
185 //! # unimplemented!()
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.
192 //! composite_custom_message_handler!(
193 //! pub struct FooBarHandler {
198 //! pub enum FooBarMessage {
199 //! Foo(foo_type_id!()),
200 //! Bar(bar_type_id!()),
205 //! macro_rules! foo_bar_type_ids {
206 //! () => { foo_type_id!() | bar_type_id!() }
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.
212 //! composite_custom_message_handler!(
213 //! pub struct FooBarBazHandler {
214 //! foo_bar: FooBarHandler,
218 //! pub enum FooBarBazMessage {
219 //! FooBar(foo_bar_type_ids!()),
220 //! Baz(baz_type_id!()),
225 //! macro_rules! foo_bar_baz_type_ids {
226 //! () => { foo_bar_type_ids!() | baz_type_id!() }
230 //! [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md
231 //! [`CustomMessageHandler`]: crate::lightning::ln::peer_handler::CustomMessageHandler
233 #![doc(test(no_crate_inject, attr(deny(warnings))))]
235 pub extern crate bitcoin;
236 pub extern crate lightning;
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.
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.
247 /// See [crate documentation] for example usage.
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
255 macro_rules! composite_custom_message_handler {
257 $handler_visibility:vis struct $handler:ident {
258 $($field_visibility:vis $field:ident: $type:ty),* $(,)*
261 $message_visibility:vis enum $message:ident {
262 $($variant:ident($pattern:pat)),* $(,)*
265 #[allow(missing_docs)]
266 $handler_visibility struct $handler {
268 $field_visibility $field: $type,
272 #[allow(missing_docs)]
274 $message_visibility enum $message {
276 $variant(<$type as $crate::lightning::ln::wire::CustomMessageReader>::CustomMessage),
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> {
286 $message::$variant(message) => {
287 $crate::lightning::ln::peer_handler::CustomMessageHandler::handle_custom_message(
288 &self.$field, message, sender_node_id
295 fn get_and_clear_pending_msg(&self) -> Vec<($crate::bitcoin::secp256k1::PublicKey, Self::CustomMessage)> {
300 .get_and_clear_pending_msg()
302 .map(|(pubkey, message)| (pubkey, $message::$variant(message)))
308 fn peer_disconnected(&self, their_node_id: &$crate::bitcoin::secp256k1::PublicKey) {
310 self.$field.peer_disconnected(their_node_id);
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(());
317 if let Err(e) = self.$field.peer_connected(their_node_id, msg, inbound) {
324 fn provided_node_features(&self) -> $crate::lightning::ln::features::NodeFeatures {
325 $crate::lightning::ln::features::NodeFeatures::empty()
327 | self.$field.provided_node_features()
331 fn provided_init_features(
332 &self, their_node_id: &$crate::bitcoin::secp256k1::PublicKey
333 ) -> $crate::lightning::ln::features::InitFeatures {
334 $crate::lightning::ln::features::InitFeatures::empty()
336 | self.$field.provided_init_features(their_node_id)
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> {
348 $pattern => match <$type>::read(&self.$field, message_type, buffer)? {
349 None => unreachable!(),
350 Some(message) => Ok(Some($message::$variant(message))),
358 impl $crate::lightning::ln::wire::Type for $message {
359 fn type_id(&self) -> u16 {
362 Self::$variant(message) => message.type_id(),
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> {
372 Self::$variant(message) => message.write(writer),