@@ -122,7 +122,7 @@ use types::{ChainMonitor, ChannelManager, KeysManager, NetworkGraph, PeerManager
122122pub use types:: { ChannelDetails , PeerDetails , UserChannelId } ;
123123use wallet:: Wallet ;
124124
125- use logger:: { log_debug , log_error, log_info, log_trace, FilesystemLogger , Logger } ;
125+ use logger:: { log_error, log_info, log_trace, FilesystemLogger , Logger } ;
126126
127127use lightning:: chain:: Confirm ;
128128use lightning:: ln:: channelmanager:: { self , PaymentId , RecipientOnionFields , Retry } ;
@@ -138,7 +138,7 @@ use lightning_background_processor::process_events_async;
138138
139139use lightning_transaction_sync:: EsploraSyncClient ;
140140
141- use lightning:: routing:: router:: { PaymentParameters , RouteParameters , Router as LdkRouter } ;
141+ use lightning:: routing:: router:: { PaymentParameters , RouteParameters } ;
142142use lightning_invoice:: { payment, Bolt11Invoice , Currency } ;
143143
144144use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
@@ -150,7 +150,6 @@ use bitcoin::{Address, Txid};
150150
151151use rand:: Rng ;
152152
153- use std:: collections:: HashMap ;
154153use std:: default:: Default ;
155154use std:: net:: ToSocketAddrs ;
156155use std:: sync:: { Arc , Mutex , RwLock } ;
@@ -295,7 +294,7 @@ pub struct Node<K: KVStore + Sync + Send + 'static> {
295294 gossip_source : Arc < GossipSource > ,
296295 kv_store : Arc < K > ,
297296 logger : Arc < FilesystemLogger > ,
298- router : Arc < Router > ,
297+ _router : Arc < Router > ,
299298 scorer : Arc < Mutex < Scorer > > ,
300299 peer_store : Arc < PeerStore < K , Arc < FilesystemLogger > > > ,
301300 payment_store : Arc < PaymentStore < K , Arc < FilesystemLogger > > > ,
@@ -1320,116 +1319,93 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13201319 /// payment. To mitigate this issue, channels with available liquidity less than the required
13211320 /// amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
13221321 /// pre-flight probes.
1323- pub fn send_payment_probe ( & self , invoice : & Bolt11Invoice ) -> Result < ( ) , Error > {
1322+ pub fn send_payment_probes ( & self , invoice : & Bolt11Invoice ) -> Result < ( ) , Error > {
13241323 let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
13251324 if rt_lock. is_none ( ) {
13261325 return Err ( Error :: NotRunning ) ;
13271326 }
13281327
1329- let amount_msat = if let Some ( invoice_amount_msat) = invoice. amount_milli_satoshis ( ) {
1330- invoice_amount_msat
1331- } else {
1332- log_error ! ( self . logger, "Failed to send probe as no amount was given in the invoice." ) ;
1333- return Err ( Error :: InvalidAmount ) ;
1334- } ;
1328+ let liquidity_limit_multiplier = Some ( self . config . probing_liquidity_limit_multiplier ) ;
13351329
1336- let expiry_time = invoice . duration_since_epoch ( ) . saturating_add ( invoice . expiry_time ( ) ) ;
1337- let mut payment_params = PaymentParameters :: from_node_id (
1338- invoice . recover_payee_pub_key ( ) ,
1339- invoice . min_final_cltv_expiry_delta ( ) as u32 ,
1330+ payment :: preflight_probe_invoice (
1331+ invoice ,
1332+ & * self . channel_manager ,
1333+ liquidity_limit_multiplier ,
13401334 )
1341- . with_expiry_time ( expiry_time. as_secs ( ) )
1342- . with_route_hints ( invoice. route_hints ( ) )
1343- . map_err ( |_| Error :: InvalidInvoice ) ?;
1344- if let Some ( features) = invoice. features ( ) {
1345- payment_params = payment_params
1346- . with_bolt11_features ( features. clone ( ) )
1347- . map_err ( |_| Error :: InvalidInvoice ) ?;
1348- }
1349- let route_params = RouteParameters { payment_params, final_value_msat : amount_msat } ;
1335+ . map_err ( |e| {
1336+ log_error ! ( self . logger, "Failed to send payment probes: {:?}" , e) ;
1337+ Error :: ProbeSendingFailed
1338+ } ) ?;
13501339
1351- self . send_payment_probe_internal ( route_params )
1340+ Ok ( ( ) )
13521341 }
13531342
13541343 /// Sends payment probes over all paths of a route that would be used to pay the given
13551344 /// amount to the given `node_id`.
13561345 ///
1357- /// This may be used to send "pre-flight" probes, i.e., to train our scorer before conducting
1358- /// the actual payment. Note this is only useful if there likely is sufficient time for the
1359- /// probe to settle before sending out the actual payment, e.g., when waiting for user
1360- /// confirmation in a wallet UI.
1361- ///
1362- /// Otherwise, there is a chance the probe could take up some liquidity needed to complete the
1363- /// actual payment. Users should therefore be cautious and might avoid sending probes if
1364- /// liquidity is scarce and/or they don't expect the probe to return before they send the
1365- /// payment. To mitigate this issue, channels with available liquidity less than the required
1366- /// amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
1367- /// pre-flight probes.
1368- pub fn send_spontaneous_payment_probe (
1346+ /// See [`Self::send_payment_probes`] for more information.
1347+ pub fn send_spontaneous_payment_probes (
13691348 & self , amount_msat : u64 , node_id : PublicKey ,
13701349 ) -> Result < ( ) , Error > {
13711350 let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
13721351 if rt_lock. is_none ( ) {
13731352 return Err ( Error :: NotRunning ) ;
13741353 }
13751354
1376- let payment_params =
1377- PaymentParameters :: from_node_id ( node_id, self . config . default_cltv_expiry_delta ) ;
1378-
1379- let route_params = RouteParameters { payment_params, final_value_msat : amount_msat } ;
1380-
1381- self . send_payment_probe_internal ( route_params)
1382- }
1383-
1384- fn send_payment_probe_internal ( & self , route_params : RouteParameters ) -> Result < ( ) , Error > {
1385- let payer = self . channel_manager . get_our_node_id ( ) ;
1386- let usable_channels = self . channel_manager . list_usable_channels ( ) ;
1387- let first_hops = usable_channels. iter ( ) . collect :: < Vec < _ > > ( ) ;
1388- let inflight_htlcs = self . channel_manager . compute_inflight_htlcs ( ) ;
1355+ let liquidity_limit_multiplier = Some ( self . config . probing_liquidity_limit_multiplier ) ;
1356+ let cltv_expiry_delta = self . config . default_cltv_expiry_delta ;
13891357
1390- let route = self
1391- . router
1392- . find_route ( & payer, & route_params, Some ( & first_hops) , inflight_htlcs)
1358+ self . channel_manager
1359+ . send_spontaneous_preflight_probes (
1360+ node_id,
1361+ amount_msat,
1362+ cltv_expiry_delta,
1363+ liquidity_limit_multiplier,
1364+ )
13931365 . map_err ( |e| {
1394- log_error ! ( self . logger, "Failed to find path for payment probe : {:?}" , e) ;
1366+ log_error ! ( self . logger, "Failed to send payment probes : {:?}" , e) ;
13951367 Error :: ProbeSendingFailed
13961368 } ) ?;
13971369
1398- let mut used_liquidity_map = HashMap :: with_capacity ( first_hops. len ( ) ) ;
1399- for path in route. paths {
1400- if path. hops . len ( ) + path. blinded_tail . as_ref ( ) . map_or ( 0 , |t| t. hops . len ( ) ) < 2 {
1401- log_debug ! (
1370+ Ok ( ( ) )
1371+ }
1372+
1373+ /// Sends payment probes over all paths of a route that would be used to pay the given
1374+ /// zero-value invoice using the given amount.
1375+ ///
1376+ /// This can be used to send pre-flight probes for a so-called "zero-amount" invoice, i.e., an
1377+ /// invoice that leaves the amount paid to be determined by the user.
1378+ ///
1379+ /// See [`Self::send_payment_probes`] for more information.
1380+ pub fn send_payment_probes_using_amount (
1381+ & self , invoice : & Bolt11Invoice , amount_msat : u64 ,
1382+ ) -> Result < ( ) , Error > {
1383+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1384+ if rt_lock. is_none ( ) {
1385+ return Err ( Error :: NotRunning ) ;
1386+ }
1387+
1388+ if let Some ( invoice_amount_msat) = invoice. amount_milli_satoshis ( ) {
1389+ if amount_msat < invoice_amount_msat {
1390+ log_error ! (
14021391 self . logger,
1403- "Skipped sending payment probe over path with less than two hops."
1404- ) ;
1405- continue ;
1392+ "Failed to send probes as the given amount needs to be at least the invoice amount: required {}msat, gave {}msat." , invoice_amount_msat, amount_msat) ;
1393+ return Err ( Error :: InvalidAmount ) ;
14061394 }
1395+ }
14071396
1408- if let Some ( first_path_hop) = path. hops . first ( ) {
1409- if let Some ( first_hop) = first_hops. iter ( ) . find ( |h| {
1410- h. get_outbound_payment_scid ( ) == Some ( first_path_hop. short_channel_id )
1411- } ) {
1412- let path_value = path. final_value_msat ( ) + path. fee_msat ( ) ;
1413- let used_liquidity =
1414- used_liquidity_map. entry ( first_path_hop. short_channel_id ) . or_insert ( 0 ) ;
1415-
1416- if first_hop. next_outbound_htlc_limit_msat
1417- < ( * used_liquidity + path_value)
1418- * self . config . probing_liquidity_limit_multiplier
1419- {
1420- log_debug ! ( self . logger, "Skipped sending payment probe to avoid putting channel {} under the liquidity limit." , first_path_hop. short_channel_id) ;
1421- continue ;
1422- } else {
1423- * used_liquidity += path_value;
1424- }
1425- }
1426- }
1397+ let liquidity_limit_multiplier = Some ( self . config . probing_liquidity_limit_multiplier ) ;
14271398
1428- self . channel_manager . send_probe ( path) . map_err ( |e| {
1429- log_error ! ( self . logger, "Failed to send payment probe: {:?}" , e) ;
1430- Error :: ProbeSendingFailed
1431- } ) ?;
1432- }
1399+ payment:: preflight_probe_zero_value_invoice (
1400+ invoice,
1401+ amount_msat,
1402+ & * self . channel_manager ,
1403+ liquidity_limit_multiplier,
1404+ )
1405+ . map_err ( |e| {
1406+ log_error ! ( self . logger, "Failed to send payment probes: {:?}" , e) ;
1407+ Error :: ProbeSendingFailed
1408+ } ) ?;
14331409
14341410 Ok ( ( ) )
14351411 }
0 commit comments