Skip to content

Commit 78cc9e9

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 42d0b20 commit 78cc9e9

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
@@ -106,6 +106,9 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
106106
// The minimum channel balance certainty required for using a channel in a blinded path.
107107
const MIN_CHANNEL_CERTAINTY: f64 = 0.5;
108108

109+
// The minimum success probability required for using a channel in a blinded path.
110+
const MIN_SUCCESS_PROBABILITY: f64 = 0.25;
111+
109112
let network_graph = self.network_graph.deref().read_only();
110113
let counterparty_channels = first_hops.into_iter()
111114
.filter(|details| details.counterparty.features.supports_route_blinding())
@@ -181,6 +184,21 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
181184
//
182185
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient
183186
.filter_map(|(introduction_node_id, scid, info, counterparty_forward_node)| {
187+
let amount_msat = amount_msats;
188+
let effective_capacity = info.effective_capacity();
189+
let usage = ChannelUsage { amount_msat, inflight_htlc_msat: 0, effective_capacity };
190+
let success_probability = scorer.channel_success_probability(
191+
scid, &info, usage, &self.score_params
192+
);
193+
194+
if !success_probability.is_finite() {
195+
return None;
196+
}
197+
198+
if success_probability < MIN_SUCCESS_PROBABILITY {
199+
return None;
200+
}
201+
184202
let htlc_minimum_msat = info.direction().htlc_minimum_msat;
185203
let htlc_maximum_msat = info.direction().htlc_maximum_msat;
186204
let payment_relay: PaymentRelay = match info.try_into() {
@@ -202,12 +220,13 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
202220
node_id: introduction_node_id.as_pubkey().unwrap(),
203221
htlc_maximum_msat,
204222
};
205-
Some(BlindedPath::new_for_payment(
223+
let path = BlindedPath::new_for_payment(
206224
&[introduction_forward_node, counterparty_forward_node], recipient,
207225
tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, entropy_source, secp_ctx
208-
))
209-
})
210-
.take(MAX_PAYMENT_PATHS);
226+
);
227+
228+
Some(path.map(|path| (path, success_probability)))
229+
});
211230

212231
let two_hop_paths = counterparty_channels
213232
.map(|(forward_node, _)| {
@@ -221,6 +240,10 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
221240
three_hop_paths
222241
.collect::<Result<Vec<_>, _>>().ok()
223242
.and_then(|paths| (!paths.is_empty()).then(|| paths))
243+
.map(|mut paths| {
244+
paths.sort_unstable_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
245+
paths.into_iter().map(|(path, _)| path).take(MAX_PAYMENT_PATHS).collect::<Vec<_>>()
246+
})
224247
.or_else(|| two_hop_paths.collect::<Result<Vec<_>, _>>().ok())
225248
.and_then(|paths| (!paths.is_empty()).then(|| paths))
226249
.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)