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

Commit 1fbedb7

Browse files
expose lsps2 api in LiquidityManager
1 parent e3a6ee2 commit 1fbedb7

File tree

1 file changed

+178
-13
lines changed

1 file changed

+178
-13
lines changed

src/transport/message_handler.rs

Lines changed: 178 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
use crate::events::{Event, EventQueue};
22
use crate::jit_channel::channel_manager::JITChannelManager;
3+
use crate::jit_channel::msgs::{OpeningFeeParams, RawOpeningFeeParams};
4+
use crate::transport::msgs::RequestId;
35
use crate::transport::msgs::{LSPSMessage, RawLSPSMessage, LSPS_MESSAGE_TYPE_ID};
46
use crate::transport::protocol::LSPS0MessageHandler;
57

68
use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
79
use lightning::chain::{self, BestBlock, Confirm, Filter, Listen};
8-
use lightning::ln::channelmanager::{ChainParameters, ChannelManager};
10+
use lightning::ln::channelmanager::{ChainParameters, ChannelManager, InterceptId};
911
use lightning::ln::features::{InitFeatures, NodeFeatures};
1012
use lightning::ln::msgs::{
1113
ChannelMessageHandler, ErrorAction, LightningError, OnionMessageHandler, RoutingMessageHandler,
1214
};
13-
use lightning::ln::peer_handler::{CustomMessageHandler, SocketDescriptor};
15+
use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor};
1416
use lightning::ln::wire::CustomMessageReader;
17+
use lightning::ln::ChannelId;
1518
use lightning::routing::router::Router;
1619
use lightning::sign::{EntropySource, NodeSigner, SignerProvider};
20+
use lightning::util::errors::APIError;
1721
use lightning::util::logger::{Level, Logger};
1822
use lightning::util::ser::Readable;
1923

@@ -203,6 +207,165 @@ where {
203207
self.pending_events.get_and_clear_pending_events()
204208
}
205209

210+
/// Set a [`lightning::ln::peer_handler::PeerManager`] reference for the message handlers
211+
///
212+
/// This allows the message handlers to wake the [`lightning::ln::peer_handler::PeerManager`] by calling
213+
/// [`lightning::ln::peer_handler::PeerManager::process_events()`] after enqueing messages to be sent.
214+
///
215+
/// Without this the messages will be sent based on whatever polling interval
216+
/// your background processor uses.
217+
pub fn set_peer_manager(
218+
&self, peer_manager: Arc<PeerManager<Descriptor, CM, RM, OM, L, CMH, NS>>,
219+
) {
220+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
221+
lsps2_message_handler.set_peer_manager(peer_manager);
222+
}
223+
}
224+
225+
/// Initiate the creation of an invoice that when paid will open a channel
226+
/// with enough inbound liquidity to be able to receive the payment.
227+
///
228+
/// `counterparty_node_id` is the node_id of the LSP you would like to use.
229+
///
230+
/// if `payment_size_msat` is [`Option::Some`] then the invoice will be for a fixed amount
231+
/// and MPP can be used to pay it.
232+
///
233+
/// if `payment_size_msat` is [`Option::None`] then the invoice can be for an arbitrary amount
234+
/// but MPP can no longer be used to pay it.
235+
///
236+
/// `token` is an optional String that will be provided to the LSP.
237+
/// it can be used by the LSP as an API key, coupon code, or some other way to identify a user.
238+
pub fn create_invoice(
239+
&self, counterparty_node_id: PublicKey, payment_size_msat: Option<u64>,
240+
token: Option<String>, user_channel_id: u128,
241+
) -> Result<(), APIError> {
242+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
243+
lsps2_message_handler.create_invoice(
244+
counterparty_node_id,
245+
payment_size_msat,
246+
token,
247+
user_channel_id,
248+
);
249+
Ok(())
250+
} else {
251+
Err(APIError::APIMisuseError {
252+
err: "JIT Channels were not configured when LSPManager was instantiated"
253+
.to_string(),
254+
})
255+
}
256+
}
257+
258+
/// Used by LSP to provide fee parameters to a client requesting a JIT Channel.
259+
///
260+
/// Should be called in response to receiving a [`crate::JITChannelEvent::GetInfo`] event.
261+
pub fn opening_fee_params_generated(
262+
&self, counterparty_node_id: PublicKey, request_id: RequestId,
263+
opening_fee_params_menu: Vec<RawOpeningFeeParams>, min_payment_size_msat: u64,
264+
max_payment_size_msat: u64,
265+
) -> Result<(), APIError> {
266+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
267+
lsps2_message_handler.opening_fee_params_generated(
268+
counterparty_node_id,
269+
request_id,
270+
opening_fee_params_menu,
271+
min_payment_size_msat,
272+
max_payment_size_msat,
273+
)
274+
} else {
275+
Err(APIError::APIMisuseError {
276+
err: "JIT Channels were not configured when LSPManager was instantiated"
277+
.to_string(),
278+
})
279+
}
280+
}
281+
282+
/// Used by client to confirm which channel parameters to use for the JIT Channel buy request.
283+
///
284+
/// Should be called in response to receiving a [`crate::JITChannelEvent::GetInfoResponse`] event.
285+
pub fn opening_fee_params_selected(
286+
&self, counterparty_node_id: PublicKey, channel_id: u128,
287+
opening_fee_params: OpeningFeeParams,
288+
) -> Result<(), APIError> {
289+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
290+
lsps2_message_handler.opening_fee_params_selected(
291+
counterparty_node_id,
292+
channel_id,
293+
opening_fee_params,
294+
)
295+
} else {
296+
Err(APIError::APIMisuseError {
297+
err: "JIT Channels were not configured when LSPManager was instantiated"
298+
.to_string(),
299+
})
300+
}
301+
}
302+
303+
/// Used by LSP to provide client with the scid and cltv_expiry_delta to use in their invoice
304+
///
305+
/// Should be called in response to receiving a [`crate::JITChannelEvent::BuyRequest`] event.
306+
pub fn invoice_parameters_generated(
307+
&self, counterparty_node_id: PublicKey, request_id: RequestId, scid: u64,
308+
cltv_expiry_delta: u32, client_trusts_lsp: bool,
309+
) -> Result<(), APIError> {
310+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
311+
lsps2_message_handler.invoice_parameters_generated(
312+
counterparty_node_id,
313+
request_id,
314+
scid,
315+
cltv_expiry_delta,
316+
client_trusts_lsp,
317+
)
318+
} else {
319+
Err(APIError::APIMisuseError {
320+
err: "JIT Channels were not configured when LSPManager was instantiated"
321+
.to_string(),
322+
})
323+
}
324+
}
325+
326+
/// Forward [`lightning::events::Event::HTLCIntercepted`] event parameters into this function.
327+
///
328+
/// Will fail the intercepted HTLC if the scid matches a payment we are expecting
329+
/// but the payment amount is incorrect or the expiry has passed.
330+
///
331+
/// Will generate a [`crate::JITChannelEvent::OpenChannel`] event if the scid matches a payment we are expected
332+
/// and the payment amount is correct and the offer has not expired.
333+
///
334+
/// Will do nothing if the scid does not match any of the ones we gave out.
335+
pub fn htlc_intercepted(
336+
&self, scid: u64, intercept_id: InterceptId, inbound_amount_msat: u64,
337+
expected_outbound_amount_msat: u64,
338+
) -> Result<(), APIError> {
339+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
340+
lsps2_message_handler.htlc_intercepted(
341+
scid,
342+
intercept_id,
343+
inbound_amount_msat,
344+
expected_outbound_amount_msat,
345+
)?;
346+
}
347+
348+
Ok(())
349+
}
350+
351+
/// Forward [`lightning::events::Event::ChannelReady`] event parameters into this function.
352+
///
353+
/// Will forward the intercepted HTLC if it matches a channel
354+
/// we need to forward a payment over otherwise it will be ignored.
355+
pub fn channel_ready(
356+
&self, user_channel_id: u128, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
357+
) -> Result<(), APIError> {
358+
if let Some(lsps2_message_handler) = &self.lsps2_message_handler {
359+
lsps2_message_handler.channel_ready(
360+
user_channel_id,
361+
channel_id,
362+
counterparty_node_id,
363+
)?;
364+
}
365+
366+
Ok(())
367+
}
368+
206369
fn handle_lsps_message(
207370
&self, msg: LSPSMessage, sender_node_id: &PublicKey,
208371
) -> Result<(), lightning::ln::msgs::LightningError> {
@@ -213,15 +376,14 @@ where {
213376
LSPSMessage::LSPS0(msg) => {
214377
self.lsps0_message_handler.handle_message(msg, sender_node_id)?;
215378
}
216-
_ => {
217-
return Err(LightningError {
218-
err: format!(
219-
"Received message without message handler configured. From node = {:?}",
220-
sender_node_id
221-
),
222-
action: ErrorAction::IgnoreAndLog(Level::Info),
223-
});
224-
}
379+
LSPSMessage::LSPS2(msg) => match &self.lsps2_message_handler {
380+
Some(lsps2_message_handler) => {
381+
lsps2_message_handler.handle_message(msg, sender_node_id)?;
382+
}
383+
None => {
384+
return Err(LightningError { err: format!("Received LSPS2 message without LSPS2 message handler configured. From node = {:?}", sender_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)});
385+
}
386+
},
225387
}
226388
Ok(())
227389
}
@@ -311,9 +473,12 @@ where
311473
fn handle_custom_message(
312474
&self, msg: Self::CustomMessage, sender_node_id: &PublicKey,
313475
) -> Result<(), lightning::ln::msgs::LightningError> {
314-
let mut request_id_to_method_map = self.request_id_to_method_map.lock().unwrap();
476+
let message = {
477+
let mut request_id_to_method_map = self.request_id_to_method_map.lock().unwrap();
478+
LSPSMessage::from_str_with_id_map(&msg.payload, &mut request_id_to_method_map)
479+
};
315480

316-
match LSPSMessage::from_str_with_id_map(&msg.payload, &mut request_id_to_method_map) {
481+
match message {
317482
Ok(msg) => self.handle_lsps_message(msg, sender_node_id),
318483
Err(_) => {
319484
self.enqueue_message(*sender_node_id, LSPSMessage::Invalid);

0 commit comments

Comments
 (0)