Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit bd49cce

Browse files
refactor to remove generic message handlers
Simpler model where we have fixed set of protocol message handlers with shared message and event queues.
1 parent 261beba commit bd49cce

File tree

8 files changed

+220
-265
lines changed

8 files changed

+220
-265
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ jobs:
3131
- name: Pin serde for MSRV
3232
if: matrix.msrv
3333
run: cargo update -p serde --precise "1.0.156" --verbose
34+
- name: Check documentation
35+
run: cargo check --release && cargo doc --release
3436
- name: Build on Rust ${{ matrix.toolchain }}
3537
run: cargo build --verbose --color always
3638
- name: Check formatting

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ description = "Types and primitives to integrate a spec-compliant LSP with an LD
88
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
99

1010
[dependencies]
11-
lightning = { version = "0.0.114", features = ["max_level_trace", "std"] }
12-
lightning-invoice = { version = "0.22" }
13-
lightning-net-tokio = { version = "0.0.114" }
11+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "498f2331459d8031031ef151a44c90d700aa8c7e", features = ["max_level_trace"] }
12+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "498f2331459d8031031ef151a44c90d700aa8c7e" }
13+
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "498f2331459d8031031ef151a44c90d700aa8c7e" }
1414

15-
bitcoin = "0.29.2"
15+
bitcoin = "0.29.0"
1616

17-
serde = { version = "1.0", features = ["derive"] }
17+
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] }
1818
serde_json = "1.0"

src/events.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1-
use bitcoin::secp256k1::PublicKey;
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
29

3-
pub trait EventHandler {
4-
fn handle_event(&self, event: Event);
5-
}
10+
//! Events are returned from various bits in the library which indicate some action must be taken
11+
//! by the client.
12+
//!
13+
//! Because we don't have a built-in runtime, it's up to the client to call events at a time in the
14+
//! future.
15+
use bitcoin::secp256k1::PublicKey;
616

17+
/// An Event which you should probably take some action in response to.
718
#[derive(Debug, Clone, PartialEq, Eq)]
819
pub enum Event {
9-
ListProtocols { counterparty_node_id: PublicKey, protocols: Vec<u16> },
20+
/// A response to a ListProtocols request that informs the caller
21+
/// what protocols a particular node supports.
22+
ListProtocols {
23+
/// The counterparty's node_id that identifies the node.
24+
counterparty_node_id: PublicKey,
25+
/// The list of protocol numbers that are supported.
26+
protocols: Vec<u16>,
27+
},
1028
}

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2020

2121
mod channel_request;
22-
mod events;
22+
pub mod events;
2323
mod jit_channel;
2424
mod transport;
2525
mod utils;
26+
27+
pub use transport::message_handler::{LSPConfig, LSPManager};

src/transport/message_handler.rs

Lines changed: 89 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,131 @@
1-
use crate::events::{Event, EventHandler};
2-
use crate::transport::msgs::{LSPSMessage, Prefix, RawLSPSMessage, LSPS_MESSAGE_TYPE};
1+
use crate::events::Event;
2+
use crate::transport::msgs::{LSPSMessage, RawLSPSMessage, LSPS_MESSAGE_TYPE};
3+
use crate::transport::protocol::LSPS0MessageHandler;
4+
35
use bitcoin::secp256k1::PublicKey;
6+
use lightning::ln::features::{InitFeatures, NodeFeatures};
47
use lightning::ln::peer_handler::CustomMessageHandler;
58
use lightning::ln::wire::CustomMessageReader;
69
use lightning::log_info;
10+
use lightning::sign::EntropySource;
711
use lightning::util::logger::Logger;
12+
use lightning::util::ser::Readable;
813
use std::collections::HashMap;
9-
use std::convert::{TryFrom, TryInto};
14+
use std::convert::TryFrom;
1015
use std::io;
1116
use std::ops::Deref;
1217
use std::sync::{Arc, Mutex};
1318

19+
const LSPS_FEATURE_BIT: usize = 729;
20+
1421
/// A trait used to implement a specific LSPS protocol
1522
/// The messages the protocol uses need to be able to be mapped
1623
/// from and into LSPSMessages.
17-
pub trait ProtocolMessageHandler {
24+
pub(crate) trait ProtocolMessageHandler {
1825
type ProtocolMessage: TryFrom<LSPSMessage> + Into<LSPSMessage>;
1926
const PROTOCOL_NUMBER: Option<u16>;
2027

2128
fn handle_message(
2229
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
2330
) -> Result<(), lightning::ln::msgs::LightningError>;
24-
fn get_and_clear_pending_protocol_messages(&self) -> Vec<(PublicKey, Self::ProtocolMessage)>;
25-
fn get_and_clear_pending_protocol_events(&self) -> Vec<Event>;
26-
fn get_protocol_number(&self) -> Option<u16> {
27-
Self::PROTOCOL_NUMBER
28-
}
2931
}
3032

31-
/// A trait used to implement the mapping from a LSPS transport layer mesage
32-
/// to a specific protocol message. This enables the ProtocolMessageHandler's
33-
/// to not need to know about LSPSMessage and only have to deal with the specific
34-
/// messages related to the protocol that is being implemented.
35-
pub trait TransportMessageHandler {
36-
fn handle_lsps_message(
37-
&self, message: LSPSMessage, counterparty_node_id: &PublicKey,
38-
) -> Result<(), lightning::ln::msgs::LightningError>;
39-
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, LSPSMessage)>;
40-
fn get_and_clear_pending_events(&self) -> Vec<Event>;
41-
fn get_protocol_number(&self) -> Option<u16>;
33+
/// Configuration for the LSPManager
34+
/// Allows end-user to configure the behavior of the client
35+
pub struct LSPConfig {
36+
/// whether or not you intend to provide services
37+
is_lsp: bool,
4238
}
4339

44-
impl<T> TransportMessageHandler for T
45-
where
46-
T: ProtocolMessageHandler,
47-
LSPSMessage: TryInto<<T as ProtocolMessageHandler>::ProtocolMessage>,
48-
{
49-
fn handle_lsps_message(
50-
&self, message: LSPSMessage, counterparty_node_id: &PublicKey,
51-
) -> Result<(), lightning::ln::msgs::LightningError> {
52-
if let Ok(protocol_message) = message.try_into() {
53-
self.handle_message(protocol_message, counterparty_node_id)?;
54-
}
55-
56-
Ok(())
57-
}
58-
59-
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, LSPSMessage)> {
60-
self.get_and_clear_pending_protocol_messages()
61-
.into_iter()
62-
.map(|(public_key, protocol_message)| (public_key, protocol_message.into()))
63-
.collect()
64-
}
65-
66-
fn get_and_clear_pending_events(&self) -> Vec<Event> {
67-
self.get_and_clear_pending_protocol_events()
68-
}
69-
70-
fn get_protocol_number(&self) -> Option<u16> {
71-
self.get_protocol_number()
72-
}
73-
}
74-
75-
pub struct LSPManager<L: Deref>
40+
/// The main interface into LSP functionality
41+
pub struct LSPManager<L: Deref, ES: Deref>
7642
where
7743
L::Target: Logger,
44+
ES::Target: EntropySource,
7845
{
7946
logger: L,
80-
pending_messages: Mutex<Vec<(PublicKey, RawLSPSMessage)>>,
47+
pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
48+
pending_events: Arc<Mutex<Vec<Event>>>,
8149
request_id_to_method_map: Mutex<HashMap<String, String>>,
82-
message_handlers: Arc<Mutex<HashMap<Prefix, Arc<dyn TransportMessageHandler>>>>,
50+
lsps0_message_handler: LSPS0MessageHandler<ES>,
51+
config: LSPConfig,
8352
}
8453

85-
impl<L: Deref> LSPManager<L>
54+
impl<L: Deref, ES: Deref> LSPManager<L, ES>
8655
where
8756
L::Target: Logger,
57+
ES::Target: EntropySource,
8858
{
89-
pub fn new(logger: L) -> Self {
59+
/// Constructor for the LSPManager
60+
///
61+
/// Sets up all required protocol message handlers based on configuration passed in
62+
pub fn new(logger: L, entropy_source: ES, config: LSPConfig) -> Self {
63+
let pending_messages = Arc::new(Mutex::new(vec![]));
64+
let pending_events = Arc::new(Mutex::new(vec![]));
65+
66+
let lsps0_message_handler = LSPS0MessageHandler::new(
67+
entropy_source,
68+
vec![],
69+
pending_messages.clone(),
70+
pending_events.clone(),
71+
);
72+
9073
Self {
9174
logger,
92-
pending_messages: Mutex::new(Vec::new()),
75+
pending_messages,
76+
pending_events,
9377
request_id_to_method_map: Mutex::new(HashMap::new()),
94-
message_handlers: Arc::new(Mutex::new(HashMap::new())),
78+
lsps0_message_handler,
79+
config,
9580
}
9681
}
9782

98-
pub fn get_message_handlers(
99-
&self,
100-
) -> Arc<Mutex<HashMap<Prefix, Arc<dyn TransportMessageHandler>>>> {
101-
self.message_handlers.clone()
102-
}
103-
104-
pub fn register_message_handler(
105-
&self, prefix: Prefix, message_handler: Arc<dyn TransportMessageHandler>,
106-
) {
107-
self.message_handlers.lock().unwrap().insert(prefix, message_handler);
108-
}
109-
110-
pub fn process_pending_events<H: EventHandler>(&self, handler: H) {
111-
let message_handlers = self.message_handlers.lock().unwrap();
112-
113-
for message_handler in message_handlers.values() {
114-
let events = message_handler.get_and_clear_pending_events();
115-
for event in events {
116-
handler.handle_event(event);
117-
}
118-
}
83+
/// Needs to be polled regularly to surface events generated by the various protocols
84+
pub fn get_and_clear_pending_events(&self) -> Vec<Event> {
85+
self.pending_events.lock().unwrap().drain(..).collect()
11986
}
12087

12188
fn handle_lsps_message(
12289
&self, msg: LSPSMessage, sender_node_id: &PublicKey,
12390
) -> Result<(), lightning::ln::msgs::LightningError> {
124-
if let Some(prefix) = msg.prefix() {
125-
let message_handlers = self.message_handlers.lock().unwrap();
126-
// TODO: not sure what we are supposed to do when we receive a message we don't have a handler for
127-
if let Some(message_handler) = message_handlers.get(&prefix) {
128-
message_handler.handle_lsps_message(msg, sender_node_id)?;
129-
} else {
130-
log_info!(
131-
self.logger,
132-
"Received a message from {:?} we do not have a handler for: {:?}",
133-
sender_node_id,
134-
msg
135-
);
91+
match msg {
92+
LSPSMessage::Invalid => {
93+
log_info!(self.logger, "Received invalid message from {:?}", sender_node_id);
94+
}
95+
LSPSMessage::LSPS0(msg) => {
96+
self.lsps0_message_handler.handle_message(msg, sender_node_id)?;
13697
}
13798
}
13899
Ok(())
139100
}
140101

141-
fn enqueue_message(&self, node_id: PublicKey, msg: RawLSPSMessage) {
102+
fn enqueue_message(&self, node_id: PublicKey, msg: LSPSMessage) {
142103
let mut pending_msgs = self.pending_messages.lock().unwrap();
143104
pending_msgs.push((node_id, msg));
144105
}
145106
}
146107

147-
impl<L: Deref> CustomMessageReader for LSPManager<L>
108+
impl<L: Deref, ES: Deref> CustomMessageReader for LSPManager<L, ES>
148109
where
149110
L::Target: Logger,
111+
ES::Target: EntropySource,
150112
{
151113
type CustomMessage = RawLSPSMessage;
152114

153115
fn read<R: io::Read>(
154116
&self, message_type: u16, buffer: &mut R,
155117
) -> Result<Option<Self::CustomMessage>, lightning::ln::msgs::DecodeError> {
156118
match message_type {
157-
LSPS_MESSAGE_TYPE => {
158-
let mut payload = String::new();
159-
buffer.read_to_string(&mut payload)?;
160-
Ok(Some(RawLSPSMessage { payload }))
161-
}
119+
LSPS_MESSAGE_TYPE => Ok(Some(RawLSPSMessage::read(buffer)?)),
162120
_ => Ok(None),
163121
}
164122
}
165123
}
166124

167-
impl<L: Deref> CustomMessageHandler for LSPManager<L>
125+
impl<L: Deref, ES: Deref> CustomMessageHandler for LSPManager<L, ES>
168126
where
169127
L::Target: Logger,
128+
ES::Target: EntropySource,
170129
{
171130
fn handle_custom_message(
172131
&self, msg: Self::CustomMessage, sender_node_id: &PublicKey,
@@ -176,35 +135,47 @@ where
176135
match LSPSMessage::from_str_with_id_map(&msg.payload, &mut request_id_to_method_map) {
177136
Ok(msg) => self.handle_lsps_message(msg, sender_node_id),
178137
Err(_) => {
179-
self.enqueue_message(
180-
*sender_node_id,
181-
RawLSPSMessage {
182-
payload: serde_json::to_string(&LSPSMessage::Invalid).unwrap(),
183-
},
184-
);
138+
self.enqueue_message(*sender_node_id, LSPSMessage::Invalid);
185139
Ok(())
186140
}
187141
}
188142
}
189143

190144
fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> {
191-
let mut msgs = vec![];
145+
let mut request_id_to_method_map = self.request_id_to_method_map.lock().unwrap();
146+
self.pending_messages
147+
.lock()
148+
.unwrap()
149+
.drain(..)
150+
.map(|(public_key, lsps_message)| {
151+
if let Some((request_id, method_name)) = lsps_message.get_request_id_and_method() {
152+
request_id_to_method_map.insert(request_id, method_name);
153+
}
154+
(
155+
public_key,
156+
RawLSPSMessage { payload: serde_json::to_string(&lsps_message).unwrap() },
157+
)
158+
})
159+
.collect()
160+
}
192161

193-
{
194-
let mut pending_messages = self.pending_messages.lock().unwrap();
195-
msgs.extend(
196-
pending_messages.drain(..).collect::<Vec<(PublicKey, Self::CustomMessage)>>(),
197-
);
162+
fn provided_node_features(&self) -> NodeFeatures {
163+
let mut features = NodeFeatures::empty();
164+
165+
if self.config.is_lsp {
166+
features.set_optional_custom_bit(LSPS_FEATURE_BIT).unwrap();
198167
}
199168

200-
let message_handlers = self.message_handlers.lock().unwrap();
201-
for message_handler in message_handlers.values() {
202-
let protocol_messages = message_handler.get_and_clear_pending_msg();
203-
msgs.extend(protocol_messages.into_iter().map(|(node_id, message)| {
204-
(node_id, RawLSPSMessage { payload: serde_json::to_string(&message).unwrap() })
205-
}));
169+
features
170+
}
171+
172+
fn provided_init_features(&self, _their_node_id: &PublicKey) -> InitFeatures {
173+
let mut features = InitFeatures::empty();
174+
175+
if self.config.is_lsp {
176+
features.set_optional_custom_bit(LSPS_FEATURE_BIT).unwrap();
206177
}
207178

208-
msgs
179+
features
209180
}
210181
}

0 commit comments

Comments
 (0)