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

Commit 8cd4a4b

Browse files
authored
Merge pull request #58 from tnull/2023-11-modularize-more
2 parents d896909 + 9861f57 commit 8cd4a4b

File tree

25 files changed

+2570
-2036
lines changed

25 files changed

+2570
-2036
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ jobs:
3232
- name: Cargo check
3333
run: cargo check --release
3434
- name: Check documentation
35-
run: cargo doc --release
35+
run: |
36+
cargo doc --release
37+
cargo doc --no-default-features --features no-std
38+
RUSTFLAGS="--cfg lsps1" cargo doc --release
39+
RUSTFLAGS="--cfg lsps1" cargo doc --no-default-features --features no-std
3640
- name: Build on Rust ${{ matrix.toolchain }}
3741
run: cargo build --verbose --color always
3842
- name: Check formatting

src/events.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//!
1616
//! [`LiquidityManager::get_and_clear_pending_events`]: crate::LiquidityManager::get_and_clear_pending_events
1717
18+
use crate::lsps0;
1819
#[cfg(lsps1)]
1920
use crate::lsps1;
2021
use crate::lsps2;
@@ -78,9 +79,16 @@ impl EventQueue {
7879
/// An event which you should probably take some action in response to.
7980
#[derive(Debug, Clone, PartialEq, Eq)]
8081
pub enum Event {
81-
/// An LSPS2 (JIT Channel) protocol event.
82-
LSPS2(lsps2::LSPS2Event),
83-
/// An LSPS1 protocol event.
82+
/// An LSPS0 client event.
83+
LSPS0Client(lsps0::event::LSPS0ClientEvent),
84+
/// An LSPS1 (Channel Request) client event.
8485
#[cfg(lsps1)]
85-
LSPS1(lsps1::event::Event),
86+
LSPS1Client(lsps1::event::LSPS1ClientEvent),
87+
/// An LSPS1 (Channel Request) server event.
88+
#[cfg(lsps1)]
89+
LSPS1Service(lsps1::event::LSPS1ServiceEvent),
90+
/// An LSPS2 (JIT Channel) client event.
91+
LSPS2Client(lsps2::event::LSPS2ClientEvent),
92+
/// An LSPS2 (JIT Channel) server event.
93+
LSPS2Service(lsps2::event::LSPS2ServiceEvent),
8694
}

src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ mod prelude {
3939
}
4040

4141
pub mod events;
42-
mod lsps0;
42+
pub mod lsps0;
4343
#[cfg(lsps1)]
44-
mod lsps1;
44+
pub mod lsps1;
4545
pub mod lsps2;
46+
mod manager;
47+
pub mod message_queue;
4648
mod sync;
49+
#[cfg(test)]
50+
mod tests;
4751
mod utils;
4852

49-
pub use lsps0::message_handler::{JITChannelsConfig, LiquidityManager, LiquidityProviderConfig};
53+
pub use manager::{LiquidityClientConfig, LiquidityManager, LiquidityServiceConfig};

src/lsps0/client.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//! Contains the main LSPS2 client-side object, [`LSPS0ClientHandler`].
2+
//!
3+
//! Please refer to the [LSPS0
4+
//! specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0) for more
5+
//! information.
6+
7+
use crate::events::{Event, EventQueue};
8+
use crate::lsps0::event::LSPS0ClientEvent;
9+
use crate::lsps0::msgs::{
10+
LSPS0Message, LSPS0Request, LSPS0Response, ListProtocolsRequest, ListProtocolsResponse,
11+
ProtocolMessageHandler, ResponseError,
12+
};
13+
use crate::message_queue::MessageQueue;
14+
use crate::sync::Arc;
15+
use crate::utils;
16+
17+
use lightning::ln::msgs::{ErrorAction, LightningError};
18+
use lightning::sign::EntropySource;
19+
use lightning::util::logger::Level;
20+
21+
use bitcoin::secp256k1::PublicKey;
22+
23+
use core::ops::Deref;
24+
25+
/// A message handler capable of sending and handling LSPS0 messages.
26+
pub struct LSPS0ClientHandler<ES: Deref, MQ: Deref>
27+
where
28+
ES::Target: EntropySource,
29+
MQ::Target: MessageQueue,
30+
{
31+
entropy_source: ES,
32+
pending_messages: MQ,
33+
pending_events: Arc<EventQueue>,
34+
}
35+
36+
impl<ES: Deref, MQ: Deref> LSPS0ClientHandler<ES, MQ>
37+
where
38+
ES::Target: EntropySource,
39+
MQ::Target: MessageQueue,
40+
{
41+
/// Returns a new instance of [`LSPS0ClientHandler`].
42+
pub(crate) fn new(
43+
entropy_source: ES, pending_messages: MQ, pending_events: Arc<EventQueue>,
44+
) -> Self {
45+
Self { entropy_source, pending_messages, pending_events }
46+
}
47+
48+
/// Calls LSPS0's `list_protocols`.
49+
///
50+
/// Please refer to the [LSPS0
51+
/// specifcation](https://github.com/BitcoinAndLightningLayerSpecs/lsp/tree/main/LSPS0#lsps-specification-support-query)
52+
/// for more information.
53+
pub fn list_protocols(&self, counterparty_node_id: &PublicKey) {
54+
let msg = LSPS0Message::Request(
55+
utils::generate_request_id(&self.entropy_source),
56+
LSPS0Request::ListProtocols(ListProtocolsRequest {}),
57+
);
58+
59+
self.pending_messages.enqueue(counterparty_node_id, msg.into());
60+
}
61+
62+
fn handle_response(
63+
&self, response: LSPS0Response, counterparty_node_id: &PublicKey,
64+
) -> Result<(), LightningError> {
65+
match response {
66+
LSPS0Response::ListProtocols(ListProtocolsResponse { protocols }) => {
67+
self.pending_events.enqueue(Event::LSPS0Client(
68+
LSPS0ClientEvent::ListProtocolsResponse {
69+
counterparty_node_id: *counterparty_node_id,
70+
protocols,
71+
},
72+
));
73+
Ok(())
74+
}
75+
LSPS0Response::ListProtocolsError(ResponseError { code, message, data, .. }) => {
76+
Err(LightningError {
77+
err: format!(
78+
"ListProtocols error received. code = {}, message = {}, data = {:?}",
79+
code, message, data
80+
),
81+
action: ErrorAction::IgnoreAndLog(Level::Info),
82+
})
83+
}
84+
}
85+
}
86+
}
87+
88+
impl<ES: Deref, MQ: Deref> ProtocolMessageHandler for LSPS0ClientHandler<ES, MQ>
89+
where
90+
ES::Target: EntropySource,
91+
MQ::Target: MessageQueue,
92+
{
93+
type ProtocolMessage = LSPS0Message;
94+
const PROTOCOL_NUMBER: Option<u16> = None;
95+
96+
fn handle_message(
97+
&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
98+
) -> Result<(), LightningError> {
99+
match message {
100+
LSPS0Message::Response(_, response) => {
101+
self.handle_response(response, counterparty_node_id)
102+
}
103+
LSPS0Message::Request(..) => {
104+
debug_assert!(
105+
false,
106+
"Client handler received LSPS0 request message. This should never happen."
107+
);
108+
Err(LightningError { err: format!("Client handler received LSPS0 request message from node {:?}. This should never happen.", counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)})
109+
}
110+
}
111+
}
112+
}
113+
114+
#[cfg(test)]
115+
mod tests {
116+
117+
use alloc::string::ToString;
118+
use alloc::sync::Arc;
119+
120+
use crate::lsps0::msgs::{LSPSMessage, RequestId};
121+
use crate::tests::utils::{TestEntropy, TestMessageQueue};
122+
123+
use super::*;
124+
125+
#[test]
126+
fn test_list_protocols() {
127+
let pending_messages = Arc::new(TestMessageQueue::new());
128+
let entropy_source = Arc::new(TestEntropy {});
129+
let event_queue = Arc::new(EventQueue::new());
130+
131+
let lsps0_handler = Arc::new(LSPS0ClientHandler::new(
132+
entropy_source,
133+
Arc::clone(&pending_messages),
134+
event_queue,
135+
));
136+
137+
let counterparty_node_id = utils::parse_pubkey(
138+
"027100442c3b79f606f80f322d98d499eefcb060599efc5d4ecb00209c2cb54190",
139+
)
140+
.unwrap();
141+
142+
lsps0_handler.list_protocols(&counterparty_node_id);
143+
let pending_messages = pending_messages.get_and_clear_pending_msgs();
144+
145+
assert_eq!(pending_messages.len(), 1);
146+
147+
let (pubkey, message) = &pending_messages[0];
148+
149+
assert_eq!(*pubkey, counterparty_node_id);
150+
assert_eq!(
151+
*message,
152+
LSPSMessage::LSPS0(LSPS0Message::Request(
153+
RequestId("00000000000000000000000000000000".to_string()),
154+
LSPS0Request::ListProtocols(ListProtocolsRequest {})
155+
))
156+
);
157+
}
158+
}

src/lsps0/event.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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 LSPS0 event types
11+
12+
use crate::prelude::Vec;
13+
use bitcoin::secp256k1::PublicKey;
14+
15+
/// An event which an LSPS0 client may want to take some action in response to.
16+
#[derive(Clone, Debug, PartialEq, Eq)]
17+
pub enum LSPS0ClientEvent {
18+
/// Information from the LSP about the protocols they support.
19+
ListProtocolsResponse {
20+
/// The node id of the LSP.
21+
counterparty_node_id: PublicKey,
22+
/// A list of supported protocols.
23+
protocols: Vec<u16>,
24+
},
25+
}

0 commit comments

Comments
 (0)