lightning_liquidity/lsps0/
service.rs

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 bLIP-50 / LSPS0 server-side object, [`LSPS0ServiceHandler`].
11//!
12//! Please refer to the [bLIP-50 / LSPS0
13//! specifcation](https://github.com/lightning/blips/blob/master/blip-0050.md) for more
14//! information.
15
16use alloc::vec::Vec;
17
18use crate::lsps0::msgs::{LSPS0ListProtocolsResponse, LSPS0Message, LSPS0Request, LSPS0Response};
19use crate::lsps0::ser::{LSPSProtocolMessageHandler, LSPSRequestId};
20use crate::message_queue::MessageQueue;
21use crate::sync::Arc;
22
23use lightning::ln::msgs::{ErrorAction, LightningError};
24use lightning::util::logger::Level;
25
26use bitcoin::secp256k1::PublicKey;
27
28/// The main server-side object allowing to send and receive bLIP-50 / LSPS0 messages.
29pub struct LSPS0ServiceHandler {
30	pending_messages: Arc<MessageQueue>,
31	protocols: Vec<u16>,
32}
33
34impl LSPS0ServiceHandler {
35	/// Returns a new instance of [`LSPS0ServiceHandler`].
36	pub(crate) fn new(protocols: Vec<u16>, pending_messages: Arc<MessageQueue>) -> Self {
37		Self { protocols, pending_messages }
38	}
39
40	fn handle_request(
41		&self, request_id: LSPSRequestId, request: LSPS0Request, counterparty_node_id: &PublicKey,
42	) -> Result<(), lightning::ln::msgs::LightningError> {
43		let mut message_queue_notifier = self.pending_messages.notifier();
44
45		match request {
46			LSPS0Request::ListProtocols(_) => {
47				let msg = LSPS0Message::Response(
48					request_id,
49					LSPS0Response::ListProtocols(LSPS0ListProtocolsResponse {
50						protocols: self.protocols.clone(),
51					}),
52				);
53				message_queue_notifier.enqueue(counterparty_node_id, msg.into());
54				Ok(())
55			},
56		}
57	}
58}
59
60impl LSPSProtocolMessageHandler for LSPS0ServiceHandler {
61	type ProtocolMessage = LSPS0Message;
62	const PROTOCOL_NUMBER: Option<u16> = None;
63
64	fn handle_message(
65		&self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
66	) -> Result<(), LightningError> {
67		match message {
68			LSPS0Message::Request(request_id, request) => {
69				self.handle_request(request_id, request, counterparty_node_id)
70			},
71			LSPS0Message::Response(..) => {
72				debug_assert!(
73					false,
74					"Service handler received LSPS0 response message. This should never happen."
75				);
76				Err(LightningError { err: format!("Service handler received LSPS0 response message from node {}. This should never happen.", counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)})
77			},
78		}
79	}
80}
81
82#[cfg(test)]
83mod tests {
84
85	use crate::lsps0::msgs::LSPS0ListProtocolsRequest;
86	use crate::lsps0::ser::LSPSMessage;
87	use crate::tests::utils;
88	use alloc::string::ToString;
89	use alloc::sync::Arc;
90	use lightning::util::wakers::Notifier;
91
92	use super::*;
93
94	#[test]
95	fn test_handle_list_protocols_request() {
96		let protocols: Vec<u16> = vec![];
97		let notifier = Arc::new(Notifier::new());
98		let pending_messages = Arc::new(MessageQueue::new(notifier));
99
100		let lsps0_handler =
101			Arc::new(LSPS0ServiceHandler::new(protocols, Arc::clone(&pending_messages)));
102
103		let list_protocols_request = LSPS0Message::Request(
104			LSPSRequestId("xyz123".to_string()),
105			LSPS0Request::ListProtocols(LSPS0ListProtocolsRequest {}),
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.get_and_clear_pending_msgs();
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				LSPSRequestId("xyz123".to_string()),
124				LSPS0Response::ListProtocols(LSPS0ListProtocolsResponse { protocols: vec![] })
125			))
126		);
127	}
128}