@@ -149,6 +149,7 @@ use bitcoin::{Address, Txid};
149149
150150use rand:: Rng ;
151151
152+ use std:: collections:: HashMap ;
152153use std:: default:: Default ;
153154use std:: net:: ToSocketAddrs ;
154155use std:: sync:: { Arc , Mutex , RwLock } ;
@@ -164,6 +165,7 @@ const DEFAULT_CLTV_EXPIRY_DELTA: u32 = 144;
164165const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS : u64 = 80 ;
165166const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS : u64 = 30 ;
166167const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS : u64 = 60 * 10 ;
168+ const DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER : u64 = 3 ;
167169const DEFAULT_LOG_LEVEL : LogLevel = LogLevel :: Debug ;
168170
169171// The 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
@@ -210,6 +212,7 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
210212/// | `wallet_sync_interval_secs` | 30 |
211213/// | `fee_rate_cache_update_interval_secs` | 600 |
212214/// | `trusted_peers_0conf` | [] |
215+ /// | `probing_liquidity_limit_multiplier` | 3 |
213216/// | `log_level` | Debug |
214217///
215218pub struct Config {
@@ -243,6 +246,11 @@ pub struct Config {
243246 /// funding transaction ends up never being confirmed on-chain. Zero-confirmation channels
244247 /// should therefore only be accepted from trusted peers.
245248 pub trusted_peers_0conf : Vec < PublicKey > ,
249+ /// The liquidity factor by which we filter the outgoing channels used for sending probes.
250+ ///
251+ /// Channels with available liquidity less than the required amount times this value won't be
252+ /// used to send pre-flight probes.
253+ pub probing_liquidity_limit_multiplier : u64 ,
246254 /// The level at which we log messages.
247255 ///
248256 /// Any messages below this level will be excluded from the logs.
@@ -261,6 +269,7 @@ impl Default for Config {
261269 wallet_sync_interval_secs : DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS ,
262270 fee_rate_cache_update_interval_secs : DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS ,
263271 trusted_peers_0conf : Vec :: new ( ) ,
272+ probing_liquidity_limit_multiplier : DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER ,
264273 log_level : DEFAULT_LOG_LEVEL ,
265274 }
266275 }
@@ -1302,10 +1311,14 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13021311 /// This may be used to send "pre-flight" probes, i.e., to train our scorer before conducting
13031312 /// the actual payment. Note this is only useful if there likely is sufficient time for the
13041313 /// probe to settle before sending out the actual payment, e.g., when waiting for user
1305- /// confirmation in a wallet UI. Otherwise, there is a chance the probe could take up some
1306- /// liquidity needed to complete the actual payment. Users should therefore be cautious and
1307- /// might avoid sending probes if liquidity is scarce and/or they don't expect the probe to
1308- /// return before they send the payment.
1314+ /// confirmation in a wallet UI.
1315+ ///
1316+ /// Otherwise, there is a chance the probe could take up some liquidity needed to complete the
1317+ /// actual payment. Users should therefore be cautious and might avoid sending probes if
1318+ /// liquidity is scarce and/or they don't expect the probe to return before they send the
1319+ /// payment. To mitigate this issue, channels with available liquidity less than the required
1320+ /// amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
1321+ /// pre-flight probes.
13091322 pub fn send_payment_probe ( & self , invoice : & Bolt11Invoice ) -> Result < ( ) , Error > {
13101323 let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
13111324 if rt_lock. is_none ( ) {
@@ -1343,10 +1356,14 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13431356 /// This may be used to send "pre-flight" probes, i.e., to train our scorer before conducting
13441357 /// the actual payment. Note this is only useful if there likely is sufficient time for the
13451358 /// probe to settle before sending out the actual payment, e.g., when waiting for user
1346- /// confirmation in a wallet UI. Otherwise, there is a chance the probe could take up some
1347- /// liquidity needed to complete the actual payment. Users should therefore be cautious and
1348- /// might avoid sending probes if liquidity is scarce and/or they don't expect the probe to
1349- /// return before they send the payment.
1359+ /// confirmation in a wallet UI.
1360+ ///
1361+ /// Otherwise, there is a chance the probe could take up some liquidity needed to complete the
1362+ /// actual payment. Users should therefore be cautious and might avoid sending probes if
1363+ /// liquidity is scarce and/or they don't expect the probe to return before they send the
1364+ /// payment. To mitigate this issue, channels with available liquidity less than the required
1365+ /// amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
1366+ /// pre-flight probes.
13501367 pub fn send_spontaneous_payment_probe (
13511368 & self , amount_msat : u64 , node_id : PublicKey ,
13521369 ) -> Result < ( ) , Error > {
@@ -1365,22 +1382,19 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13651382
13661383 fn send_payment_probe_internal ( & self , route_params : RouteParameters ) -> Result < ( ) , Error > {
13671384 let payer = self . channel_manager . get_our_node_id ( ) ;
1368- let first_hops = self . channel_manager . list_usable_channels ( ) ;
1385+ let usable_channels = self . channel_manager . list_usable_channels ( ) ;
1386+ let first_hops = usable_channels. iter ( ) . collect :: < Vec < _ > > ( ) ;
13691387 let inflight_htlcs = self . channel_manager . compute_inflight_htlcs ( ) ;
13701388
13711389 let route = self
13721390 . router
1373- . find_route (
1374- & payer,
1375- & route_params,
1376- Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) ,
1377- inflight_htlcs,
1378- )
1391+ . find_route ( & payer, & route_params, Some ( & first_hops) , inflight_htlcs)
13791392 . map_err ( |e| {
13801393 log_error ! ( self . logger, "Failed to find path for payment probe: {:?}" , e) ;
13811394 Error :: ProbeSendingFailed
13821395 } ) ?;
13831396
1397+ let mut used_liquidity_map = HashMap :: with_capacity ( first_hops. len ( ) ) ;
13841398 for path in route. paths {
13851399 if path. hops . len ( ) + path. blinded_tail . as_ref ( ) . map_or ( 0 , |t| t. hops . len ( ) ) < 2 {
13861400 log_debug ! (
@@ -1390,6 +1404,26 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13901404 continue ;
13911405 }
13921406
1407+ if let Some ( first_path_hop) = path. hops . first ( ) {
1408+ if let Some ( first_hop) = first_hops. iter ( ) . find ( |h| {
1409+ h. get_outbound_payment_scid ( ) == Some ( first_path_hop. short_channel_id )
1410+ } ) {
1411+ let path_value = path. final_value_msat ( ) + path. fee_msat ( ) ;
1412+ let used_liquidity =
1413+ used_liquidity_map. entry ( first_path_hop. short_channel_id ) . or_insert ( 0 ) ;
1414+
1415+ if first_hop. next_outbound_htlc_limit_msat
1416+ < ( * used_liquidity + path_value)
1417+ * self . config . probing_liquidity_limit_multiplier
1418+ {
1419+ log_debug ! ( self . logger, "Skipped sending payment probe to avoid putting channel {} under the liquidity limit." , first_path_hop. short_channel_id) ;
1420+ continue ;
1421+ } else {
1422+ * used_liquidity += path_value;
1423+ }
1424+ }
1425+ }
1426+
13931427 self . channel_manager . send_probe ( path) . map_err ( |e| {
13941428 log_error ! ( self . logger, "Failed to send payment probe: {:?}" , e) ;
13951429 Error :: ProbeSendingFailed
0 commit comments