Skip to content

Commit 7a21cd4

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 db46590 commit 7a21cd4

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

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

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