Skip to content

Commit 2dfa7bf

Browse files
committed
Pre-filter channels used for probing based on available liquidity
As pre-flight probes might take up some of the available liquidity, we here introduce pre-filtering of the channels used for sending probes based on their available liquidity. This might result in either no route being found (in which case we won't send a probe at all), or a slightly different route being found and used for probing (which is fine, too).
1 parent 5b7019e commit 2dfa7bf

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

bindings/ldk_node.udl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ dictionary Config {
1111
u64 onchain_wallet_sync_interval_secs = 80;
1212
u64 wallet_sync_interval_secs = 30;
1313
u64 fee_rate_cache_update_interval_secs = 600;
14-
LogLevel log_level = "Debug";
1514
sequence<PublicKey> trusted_peers_0conf = [];
15+
u64 probing_liquidity_limit_multiplier = 3;
16+
LogLevel log_level = "Debug";
1617
};
1718

1819
interface Builder {

src/lib.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ const DEFAULT_CLTV_EXPIRY_DELTA: u32 = 144;
164164
const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS: u64 = 80;
165165
const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 30;
166166
const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 10;
167+
const DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER: u64 = 3;
167168
const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Debug;
168169

169170
// The 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
@@ -210,6 +211,7 @@ const WALLET_KEYS_SEED_LEN: usize = 64;
210211
/// | `wallet_sync_interval_secs` | 30 |
211212
/// | `fee_rate_cache_update_interval_secs` | 600 |
212213
/// | `trusted_peers_0conf` | [] |
214+
/// | `probing_liquidity_limit_multiplier` | 3 |
213215
/// | `log_level` | Debug |
214216
///
215217
pub struct Config {
@@ -243,6 +245,8 @@ pub struct Config {
243245
/// funding transaction ends up never being confirmed on-chain. Zero-confirmation channels
244246
/// should therefore only be accepted from trusted peers.
245247
pub trusted_peers_0conf: Vec<PublicKey>,
248+
/// The liquidity factor by which we pre-filter the outgoing channels used for sending probes.
249+
pub probing_liquidity_limit_multiplier: u64,
246250
/// The level at which we log messages.
247251
///
248252
/// Any messages below this level will be excluded from the logs.
@@ -261,6 +265,7 @@ impl Default for Config {
261265
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
262266
fee_rate_cache_update_interval_secs: DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS,
263267
trusted_peers_0conf: Vec::new(),
268+
probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
264269
log_level: DEFAULT_LOG_LEVEL,
265270
}
266271
}
@@ -1306,6 +1311,10 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13061311
/// liquidity needed to complete the actual payment. Users should therefore be cautious and
13071312
/// might avoid sending probes if liquidity is scarce and/or they don't expect the probe to
13081313
/// return before they send the payment.
1314+
///
1315+
/// To somewhat mitigate this issue, channels whose available liquidity is less than the
1316+
/// `invoice` amount times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
1317+
/// pre-flight probes.
13091318
pub fn send_payment_probe(&self, invoice: &Bolt11Invoice) -> Result<(), Error> {
13101319
let rt_lock = self.runtime.read().unwrap();
13111320
if rt_lock.is_none() {
@@ -1347,6 +1356,10 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13471356
/// liquidity needed to complete the actual payment. Users should therefore be cautious and
13481357
/// might avoid sending probes if liquidity is scarce and/or they don't expect the probe to
13491358
/// return before they send the payment.
1359+
///
1360+
/// To somewhat mitigate this issue, channels whose available liquidity is less than
1361+
/// `amount_msat` times [`Config::probing_liquidity_limit_multiplier`] won't be used to send
1362+
/// pre-flight probes.
13501363
pub fn send_spontaneous_payment_probe(
13511364
&self, amount_msat: u64, node_id: PublicKey,
13521365
) -> Result<(), Error> {
@@ -1365,17 +1378,21 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
13651378

13661379
fn send_payment_probe_internal(&self, route_params: RouteParameters) -> Result<(), Error> {
13671380
let payer = self.channel_manager.get_our_node_id();
1368-
let first_hops = self.channel_manager.list_usable_channels();
1381+
let usable_channels = self.channel_manager.list_usable_channels();
1382+
let first_hops = usable_channels
1383+
.iter()
1384+
.filter(|c| {
1385+
c.next_outbound_htlc_limit_msat
1386+
>= route_params
1387+
.final_value_msat
1388+
.saturating_mul(self.config.probing_liquidity_limit_multiplier)
1389+
})
1390+
.collect::<Vec<_>>();
13691391
let inflight_htlcs = self.channel_manager.compute_inflight_htlcs();
13701392

13711393
let route = self
13721394
.router
1373-
.find_route(
1374-
&payer,
1375-
&route_params,
1376-
Some(&first_hops.iter().collect::<Vec<_>>()),
1377-
inflight_htlcs,
1378-
)
1395+
.find_route(&payer, &route_params, Some(&first_hops), inflight_htlcs)
13791396
.map_err(|e| {
13801397
log_error!(self.logger, "Failed to find path for payment probe: {:?}", e);
13811398
Error::ProbeSendingFailed

0 commit comments

Comments
 (0)