Skip to content

Commit 26f4d72

Browse files
committed
Store available routing amounts per channel to use it in routing decisions
1 parent d735a24 commit 26f4d72

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

fuzz/src/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
223223
},
224224
cltv_expiry_delta: slice_to_be16(get_slice!(2)),
225225
htlc_minimum_msat: slice_to_be64(get_slice!(8)),
226+
htlc_maximum_msat: None,
226227
});
227228
}
228229
&last_hops_vec[..]

lightning/src/routing/router.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ pub struct RouteHint {
115115
pub cltv_expiry_delta: u16,
116116
/// The minimum value, in msat, which must be relayed to the next hop.
117117
pub htlc_minimum_msat: u64,
118+
/// The maximum value in msat available for routing with a single HTLC.
119+
pub htlc_maximum_msat: Option<u64>,
118120
}
119121

120122
#[derive(Eq, PartialEq)]
@@ -140,6 +142,7 @@ impl cmp::PartialOrd for RouteGraphNode {
140142
struct DummyDirectionalChannelInfo {
141143
cltv_expiry_delta: u32,
142144
htlc_minimum_msat: u64,
145+
htlc_maximum_msat: Option<u64>,
143146
fees: RoutingFees,
144147
}
145148

@@ -181,6 +184,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
181184
let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes
182185
cltv_expiry_delta: 0,
183186
htlc_minimum_msat: 0,
187+
htlc_maximum_msat: None,
184188
fees: RoutingFees {
185189
base_msat: 0,
186190
proportional_millionths: 0,
@@ -217,14 +221,24 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
217221
// Adds entry which goes from $src_node_id to $dest_node_id
218222
// over the channel with id $chan_id with fees described in
219223
// $directional_info.
220-
( $chan_id: expr, $src_node_id: expr, $dest_node_id: expr, $directional_info: expr, $chan_features: expr, $starting_fee_msat: expr ) => {
224+
( $chan_id: expr, $src_node_id: expr, $dest_node_id: expr, $directional_info: expr, $capacity_sats: expr, $chan_features: expr, $starting_fee_msat: expr ) => {
221225
//TODO: Explore simply adding fee to hit htlc_minimum_msat
222226
if $starting_fee_msat as u64 + final_value_msat >= $directional_info.htlc_minimum_msat {
223227
let proportional_fee_millions = ($starting_fee_msat + final_value_msat).checked_mul($directional_info.fees.proportional_millionths as u64);
224228
if let Some(new_fee) = proportional_fee_millions.and_then(|part| {
225229
($directional_info.fees.base_msat as u64).checked_add(part / 1000000) })
226230
{
227231
let mut total_fee = $starting_fee_msat as u64;
232+
233+
let mut available_msat = $capacity_sats;
234+
if let Some(htlc_maximum_msat) = $directional_info.htlc_maximum_msat {
235+
if let Some(capacity_sats) = $capacity_sats {
236+
available_msat = Some(cmp::min(capacity_sats * 1000, htlc_maximum_msat));
237+
} else {
238+
available_msat = Some(htlc_maximum_msat);
239+
}
240+
}
241+
228242
let hm_entry = dist.entry(&$src_node_id);
229243
let old_entry = hm_entry.or_insert_with(|| {
230244
let node = network.get_nodes().get(&$src_node_id).unwrap();
@@ -245,6 +259,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
245259
fee_msat: 0,
246260
cltv_expiry_delta: 0,
247261
},
262+
None,
248263
)
249264
});
250265
if $src_node_id != *our_node_id {
@@ -273,7 +288,8 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
273288
channel_features: $chan_features.clone(),
274289
fee_msat: new_fee, // This field is ignored on the last-hop anyway
275290
cltv_expiry_delta: $directional_info.cltv_expiry_delta as u32,
276-
}
291+
};
292+
old_entry.4 = available_msat;
277293
}
278294
}
279295
}
@@ -284,7 +300,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
284300
( $node: expr, $node_id: expr, $fee_to_target_msat: expr ) => {
285301
if first_hops.is_some() {
286302
if let Some(&(ref first_hop, ref features)) = first_hop_targets.get(&$node_id) {
287-
add_entry!(first_hop, *our_node_id, $node_id, dummy_directional_info, features.to_context(), $fee_to_target_msat);
303+
add_entry!(first_hop, *our_node_id, $node_id, dummy_directional_info, None::<u64>, features.to_context(), $fee_to_target_msat);
288304
}
289305
}
290306

@@ -304,15 +320,15 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
304320
if first_hops.is_none() || chan.node_two != *our_node_id {
305321
if let Some(two_to_one) = chan.two_to_one.as_ref() {
306322
if two_to_one.enabled {
307-
add_entry!(chan_id, chan.node_two, chan.node_one, two_to_one, chan.features, $fee_to_target_msat);
323+
add_entry!(chan_id, chan.node_two, chan.node_one, two_to_one, chan.capacity_sats, chan.features, $fee_to_target_msat);
308324
}
309325
}
310326
}
311327
} else {
312328
if first_hops.is_none() || chan.node_one != *our_node_id {
313329
if let Some(one_to_two) = chan.one_to_two.as_ref() {
314330
if one_to_two.enabled {
315-
add_entry!(chan_id, chan.node_one, chan.node_two, one_to_two, chan.features, $fee_to_target_msat);
331+
add_entry!(chan_id, chan.node_one, chan.node_two, one_to_two, chan.capacity_sats, chan.features, $fee_to_target_msat);
316332
}
317333
}
318334

@@ -340,12 +356,12 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
340356
// bit lazy here. In the future, we should pull them out via our
341357
// ChannelManager, but there's no reason to waste the space until we
342358
// need them.
343-
add_entry!(first_hop, *our_node_id , hop.src_node_id, dummy_directional_info, features.to_context(), 0);
359+
add_entry!(first_hop, *our_node_id , hop.src_node_id, dummy_directional_info, None::<u64>, features.to_context(), 0);
344360
}
345361
}
346362
// BOLT 11 doesn't allow inclusion of features for the last hop hints, which
347363
// really sucks, cause we're gonna need that eventually.
348-
add_entry!(hop.short_channel_id, hop.src_node_id, target, hop, ChannelFeatures::empty(), 0);
364+
add_entry!(hop.short_channel_id, hop.src_node_id, target, hop, None::<u64>, ChannelFeatures::empty(), 0);
349365
}
350366
}
351367
}
@@ -1049,6 +1065,7 @@ mod tests {
10491065
fees: zero_fees,
10501066
cltv_expiry_delta: (8 << 8) | 1,
10511067
htlc_minimum_msat: 0,
1068+
htlc_maximum_msat: None,
10521069
}, RouteHint {
10531070
src_node_id: node5.clone(),
10541071
short_channel_id: 9,
@@ -1058,12 +1075,14 @@ mod tests {
10581075
},
10591076
cltv_expiry_delta: (9 << 8) | 1,
10601077
htlc_minimum_msat: 0,
1078+
htlc_maximum_msat: None,
10611079
}, RouteHint {
10621080
src_node_id: node6.clone(),
10631081
short_channel_id: 10,
10641082
fees: zero_fees,
10651083
cltv_expiry_delta: (10 << 8) | 1,
10661084
htlc_minimum_msat: 0,
1085+
htlc_maximum_msat: None,
10671086
});
10681087

10691088
// Simple test across 2, 3, 5, and 4 via a last_hop channel

0 commit comments

Comments
 (0)