19 个版本
新 0.0.124-beta | 2024 年 8 月 20 日 |
---|---|
0.0.123 | 2024 年 5 月 9 日 |
0.0.123-beta | 2024 年 4 月 19 日 |
0.0.121 | 2024 年 1 月 23 日 |
0.0.114 | 2023 年 3 月 4 日 |
#218 in 神奇豆子
89 每月下载量
7MB
113K SLoC
LDK 中支持自定义点对点消息的实用工具。
BOLT 1 规定了用于实验性或特定应用消息的自定义消息类型范围。虽然可以定义一个 CustomMessageHandler
来支持多种消息类型,但定义此类处理程序需要大量模板代码,且容易出错。
此 crate 提供了 composite_custom_message_handler
宏,用于轻松将预定义的自定义消息处理程序组合成一个处理程序。所得处理程序可以使用相同的宏进一步与其他自定义消息处理程序组合。
以下示例演示了定义一个 FooBarHandler
,用于组合对 Foo
和 Bar
消息的单独处理程序,并将其与对 Baz
消息的处理程序进一步组合。
# fn main() {} // Avoid #[macro_export] generating an in-function warning
# extern crate bitcoin;
extern crate lightning;
#[macro_use]
extern crate lightning_custom_message;
# use bitcoin::secp256k1::PublicKey;
# use lightning::io;
# use lightning::ln::msgs::{DecodeError, Init, LightningError};
# use lightning::ln::features::{InitFeatures, NodeFeatures};
use lightning::ln::peer_handler::CustomMessageHandler;
use lightning::ln::wire::{CustomMessageReader, self};
use lightning::util::ser::Writeable;
# use lightning::util::ser::Writer;
// 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 {
// ...
# fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
# unimplemented!()
# }
}
pub struct FooHandler;
impl CustomMessageReader for FooHandler {
// ...
# type CustomMessage = Foo;
# fn read<R: io::Read>(
# &self, _message_type: u16, _buffer: &mut R
# ) -> Result<Option<Self::CustomMessage>, DecodeError> {
# unimplemented!()
# }
}
impl CustomMessageHandler for FooHandler {
// ...
# fn handle_custom_message(
# &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
# ) -> Result<(), LightningError> {
# unimplemented!()
# }
# fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
# unimplemented!()
# }
# fn peer_disconnected(&self, _their_node_id: &PublicKey) {
# unimplemented!()
# }
# fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
# unimplemented!()
# }
# fn provided_node_features(&self) -> NodeFeatures {
# unimplemented!()
# }
# fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
# unimplemented!()
# }
}
#[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 {
// ...
# fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
# unimplemented!()
# }
}
pub struct BarHandler;
impl CustomMessageReader for BarHandler {
// ...
# type CustomMessage = Bar;
# fn read<R: io::Read>(
# &self, _message_type: u16, _buffer: &mut R
# ) -> Result<Option<Self::CustomMessage>, DecodeError> {
# unimplemented!()
# }
}
impl CustomMessageHandler for BarHandler {
// ...
# fn handle_custom_message(
# &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
# ) -> Result<(), LightningError> {
# unimplemented!()
# }
# fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
# unimplemented!()
# }
# fn peer_disconnected(&self, _their_node_id: &PublicKey) {
# unimplemented!()
# }
# fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
# unimplemented!()
# }
# fn provided_node_features(&self) -> NodeFeatures {
# unimplemented!()
# }
# fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
# unimplemented!()
# }
}
#[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 {
// ...
# fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
# unimplemented!()
# }
}
pub struct BazHandler;
impl CustomMessageReader for BazHandler {
// ...
# type CustomMessage = Baz;
# fn read<R: io::Read>(
# &self, _message_type: u16, _buffer: &mut R
# ) -> Result<Option<Self::CustomMessage>, DecodeError> {
# unimplemented!()
# }
}
impl CustomMessageHandler for BazHandler {
// ...
# fn handle_custom_message(
# &self, _msg: Self::CustomMessage, _sender_node_id: &PublicKey
# ) -> Result<(), LightningError> {
# unimplemented!()
# }
# fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
# unimplemented!()
# }
# fn peer_disconnected(&self, _their_node_id: &PublicKey) {
# unimplemented!()
# }
# fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &Init, _inbound: bool) -> Result<(), ()> {
# unimplemented!()
# }
# fn provided_node_features(&self) -> NodeFeatures {
# unimplemented!()
# }
# fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
# unimplemented!()
# }
}
// 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!() }
}
依赖关系
~7.5MB
~90K SLoC