Skip to content

Commit

Permalink
WIP: Composite CustomMessageHandler macro
Browse files Browse the repository at this point in the history
A CustomMessageHandler may be used to implement an extension to the BOLT
specs. Using more than one custom handler requires defining a wrapper
for both the handlers and their CustomMessage associated type. Define a
macro that takes care of this boilerplate.
  • Loading branch information
jkczyz committed Nov 4, 2022
1 parent 6957fb6 commit 75e4328
Showing 1 changed file with 77 additions and 0 deletions.
77 changes: 77 additions & 0 deletions lightning/src/ln/peer_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,85 @@ pub trait CustomMessageHandler: wire::CustomMessageReader {
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)>;
}

macro_rules! composite_custom_message_handler {
(
$handler_visibility:vis struct $handler:ident {
$($field_visibility:vis $field:ident: $type:ty),* $(,)*
}

$message_visibility:vis enum $message:ident {
$($variant:ident($range:pat)),* $(,)*
}
) => {
#[allow(missing_docs)]
$handler_visibility struct $handler {
$(
$field_visibility $field: $type,
)*
}

#[allow(missing_docs)]
#[derive(Debug)]
$message_visibility enum $message {
$(
$variant(<$type as wire::CustomMessageReader>::CustomMessage),
)*
}

impl wire::CustomMessageReader for $handler {
type CustomMessage = $message;
fn read<R: io::Read>(
&self, message_type: u16, buffer: &mut R
) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
match message_type {
$(
$range => match <$type>::read(&self.$field, message_type, buffer)? {
None => unreachable!(),
Some(message) => Ok(Some($message::$variant(message))),
},
)*
_ => Ok(None),
}
}
}

impl wire::Type for $message {
fn type_id(&self) -> u16 {
match self {
$(
Self::$variant(message) => message.type_id(),
)*
}
}
}

impl Writeable for $message {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
match self {
$(
Self::$variant(message) => message.write(writer),
)*
}
}
}
}
}

composite_custom_message_handler!(
pub struct CompositeMessageHandler {
ignoring: IgnoringMessageHandler,
ignoring2: IgnoringMessageHandler,
}

pub enum CompositeMessage {
Infallible(0..=0),
Infallible2(1..=10),
}
);

/// A dummy struct which implements `RoutingMessageHandler` without storing any routing information
/// or doing any processing. You can provide one of these as the route_handler in a MessageHandler.
#[derive(Debug)]
pub struct IgnoringMessageHandler{}
impl MessageSendEventsProvider for IgnoringMessageHandler {
fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> { Vec::new() }
Expand Down

0 comments on commit 75e4328

Please sign in to comment.