@@ -15,15 +15,10 @@ use std::ops::Deref;
1515use std:: sync:: { Arc , Mutex , RwLock , Weak } ;
1616
1717use bitcoin:: secp256k1:: PublicKey ;
18- use chrono:: Utc ;
1918use lightning:: ln:: msgs:: SocketAddress ;
20- use lightning:: sign:: EntropySource ;
2119use lightning_liquidity:: events:: LiquidityEvent ;
22- use lightning_liquidity:: lsps0:: ser:: LSPSDateTime ;
2320use lightning_liquidity:: lsps1:: client:: LSPS1ClientConfig as LdkLSPS1ClientConfig ;
2421use lightning_liquidity:: lsps2:: client:: LSPS2ClientConfig as LdkLSPS2ClientConfig ;
25- use lightning_liquidity:: lsps2:: event:: LSPS2ServiceEvent ;
26- use lightning_liquidity:: lsps2:: msgs:: LSPS2RawOpeningFeeParams ;
2722use lightning_liquidity:: lsps2:: service:: LSPS2ServiceConfig as LdkLSPS2ServiceConfig ;
2823use lightning_liquidity:: { LiquidityClientConfig , LiquidityServiceConfig } ;
2924
@@ -32,15 +27,13 @@ use crate::logger::{log_error, LdkLogger};
3227use crate :: types:: {
3328 Broadcaster , ChannelManager , DynStore , KeysManager , LiquidityManager , PeerManager , Wallet ,
3429} ;
35- use crate :: { total_anchor_channels_reserve_sats , Config } ;
30+ use crate :: Config ;
3631
3732pub ( crate ) use client:: lsps1:: { LSPS1Client , LSPS1ClientConfig } ;
3833pub use client:: lsps1:: { LSPS1Liquidity , LSPS1OrderStatus } ;
3934pub ( crate ) use client:: lsps2:: { LSPS2Client , LSPS2ClientConfig } ;
35+ pub ( crate ) use service:: lsps2:: LSPS2Service ;
4036pub use service:: lsps2:: LSPS2ServiceConfig ;
41- pub ( crate ) use service:: lsps2:: {
42- LSPS2Service , LSPS2_CHANNEL_CLTV_EXPIRY_DELTA , LSPS2_GETINFO_REQUEST_EXPIRY ,
43- } ;
4437
4538pub ( crate ) const LIQUIDITY_REQUEST_TIMEOUT_SECS : u64 = 5 ;
4639
@@ -218,279 +211,22 @@ where
218211 log_error ! ( self . logger, "Received unexpected LSPS1Client event!" ) ;
219212 }
220213 } ,
221- LiquidityEvent :: LSPS2Service ( LSPS2ServiceEvent :: GetInfo {
222- request_id,
223- counterparty_node_id,
224- token,
225- } ) => {
226- if let Some ( lsps2_service_handler) =
227- self . liquidity_manager . lsps2_service_handler ( ) . as_ref ( )
228- {
229- let service_config = if let Some ( service_config) =
230- self . lsps2_service . as_ref ( ) . map ( |s| s. service_config . clone ( ) )
231- {
232- service_config
233- } else {
234- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
235- return ;
236- } ;
237-
238- if let Some ( required) = service_config. require_token {
239- if token != Some ( required) {
240- log_error ! (
241- self . logger,
242- "Rejecting LSPS2 request {:?} from counterparty {} as the client provided an invalid token." ,
243- request_id,
244- counterparty_node_id
245- ) ;
246- lsps2_service_handler. invalid_token_provided ( & counterparty_node_id, request_id. clone ( ) ) . unwrap_or_else ( |e| {
247- debug_assert ! ( false , "Failed to reject LSPS2 request. This should never happen." ) ;
248- log_error ! (
249- self . logger,
250- "Failed to reject LSPS2 request {:?} from counterparty {} due to: {:?}. This should never happen." ,
251- request_id,
252- counterparty_node_id,
253- e
254- ) ;
255- } ) ;
256- return ;
257- }
258- }
259-
260- let valid_until = LSPSDateTime ( Utc :: now ( ) + LSPS2_GETINFO_REQUEST_EXPIRY ) ;
261- let opening_fee_params = LSPS2RawOpeningFeeParams {
262- min_fee_msat : service_config. min_channel_opening_fee_msat ,
263- proportional : service_config. channel_opening_fee_ppm ,
264- valid_until,
265- min_lifetime : service_config. min_channel_lifetime ,
266- max_client_to_self_delay : service_config. max_client_to_self_delay ,
267- min_payment_size_msat : service_config. min_payment_size_msat ,
268- max_payment_size_msat : service_config. max_payment_size_msat ,
269- } ;
270-
271- let opening_fee_params_menu = vec ! [ opening_fee_params] ;
272-
273- if let Err ( e) = lsps2_service_handler. opening_fee_params_generated (
274- & counterparty_node_id,
275- request_id,
276- opening_fee_params_menu,
277- ) {
278- log_error ! (
279- self . logger,
280- "Failed to handle generated opening fee params: {:?}" ,
281- e
282- ) ;
283- }
284- } else {
285- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
286- return ;
287- }
288- } ,
289- LiquidityEvent :: LSPS2Service ( LSPS2ServiceEvent :: BuyRequest {
290- request_id,
291- counterparty_node_id,
292- opening_fee_params : _,
293- payment_size_msat,
294- } ) => {
295- if let Some ( lsps2_service_handler) =
296- self . liquidity_manager . lsps2_service_handler ( ) . as_ref ( )
297- {
298- let service_config = if let Some ( service_config) =
299- self . lsps2_service . as_ref ( ) . map ( |s| s. service_config . clone ( ) )
300- {
301- service_config
302- } else {
303- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
304- return ;
305- } ;
306-
307- let user_channel_id: u128 = u128:: from_ne_bytes (
308- self . keys_manager . get_secure_random_bytes ( ) [ ..16 ]
309- . try_into ( )
310- . expect ( "a 16-byte slice should convert into a [u8; 16]" ) ,
311- ) ;
312- let intercept_scid = self . channel_manager . get_intercept_scid ( ) ;
313-
314- if let Some ( payment_size_msat) = payment_size_msat {
315- // We already check this in `lightning-liquidity`, but better safe than
316- // sorry.
317- //
318- // TODO: We might want to eventually send back an error here, but we
319- // currently can't and have to trust `lightning-liquidity` is doing the
320- // right thing.
321- //
322- // TODO: Eventually we also might want to make sure that we have sufficient
323- // liquidity for the channel opening here.
324- if payment_size_msat > service_config. max_payment_size_msat
325- || payment_size_msat < service_config. min_payment_size_msat
326- {
327- log_error ! (
328- self . logger,
329- "Rejecting to handle LSPS2 buy request {:?} from counterparty {} as the client requested an invalid payment size." ,
330- request_id,
331- counterparty_node_id
332- ) ;
333- return ;
334- }
335- }
336-
337- match lsps2_service_handler
338- . invoice_parameters_generated (
339- & counterparty_node_id,
340- request_id,
341- intercept_scid,
342- LSPS2_CHANNEL_CLTV_EXPIRY_DELTA ,
343- service_config. client_trusts_lsp ,
344- user_channel_id,
214+ LiquidityEvent :: LSPS2Service ( event) => {
215+ if let Some ( lsps2_service) = self . lsps2_service . as_ref ( ) {
216+ lsps2_service
217+ . handle_next_event (
218+ event,
219+ & self . liquidity_manager ,
220+ & self . channel_manager ,
221+ & self . keys_manager ,
222+ & self . peer_manager ,
223+ & self . wallet ,
224+ & self . config ,
225+ & self . logger ,
345226 )
346- . await
347- {
348- Ok ( ( ) ) => { } ,
349- Err ( e) => {
350- log_error ! (
351- self . logger,
352- "Failed to provide invoice parameters: {:?}" ,
353- e
354- ) ;
355- return ;
356- } ,
357- }
358- } else {
359- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
360- return ;
361- }
362- } ,
363- LiquidityEvent :: LSPS2Service ( LSPS2ServiceEvent :: OpenChannel {
364- their_network_key,
365- amt_to_forward_msat,
366- opening_fee_msat : _,
367- user_channel_id,
368- intercept_scid : _,
369- } ) => {
370- if self . liquidity_manager . lsps2_service_handler ( ) . is_none ( ) {
371- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
372- return ;
373- } ;
374-
375- let service_config = if let Some ( service_config) =
376- self . lsps2_service . as_ref ( ) . map ( |s| s. service_config . clone ( ) )
377- {
378- service_config
227+ . await ;
379228 } else {
380229 log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as LSPS2 liquidity service was not configured." , ) ;
381- return ;
382- } ;
383-
384- let init_features = if let Some ( Some ( peer_manager) ) =
385- self . peer_manager . read ( ) . expect ( "lock" ) . as_ref ( ) . map ( |weak| weak. upgrade ( ) )
386- {
387- // Fail if we're not connected to the prospective channel partner.
388- if let Some ( peer) = peer_manager. peer_by_node_id ( & their_network_key) {
389- peer. init_features
390- } else {
391- // TODO: We just silently fail here. Eventually we will need to remember
392- // the pending requests and regularly retry opening the channel until we
393- // succeed.
394- log_error ! (
395- self . logger,
396- "Failed to open LSPS2 channel to {} due to peer not being not connected." ,
397- their_network_key,
398- ) ;
399- return ;
400- }
401- } else {
402- debug_assert ! ( false , "Failed to handle LSPS2ServiceEvent as peer manager isn't available. This should never happen." , ) ;
403- log_error ! ( self . logger, "Failed to handle LSPS2ServiceEvent as peer manager isn't available. This should never happen." , ) ;
404- return ;
405- } ;
406-
407- // Fail if we have insufficient onchain funds available.
408- let over_provisioning_msat = ( amt_to_forward_msat
409- * service_config. channel_over_provisioning_ppm as u64 )
410- / 1_000_000 ;
411- let channel_amount_sats = ( amt_to_forward_msat + over_provisioning_msat) / 1000 ;
412- let cur_anchor_reserve_sats =
413- total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
414- let spendable_amount_sats =
415- self . wallet . get_spendable_amount_sats ( cur_anchor_reserve_sats) . unwrap_or ( 0 ) ;
416- let required_funds_sats = channel_amount_sats
417- + self . config . anchor_channels_config . as_ref ( ) . map_or ( 0 , |c| {
418- if init_features. requires_anchors_zero_fee_htlc_tx ( )
419- && !c. trusted_peers_no_reserve . contains ( & their_network_key)
420- {
421- c. per_channel_reserve_sats
422- } else {
423- 0
424- }
425- } ) ;
426- if spendable_amount_sats < required_funds_sats {
427- log_error ! ( self . logger,
428- "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats" ,
429- spendable_amount_sats, channel_amount_sats
430- ) ;
431- // TODO: We just silently fail here. Eventually we will need to remember
432- // the pending requests and regularly retry opening the channel until we
433- // succeed.
434- return ;
435- }
436-
437- let mut config = self . channel_manager . get_current_config ( ) . clone ( ) ;
438-
439- // If we act as an LSPS2 service, the HTLC-value-in-flight must be 100% of the
440- // channel value to ensure we can forward the initial payment. That cap only
441- // applies to unannounced channels, so the channel must also be unannounced.
442- debug_assert_eq ! (
443- config
444- . channel_handshake_config
445- . unannounced_channel_max_inbound_htlc_value_in_flight_percentage,
446- 100
447- ) ;
448- debug_assert ! ( !config. channel_handshake_config. announce_for_forwarding) ;
449- debug_assert ! ( config. accept_forwards_to_priv_channels) ;
450-
451- // We set the forwarding fee to 0 for now as we're getting paid by the channel fee.
452- //
453- // TODO: revisit this decision eventually.
454- config. channel_config . forwarding_fee_base_msat = 0 ;
455- config. channel_config . forwarding_fee_proportional_millionths = 0 ;
456-
457- let result = if service_config. disable_client_reserve {
458- self . channel_manager . create_channel_to_trusted_peer_0reserve (
459- their_network_key,
460- channel_amount_sats,
461- 0 ,
462- user_channel_id,
463- None ,
464- Some ( config) ,
465- )
466- } else {
467- self . channel_manager . create_channel (
468- their_network_key,
469- channel_amount_sats,
470- 0 ,
471- user_channel_id,
472- None ,
473- Some ( config) ,
474- )
475- } ;
476-
477- match result {
478- Ok ( _) => { } ,
479- Err ( e) => {
480- // TODO: We just silently fail here. Eventually we will need to remember
481- // the pending requests and regularly retry opening the channel until we
482- // succeed.
483- let zero_reserve_string =
484- if service_config. disable_client_reserve { "0reserve " } else { "" } ;
485- log_error ! (
486- self . logger,
487- "Failed to open LSPS2 {}channel to {}: {:?}" ,
488- zero_reserve_string,
489- their_network_key,
490- e
491- ) ;
492- return ;
493- } ,
494230 }
495231 } ,
496232 LiquidityEvent :: LSPS2Client ( event) => {
0 commit comments