23 releases

0.1.0 Jan 16, 2025
0.1.0-beta1 Dec 22, 2024
0.0.125 Oct 14, 2024
0.0.123 May 9, 2024
0.0.114 Mar 4, 2023

#10 in #lightning-network

Download history 13/week @ 2025-02-01 54/week @ 2025-02-08 86/week @ 2025-02-15 104/week @ 2025-02-22 191/week @ 2025-03-01 148/week @ 2025-03-08 88/week @ 2025-03-15 63/week @ 2025-03-22 119/week @ 2025-03-29 132/week @ 2025-04-05 196/week @ 2025-04-12 127/week @ 2025-04-19 241/week @ 2025-04-26 140/week @ 2025-05-03 244/week @ 2025-05-10 149/week @ 2025-05-17

789 downloads per month

MIT/Apache

7.5MB
121K SLoC

Utilities for supporting custom peer-to-peer messages in LDK.

BOLT 1 specifies a custom message type range for use with experimental or application-specific messages. While a CustomMessageHandler can be defined to support more than one message type, defining such a handler requires a significant amount of boilerplate and can be error prone.

This crate provides the composite_custom_message_handler macro for easily composing pre-defined custom message handlers into one handler. The resulting handler can be further composed with other custom message handlers using the same macro.

The following example demonstrates defining a FooBarHandler to compose separate handlers for Foo and Bar messages, and further composing it with a handler for Baz messages.

extern crate lightning;
#[macro_use]
extern crate lightning_custom_message;

use lightning::ln::peer_handler::CustomMessageHandler;
use lightning::ln::wire::{CustomMessageReader, self};
use lightning::util::ser::Writeable;

// Assume that `FooHandler` and `BarHandler` are defined in one crate and `BazHandler` is
// defined in another crate, handling messages `Foo`, `Bar`, and `Baz`, respectively.

#[derive(Debug)]
pub struct Foo;

macro_rules! foo_type_id {
    () => { 32768 }
}

impl wire::Type for Foo {
    fn type_id(&self) -> u16 { foo_type_id!() }
}
impl Writeable for Foo {
    // ...
}

pub struct FooHandler;

impl CustomMessageReader for FooHandler {
    // ...
}
impl CustomMessageHandler for FooHandler {
    // ...
}

#[derive(Debug)]
pub struct Bar;

macro_rules! bar_type_id {
    () => { 32769 }
}

impl wire::Type for Bar {
    fn type_id(&self) -> u16 { bar_type_id!() }
}
impl Writeable for Bar {
    // ...
}

pub struct BarHandler;

impl CustomMessageReader for BarHandler {
    // ...
}
impl CustomMessageHandler for BarHandler {
    // ...
}

#[derive(Debug)]
pub struct Baz;

macro_rules! baz_type_id {
    () => { 32770 }
}

impl wire::Type for Baz {
    fn type_id(&self) -> u16 { baz_type_id!() }
}
impl Writeable for Baz {
    // ...
}

pub struct BazHandler;

impl CustomMessageReader for BazHandler {
    // ...
}
impl CustomMessageHandler for BazHandler {
    // ...
}

// The first crate may define a handler composing `FooHandler` and `BarHandler` and export the
// corresponding message type ids as a macro to use in further composition.

composite_custom_message_handler!(
    pub struct FooBarHandler {
        foo: FooHandler,
        bar: BarHandler,
    }

    pub enum FooBarMessage {
        Foo(foo_type_id!()),
        Bar(bar_type_id!()),
    }
);

#[macro_export]
macro_rules! foo_bar_type_ids {
    () => { foo_type_id!() | bar_type_id!() }
}

// Another crate can then define a handler further composing `FooBarHandler` with `BazHandler`
// and similarly export the composition of message type ids as a macro.

composite_custom_message_handler!(
    pub struct FooBarBazHandler {
        foo_bar: FooBarHandler,
        baz: BazHandler,
    }

    pub enum FooBarBazMessage {
        FooBar(foo_bar_type_ids!()),
        Baz(baz_type_id!()),
    }
);

#[macro_export]
macro_rules! foo_bar_baz_type_ids {
    () => { foo_bar_type_ids!() | baz_type_id!() }
}

Dependencies

~9MB
~116K SLoC