@@ -1198,6 +1198,41 @@ impl fmt::Display for LoggedPayeePubkey {
1198
1198
}
1199
1199
}
1200
1200
1201
+ #[ inline]
1202
+ fn sort_first_hop_channels (
1203
+ channels : & mut Vec < & ChannelDetails > , used_channel_liquidities : & HashMap < ( u64 , bool ) , u64 > ,
1204
+ recommended_value_msat : u64 , our_node_pubkey : & PublicKey
1205
+ ) {
1206
+ // Sort the first_hops channels to the same node(s) in priority order of which channel we'd
1207
+ // most like to use.
1208
+ //
1209
+ // First, if channels are below `recommended_value_msat`, sort them in descending order,
1210
+ // preferring larger channels to avoid splitting the payment into more MPP parts than is
1211
+ // required.
1212
+ //
1213
+ // Second, because simply always sorting in descending order would always use our largest
1214
+ // available outbound capacity, needlessly fragmenting our available channel capacities,
1215
+ // sort channels above `recommended_value_msat` in ascending order, preferring channels
1216
+ // which have enough, but not too much, capacity for the payment.
1217
+ //
1218
+ // Available outbound balances factor in liquidity already reserved for previously found paths.
1219
+ channels. sort_unstable_by ( |chan_a, chan_b| {
1220
+ let chan_a_outbound_limit_msat = chan_a. next_outbound_htlc_limit_msat
1221
+ . saturating_sub ( * used_channel_liquidities. get ( & ( chan_a. get_outbound_payment_scid ( ) . unwrap ( ) ,
1222
+ our_node_pubkey < & chan_a. counterparty . node_id ) ) . unwrap_or ( & 0 ) ) ;
1223
+ let chan_b_outbound_limit_msat = chan_b. next_outbound_htlc_limit_msat
1224
+ . saturating_sub ( * used_channel_liquidities. get ( & ( chan_b. get_outbound_payment_scid ( ) . unwrap ( ) ,
1225
+ our_node_pubkey < & chan_b. counterparty . node_id ) ) . unwrap_or ( & 0 ) ) ;
1226
+ if chan_b_outbound_limit_msat < recommended_value_msat || chan_a_outbound_limit_msat < recommended_value_msat {
1227
+ // Sort in descending order
1228
+ chan_b_outbound_limit_msat. cmp ( & chan_a_outbound_limit_msat)
1229
+ } else {
1230
+ // Sort in ascending order
1231
+ chan_a_outbound_limit_msat. cmp ( & chan_b_outbound_limit_msat)
1232
+ }
1233
+ } ) ;
1234
+ }
1235
+
1201
1236
/// Finds a route from us (payer) to the given target node (payee).
1202
1237
///
1203
1238
/// If the payee provided features in their invoice, they should be provided via `params.payee`.
@@ -1442,38 +1477,9 @@ where L::Target: Logger {
1442
1477
// when we want to stop looking for new paths.
1443
1478
let mut already_collected_value_msat = 0 ;
1444
1479
1445
- macro_rules! sort_first_hop_channels {
1446
- ( $channels: expr) => {
1447
- // Sort the first_hops channels to the same node(s) in priority order of which channel we'd
1448
- // most like to use.
1449
- //
1450
- // First, if channels are below `recommended_value_msat`, sort them in descending order,
1451
- // preferring larger channels to avoid splitting the payment into more MPP parts than is
1452
- // required.
1453
- //
1454
- // Second, because simply always sorting in descending order would always use our largest
1455
- // available outbound capacity, needlessly fragmenting our available channel capacities,
1456
- // sort channels above `recommended_value_msat` in ascending order, preferring channels
1457
- // which have enough, but not too much, capacity for the payment.
1458
- $channels. sort_unstable_by( |chan_a, chan_b| {
1459
- let chan_a_outbound_limit_msat = chan_a. next_outbound_htlc_limit_msat
1460
- . saturating_sub( * used_channel_liquidities. get( & ( chan_a. get_outbound_payment_scid( ) . unwrap( ) ,
1461
- our_node_pubkey < & chan_a. counterparty. node_id) ) . unwrap_or( & 0 ) ) ;
1462
- let chan_b_outbound_limit_msat = chan_b. next_outbound_htlc_limit_msat
1463
- . saturating_sub( * used_channel_liquidities. get( & ( chan_b. get_outbound_payment_scid( ) . unwrap( ) ,
1464
- our_node_pubkey < & chan_b. counterparty. node_id) ) . unwrap_or( & 0 ) ) ;
1465
- if chan_b_outbound_limit_msat < recommended_value_msat || chan_a_outbound_limit_msat < recommended_value_msat {
1466
- // Sort in descending order
1467
- chan_b_outbound_limit_msat. cmp( & chan_a_outbound_limit_msat)
1468
- } else {
1469
- // Sort in ascending order
1470
- chan_a_outbound_limit_msat. cmp( & chan_b_outbound_limit_msat)
1471
- }
1472
- } ) ;
1473
- }
1474
- }
1475
1480
for ( _, channels) in first_hop_targets. iter_mut ( ) {
1476
- sort_first_hop_channels ! ( channels) ;
1481
+ sort_first_hop_channels ( channels, & used_channel_liquidities, recommended_value_msat,
1482
+ our_node_pubkey) ;
1477
1483
}
1478
1484
1479
1485
log_trace ! ( logger, "Building path from {} to payer {} for value {} msat." ,
@@ -1883,7 +1889,8 @@ where L::Target: Logger {
1883
1889
let hint_candidate_contribution_msat = cmp:: min ( path_value_msat,
1884
1890
candidate. effective_capacity ( ) . as_msat ( ) . saturating_sub ( used_liquidity_msat) ) ;
1885
1891
if let Some ( first_channels) = first_hop_targets. get_mut ( & NodeId :: from_pubkey ( & prev_hop_id) ) {
1886
- sort_first_hop_channels ! ( first_channels) ;
1892
+ sort_first_hop_channels ( first_channels, & used_channel_liquidities,
1893
+ recommended_value_msat, our_node_pubkey) ;
1887
1894
for details in first_channels {
1888
1895
let first_hop_candidate = CandidateRouteHop :: FirstHop { details } ;
1889
1896
add_entry ! ( first_hop_candidate, our_node_id, NodeId :: from_pubkey( & prev_hop_id) ,
@@ -1923,7 +1930,8 @@ where L::Target: Logger {
1923
1930
// always assumes that the third argument is a node to which we have a
1924
1931
// path.
1925
1932
if let Some ( first_channels) = first_hop_targets. get_mut ( & NodeId :: from_pubkey ( & hop. src_node_id ) ) {
1926
- sort_first_hop_channels ! ( first_channels) ;
1933
+ sort_first_hop_channels ( first_channels, & used_channel_liquidities,
1934
+ recommended_value_msat, our_node_pubkey) ;
1927
1935
for details in first_channels {
1928
1936
let first_hop_candidate = CandidateRouteHop :: FirstHop { details } ;
1929
1937
add_entry ! ( first_hop_candidate, our_node_id,
0 commit comments