Skip to content

Commit d2067bb

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 82b3826 commit d2067bb

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
@@ -102,6 +102,9 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
102102
// The minimum channel balance certainty required for using a channel in a blinded path.
103103
const MIN_CHANNEL_CERTAINTY: f64 = 0.5;
104104

105+
// The minimum success probability required for using a channel in a blinded path.
106+
const MIN_SUCCESS_PROBABILITY: f64 = 0.25;
107+
105108
let network_graph = self.network_graph.deref().read_only();
106109
let counterparty_channels = first_hops.into_iter()
107110
.filter(|details| details.counterparty.features.supports_route_blinding())
@@ -177,6 +180,21 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
177180
//
178181
// source --- info ---> counterparty --- counterparty_forward_node ---> recipient
179182
.filter_map(|(introduction_node_id, scid, info, counterparty_forward_node)| {
183+
let amount_msat = amount_msats;
184+
let effective_capacity = info.effective_capacity();
185+
let usage = ChannelUsage { amount_msat, inflight_htlc_msat: 0, effective_capacity };
186+
let success_probability = scorer.channel_success_probability(
187+
scid, &info, usage, &self.score_params
188+
);
189+
190+
if !success_probability.is_finite() {
191+
return None;
192+
}
193+
194+
if success_probability < MIN_SUCCESS_PROBABILITY {
195+
return None;
196+
}
197+
180198
let htlc_minimum_msat = info.direction().htlc_minimum_msat;
181199
let htlc_maximum_msat = info.direction().htlc_maximum_msat;
182200
let payment_relay: PaymentRelay = match info.try_into() {
@@ -198,12 +216,13 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
198216
node_id: introduction_node_id.as_pubkey().unwrap(),
199217
htlc_maximum_msat,
200218
};
201-
Some(BlindedPath::new_for_payment(
219+
let path = BlindedPath::new_for_payment(
202220
&[introduction_forward_node, counterparty_forward_node], recipient,
203221
tlvs.clone(), u64::MAX, entropy_source, secp_ctx
204-
))
205-
})
206-
.take(MAX_PAYMENT_PATHS);
222+
);
223+
224+
Some(path.map(|path| (path, success_probability)))
225+
});
207226

208227
let two_hop_paths = counterparty_channels
209228
.map(|(forward_node, _)| {
@@ -216,6 +235,10 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized,
216235
three_hop_paths
217236
.collect::<Result<Vec<_>, _>>().ok()
218237
.and_then(|paths| (!paths.is_empty()).then(|| paths))
238+
.map(|mut paths| {
239+
paths.sort_unstable_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
240+
paths.into_iter().map(|(path, _)| path).take(MAX_PAYMENT_PATHS).collect::<Vec<_>>()
241+
})
219242
.or_else(|| two_hop_paths.collect::<Result<Vec<_>, _>>().ok())
220243
.and_then(|paths| (!paths.is_empty()).then(|| paths))
221244
.or_else(|| network_graph

lightning/src/routing/scoring.rs

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

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

0 commit comments

Comments
 (0)