Skip to content

Commit 392aadb

Browse files
committed
Consider success probability in blinded path
How certain a scorer is about a channel's success probability is useful in determining if the channel should be included in a blinded payment path. Channels with low success probability for a given amount should be avoided to facilitate successful payments. Expand ScoreLookUp with a channel_success_probability method and use it in DefaultRouter::create_blinded_payment_paths.
1 parent 315cb7c commit 392aadb

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

lightning/src/routing/router.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
100100
// The minimum channel balance certainty required for using a channel in a blinded path.
101101
const MIN_CHANNEL_CERTAINTY: f64 = 0.5;
102102

103+
// The minimum success probability required for using a channel in a blinded path.
104+
const MIN_SUCCESS_PROBABILITY: f64 = 0.25;
105+
103106
let network_graph = self.network_graph.deref().read_only();
104107
let counterparty_channels = first_hops.into_iter()
105108
.filter(|details| details.counterparty.features.supports_route_blinding())
@@ -175,6 +178,21 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
175178
//
176179
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient
177180
.filter_map(|(introduction_node_id, scid, info, counterparty_forward_node)| {
181+
let amount_msat = amount_msats;
182+
let effective_capacity = info.effective_capacity();
183+
let usage = ChannelUsage { amount_msat, inflight_htlc_msat: 0, effective_capacity };
184+
let success_probability = scorer.channel_success_probability(
185+
scid, &info, usage, &self.score_params
186+
);
187+
188+
if !success_probability.is_finite() {
189+
return None;
190+
}
191+
192+
if success_probability < MIN_SUCCESS_PROBABILITY {
193+
return None;
194+
}
195+
178196
let htlc_minimum_msat = info.direction().htlc_minimum_msat;
179197
let htlc_maximum_msat = info.direction().htlc_maximum_msat;
180198
let payment_relay: PaymentRelay = match info.try_into() {
@@ -196,12 +214,13 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
196214
node_id: introduction_node_id.as_pubkey().unwrap(),
197215
htlc_maximum_msat,
198216
};
199-
Some(BlindedPath::new_for_payment(
217+
let path = BlindedPath::new_for_payment(
200218
&[introduction_forward_node, counterparty_forward_node], recipient,
201219
tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, entropy_source, secp_ctx
202-
))
203-
})
204-
.take(MAX_PAYMENT_PATHS);
220+
);
221+
222+
Some(path.map(|path| (path, success_probability)))
223+
});
205224

206225
let two_hop_paths = counterparty_channels
207226
.map(|(forward_node, _)| {
@@ -215,6 +234,10 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
215234
three_hop_paths
216235
.collect::<Result<Vec<_>, _>>().ok()
217236
.and_then(|paths| (!paths.is_empty()).then(|| paths))
237+
.map(|mut paths| {
238+
paths.sort_unstable_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
239+
paths.into_iter().map(|(path, _)| path).take(MAX_PAYMENT_PATHS).collect::<Vec<_>>()
240+
})
218241
.or_else(|| two_hop_paths.collect::<Result<Vec<_>, _>>().ok())
219242
.and_then(|paths| (!paths.is_empty()).then(|| paths))
220243
.or_else(|| network_graph

lightning/src/routing/scoring.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ pub trait ScoreLookUp {
109109
&self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams
110110
) -> u64;
111111

112+
/// Returns the success probability of sending an HTLC through a channel.
113+
///
114+
/// Expected to return a value between `0.0` and `1.0`, inclusive, where `0.0` indicates
115+
/// highly unlikely and `1.0` highly likely.
116+
///
117+
/// This is useful to determine whether a channel should be included in a blinded path and the
118+
/// preferred ordering of blinded paths.
119+
fn channel_success_probability(
120+
&self, _short_channel_id: u64, _info: &DirectedChannelInfo, _usage: ChannelUsage,
121+
_score_params: &Self::ScoreParams
122+
) -> f64 { 0.5 }
123+
112124
/// Returns how certain any knowledge gained about the channel's liquidity balance is.
113125
///
114126
/// Expected to return a value between `0.0` and `1.0`, inclusive, where `0.0` indicates

0 commit comments

Comments
 (0)