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

Commit 332741f

Browse files
committed
Split LSPS0 in client/server handler modules
1 parent 83181ae commit 332741f

File tree

9 files changed

+207
-110
lines changed

9 files changed

+207
-110
lines changed

src/lsps0/message_handler.rs renamed to src/lsps0/client.rs

Lines changed: 20 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//! Contains the logic to handle LSPS0 protocol messages.
1+
//! Contains the main LSPS2 client-side object, [`LSPS0ClientHandler`].
22
//!
33
//! Please refer to the [LSPS0
44
//! specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0) for more
55
//! information.
66
77
use crate::lsps0::msgs::{
88
LSPS0Message, LSPS0Request, LSPS0Response, LSPSMessage, ListProtocolsRequest,
9-
ListProtocolsResponse, RequestId, ResponseError,
9+
ListProtocolsResponse, ProtocolMessageHandler, ResponseError,
1010
};
1111
use crate::prelude::Vec;
1212
use crate::sync::{Arc, Mutex};
@@ -20,39 +20,24 @@ use bitcoin::secp256k1::PublicKey;
2020

2121
use core::ops::Deref;
2222

23-
/// A trait used to implement a specific LSPS protocol.
24-
///
25-
/// The messages the protocol uses need to be able to be mapped
26-
/// from and into [`LSPSMessage`].
27-
pub(crate) trait ProtocolMessageHandler {
28-
type ProtocolMessage: TryFrom<LSPSMessage> + Into<LSPSMessage>;
29-
const PROTOCOL_NUMBER: Option<u16>;
30-
31-
fn handle_message(
32-
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
33-
) -> Result<(), LightningError>;
34-
}
35-
3623
/// A message handler capable of sending and handling LSPS0 messages.
37-
pub struct LSPS0MessageHandler<ES: Deref>
24+
pub struct LSPS0ClientHandler<ES: Deref>
3825
where
3926
ES::Target: EntropySource,
4027
{
4128
entropy_source: ES,
4229
pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
43-
protocols: Vec<u16>,
4430
}
4531

46-
impl<ES: Deref> LSPS0MessageHandler<ES>
32+
impl<ES: Deref> LSPS0ClientHandler<ES>
4733
where
4834
ES::Target: EntropySource,
4935
{
50-
/// Returns a new instance of [`LSPS0MessageHandler`].
51-
pub fn new(
52-
entropy_source: ES, protocols: Vec<u16>,
53-
pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
36+
/// Returns a new instance of [`LSPS0ClientHandler`].
37+
pub(crate) fn new(
38+
entropy_source: ES, pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
5439
) -> Self {
55-
Self { entropy_source, protocols, pending_messages }
40+
Self { entropy_source, pending_messages }
5641
}
5742

5843
/// Calls LSPS0's `list_protocols`.
@@ -73,23 +58,6 @@ where
7358
self.pending_messages.lock().unwrap().push((counterparty_node_id, message.into()));
7459
}
7560

76-
fn handle_request(
77-
&self, request_id: RequestId, request: LSPS0Request, counterparty_node_id: &PublicKey,
78-
) -> Result<(), lightning::ln::msgs::LightningError> {
79-
match request {
80-
LSPS0Request::ListProtocols(_) => {
81-
let msg = LSPS0Message::Response(
82-
request_id,
83-
LSPS0Response::ListProtocols(ListProtocolsResponse {
84-
protocols: self.protocols.clone(),
85-
}),
86-
);
87-
self.enqueue_message(*counterparty_node_id, msg);
88-
Ok(())
89-
}
90-
}
91-
}
92-
9361
fn handle_response(
9462
&self, response: LSPS0Response, _counterparty_node_id: &PublicKey,
9563
) -> Result<(), LightningError> {
@@ -108,7 +76,7 @@ where
10876
}
10977
}
11078

111-
impl<ES: Deref> ProtocolMessageHandler for LSPS0MessageHandler<ES>
79+
impl<ES: Deref> ProtocolMessageHandler for LSPS0ClientHandler<ES>
11280
where
11381
ES::Target: EntropySource,
11482
{
@@ -119,12 +87,16 @@ where
11987
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
12088
) -> Result<(), LightningError> {
12189
match message {
122-
LSPS0Message::Request(request_id, request) => {
123-
self.handle_request(request_id, request, counterparty_node_id)
124-
}
12590
LSPS0Message::Response(_, response) => {
12691
self.handle_response(response, counterparty_node_id)
12792
}
93+
LSPS0Message::Request(..) => {
94+
debug_assert!(
95+
false,
96+
"Client handler received LSPS0 request message. This should never happen."
97+
);
98+
Err(LightningError { err: format!("Client handler received LSPS0 request message from node {:?}. This should never happen.", counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)})
99+
}
128100
}
129101
}
130102
}
@@ -135,6 +107,8 @@ mod tests {
135107
use alloc::string::ToString;
136108
use alloc::sync::Arc;
137109

110+
use crate::lsps0::msgs::RequestId;
111+
138112
use super::*;
139113

140114
struct TestEntropy {}
@@ -144,50 +118,12 @@ mod tests {
144118
}
145119
}
146120

147-
#[test]
148-
fn test_handle_list_protocols_request() {
149-
let entropy = Arc::new(TestEntropy {});
150-
let protocols: Vec<u16> = vec![];
151-
let pending_messages = Arc::new(Mutex::new(vec![]));
152-
153-
let lsps0_handler =
154-
Arc::new(LSPS0MessageHandler::new(entropy, protocols, pending_messages.clone()));
155-
156-
let list_protocols_request = LSPS0Message::Request(
157-
RequestId("xyz123".to_string()),
158-
LSPS0Request::ListProtocols(ListProtocolsRequest {}),
159-
);
160-
let counterparty_node_id = utils::parse_pubkey(
161-
"027100442c3b79f606f80f322d98d499eefcb060599efc5d4ecb00209c2cb54190",
162-
)
163-
.unwrap();
164-
165-
lsps0_handler.handle_message(list_protocols_request, &counterparty_node_id).unwrap();
166-
let pending_messages = pending_messages.lock().unwrap();
167-
168-
assert_eq!(pending_messages.len(), 1);
169-
170-
let (pubkey, message) = &pending_messages[0];
171-
172-
assert_eq!(*pubkey, counterparty_node_id);
173-
assert_eq!(
174-
*message,
175-
LSPSMessage::LSPS0(LSPS0Message::Response(
176-
RequestId("xyz123".to_string()),
177-
LSPS0Response::ListProtocols(ListProtocolsResponse { protocols: vec![] })
178-
))
179-
);
180-
}
181-
182121
#[test]
183122
fn test_list_protocols() {
184123
let pending_messages = Arc::new(Mutex::new(vec![]));
185124

186-
let lsps0_handler = Arc::new(LSPS0MessageHandler::new(
187-
Arc::new(TestEntropy {}),
188-
vec![1, 2, 3],
189-
pending_messages.clone(),
190-
));
125+
let lsps0_handler =
126+
Arc::new(LSPS0ClientHandler::new(Arc::new(TestEntropy {}), pending_messages.clone()));
191127

192128
let counterparty_node_id = utils::parse_pubkey(
193129
"027100442c3b79f606f80f322d98d499eefcb060599efc5d4ecb00209c2cb54190",

src/lsps0/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99

1010
//! Types and primitives that implement the LSPS0: Transport Layer specification.
1111
12-
pub mod message_handler;
12+
pub mod client;
1313
pub mod msgs;
14+
pub mod service;

src/lsps0/msgs.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ use crate::lsps2::msgs::{
1414
use crate::prelude::{HashMap, String, ToString, Vec};
1515

1616
use lightning::impl_writeable_msg;
17+
use lightning::ln::msgs::LightningError;
1718
use lightning::ln::wire;
1819

20+
use bitcoin::secp256k1::PublicKey;
21+
1922
use serde::de;
2023
use serde::de::{MapAccess, Visitor};
2124
use serde::ser::SerializeStruct;
@@ -40,6 +43,19 @@ const LSPS0_LISTPROTOCOLS_METHOD_NAME: &str = "lsps0.list_protocols";
4043
/// The Lightning message type id for LSPS messages.
4144
pub const LSPS_MESSAGE_TYPE_ID: u16 = 37913;
4245

46+
/// A trait used to implement a specific LSPS protocol.
47+
///
48+
/// The messages the protocol uses need to be able to be mapped
49+
/// from and into [`LSPSMessage`].
50+
pub(crate) trait ProtocolMessageHandler {
51+
type ProtocolMessage: TryFrom<LSPSMessage> + Into<LSPSMessage>;
52+
const PROTOCOL_NUMBER: Option<u16>;
53+
54+
fn handle_message(
55+
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
56+
) -> Result<(), LightningError>;
57+
}
58+
4359
/// Lightning message type used by LSPS protocols.
4460
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
4561
pub struct RawLSPSMessage {

src/lsps0/service.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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.
9+
10+
//! Contains the main LSPS0 server-side object, [`LSPS0ServiceHandler`].
11+
//!
12+
//! Please refer to the [LSPS0
13+
//! specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0) for more
14+
//! information.
15+
16+
use crate::lsps0::msgs::{
17+
LSPS0Message, LSPS0Request, LSPS0Response, LSPSMessage, ListProtocolsResponse,
18+
ProtocolMessageHandler, RequestId,
19+
};
20+
use crate::prelude::Vec;
21+
use crate::sync::{Arc, Mutex};
22+
23+
use lightning::ln::msgs::{ErrorAction, LightningError};
24+
use lightning::util::logger::Level;
25+
26+
use bitcoin::secp256k1::PublicKey;
27+
28+
/// The main server-side object allowing to send and receive LSPS0 messages.
29+
pub struct LSPS0ServiceHandler {
30+
pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
31+
protocols: Vec<u16>,
32+
}
33+
34+
impl LSPS0ServiceHandler {
35+
/// Returns a new instance of [`LSPS0ServiceHandler`].
36+
pub(crate) fn new(
37+
protocols: Vec<u16>, pending_messages: Arc<Mutex<Vec<(PublicKey, LSPSMessage)>>>,
38+
) -> Self {
39+
Self { protocols, pending_messages }
40+
}
41+
42+
fn enqueue_message(&self, counterparty_node_id: PublicKey, message: LSPS0Message) {
43+
self.pending_messages.lock().unwrap().push((counterparty_node_id, message.into()));
44+
}
45+
46+
fn handle_request(
47+
&self, request_id: RequestId, request: LSPS0Request, counterparty_node_id: &PublicKey,
48+
) -> Result<(), lightning::ln::msgs::LightningError> {
49+
match request {
50+
LSPS0Request::ListProtocols(_) => {
51+
let msg = LSPS0Message::Response(
52+
request_id,
53+
LSPS0Response::ListProtocols(ListProtocolsResponse {
54+
protocols: self.protocols.clone(),
55+
}),
56+
);
57+
self.enqueue_message(*counterparty_node_id, msg);
58+
Ok(())
59+
}
60+
}
61+
}
62+
}
63+
64+
impl ProtocolMessageHandler for LSPS0ServiceHandler {
65+
type ProtocolMessage = LSPS0Message;
66+
const PROTOCOL_NUMBER: Option<u16> = None;
67+
68+
fn handle_message(
69+
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
70+
) -> Result<(), LightningError> {
71+
match message {
72+
LSPS0Message::Request(request_id, request) => {
73+
self.handle_request(request_id, request, counterparty_node_id)
74+
}
75+
LSPS0Message::Response(..) => {
76+
debug_assert!(
77+
false,
78+
"Service handler received LSPS0 response message. This should never happen."
79+
);
80+
Err(LightningError { err: format!("Service handler received LSPS0 response message from node {:?}. This should never happen.", counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)})
81+
}
82+
}
83+
}
84+
}
85+
86+
#[cfg(test)]
87+
mod tests {
88+
89+
use crate::lsps0::msgs::ListProtocolsRequest;
90+
use crate::utils;
91+
use alloc::string::ToString;
92+
use alloc::sync::Arc;
93+
94+
use super::*;
95+
96+
#[test]
97+
fn test_handle_list_protocols_request() {
98+
let protocols: Vec<u16> = vec![];
99+
let pending_messages = Arc::new(Mutex::new(vec![]));
100+
101+
let lsps0_handler = Arc::new(LSPS0ServiceHandler::new(protocols, pending_messages.clone()));
102+
103+
let list_protocols_request = LSPS0Message::Request(
104+
RequestId("xyz123".to_string()),
105+
LSPS0Request::ListProtocols(ListProtocolsRequest {}),
106+
);
107+
let counterparty_node_id = utils::parse_pubkey(
108+
"027100442c3b79f606f80f322d98d499eefcb060599efc5d4ecb00209c2cb54190",
109+
)
110+
.unwrap();
111+
112+
lsps0_handler.handle_message(list_protocols_request, &counterparty_node_id).unwrap();
113+
let pending_messages = pending_messages.lock().unwrap();
114+
115+
assert_eq!(pending_messages.len(), 1);
116+
117+
let (pubkey, message) = &pending_messages[0];
118+
119+
assert_eq!(*pubkey, counterparty_node_id);
120+
assert_eq!(
121+
*message,
122+
LSPSMessage::LSPS0(LSPS0Message::Response(
123+
RequestId("xyz123".to_string()),
124+
LSPS0Response::ListProtocols(ListProtocolsResponse { protocols: vec![] })
125+
))
126+
);
127+
}
128+
}

src/lsps1/client.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ use super::msgs::{
1818
use super::utils::is_valid;
1919

2020
use crate::events::EventQueue;
21-
use crate::lsps0::message_handler::ProtocolMessageHandler;
22-
use crate::lsps0::msgs::{LSPSMessage, RequestId};
21+
use crate::lsps0::msgs::{LSPSMessage, ProtocolMessageHandler, RequestId};
2322
use crate::prelude::{HashMap, String, ToString, Vec};
2423
use crate::sync::{Arc, Mutex, RwLock};
25-
use crate::utils;
2624
use crate::{events::Event, lsps0::msgs::ResponseError};
2725

2826
use lightning::chain::Filter;

src/lsps1/service.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ use super::msgs::{
1919
use super::utils::is_valid;
2020

2121
use crate::events::EventQueue;
22-
use crate::lsps0::message_handler::ProtocolMessageHandler;
23-
use crate::lsps0::msgs::{LSPSMessage, RequestId};
22+
use crate::lsps0::msgs::{LSPSMessage, ProtocolMessageHandler, RequestId};
2423
use crate::prelude::{HashMap, String, ToString, Vec};
2524
use crate::sync::{Arc, Mutex, RwLock};
2625
use crate::utils;

src/lsps2/client.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
//! Contains the main LSPS2 client object, [`LSPS2ClientHandler`].
1111
1212
use crate::events::EventQueue;
13-
use crate::lsps0::message_handler::ProtocolMessageHandler;
14-
use crate::lsps0::msgs::{LSPSMessage, RequestId};
13+
use crate::lsps0::msgs::{LSPSMessage, ProtocolMessageHandler, RequestId};
1514
use crate::lsps2::event::LSPS2ClientEvent;
1615
use crate::prelude::{HashMap, String, ToString, Vec};
1716
use crate::sync::{Arc, Mutex, RwLock};
18-
use crate::utils;
1917
use crate::{events::Event, lsps0::msgs::ResponseError};
2018

2119
use lightning::ln::msgs::{ErrorAction, LightningError};

src/lsps2/service.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
//! Contains the main LSPS2 server-side object, [`LSPS2ServiceHandler`].
1111
1212
use crate::events::EventQueue;
13-
use crate::lsps0::message_handler::ProtocolMessageHandler;
14-
use crate::lsps0::msgs::{LSPSMessage, RequestId};
13+
use crate::lsps0::msgs::{LSPSMessage, ProtocolMessageHandler, RequestId};
1514
use crate::lsps2::event::LSPS2ServiceEvent;
1615
use crate::lsps2::utils::{compute_opening_fee, is_valid_opening_fee_params};
1716
use crate::prelude::{HashMap, String, ToString, Vec};

0 commit comments

Comments
 (0)