@@ -124,6 +124,8 @@ pub struct RouteHint {
124
124
pub cltv_expiry_delta : u16 ,
125
125
/// The minimum value, in msat, which must be relayed to the next hop.
126
126
pub htlc_minimum_msat : u64 ,
127
+ /// The maximum value in msat available for routing with a single HTLC.
128
+ pub htlc_maximum_msat : Option < u64 > ,
127
129
}
128
130
129
131
#[ derive( Eq , PartialEq ) ]
@@ -149,6 +151,7 @@ impl cmp::PartialOrd for RouteGraphNode {
149
151
struct DummyDirectionalChannelInfo {
150
152
cltv_expiry_delta : u32 ,
151
153
htlc_minimum_msat : u64 ,
154
+ htlc_maximum_msat : Option < u64 > ,
152
155
fees : RoutingFees ,
153
156
}
154
157
@@ -190,6 +193,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
190
193
let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes
191
194
cltv_expiry_delta : 0 ,
192
195
htlc_minimum_msat : 0 ,
196
+ htlc_maximum_msat : None ,
193
197
fees : RoutingFees {
194
198
base_msat : 0 ,
195
199
proportional_millionths : 0 ,
@@ -226,14 +230,24 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
226
230
// Adds entry which goes from $src_node_id to $dest_node_id
227
231
// over the channel with id $chan_id with fees described in
228
232
// $directional_info.
229
- ( $chan_id: expr, $src_node_id: expr, $dest_node_id: expr, $directional_info: expr, $chan_features: expr, $starting_fee_msat: expr ) => {
233
+ ( $chan_id: expr, $src_node_id: expr, $dest_node_id: expr, $directional_info: expr, $capacity_sats : expr , $ chan_features: expr, $starting_fee_msat: expr ) => {
230
234
//TODO: Explore simply adding fee to hit htlc_minimum_msat
231
235
if $starting_fee_msat as u64 + final_value_msat >= $directional_info. htlc_minimum_msat {
232
236
let proportional_fee_millions = ( $starting_fee_msat + final_value_msat) . checked_mul( $directional_info. fees. proportional_millionths as u64 ) ;
233
237
if let Some ( new_fee) = proportional_fee_millions. and_then( |part| {
234
238
( $directional_info. fees. base_msat as u64 ) . checked_add( part / 1000000 ) } )
235
239
{
236
240
let mut total_fee = $starting_fee_msat as u64 ;
241
+
242
+ let mut available_msat = $capacity_sats;
243
+ if let Some ( htlc_maximum_msat) = $directional_info. htlc_maximum_msat {
244
+ if let Some ( capacity_sats) = $capacity_sats {
245
+ available_msat = Some ( cmp:: min( capacity_sats * 1000 , htlc_maximum_msat) ) ;
246
+ } else {
247
+ available_msat = Some ( htlc_maximum_msat) ;
248
+ }
249
+ }
250
+
237
251
let hm_entry = dist. entry( & $src_node_id) ;
238
252
let old_entry = hm_entry. or_insert_with( || {
239
253
let node = network. get_nodes( ) . get( & $src_node_id) . unwrap( ) ;
@@ -254,6 +268,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
254
268
fee_msat: 0 ,
255
269
cltv_expiry_delta: 0 ,
256
270
} ,
271
+ None ,
257
272
)
258
273
} ) ;
259
274
if $src_node_id != * our_node_id {
@@ -282,7 +297,8 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
282
297
channel_features: $chan_features. clone( ) ,
283
298
fee_msat: new_fee, // This field is ignored on the last-hop anyway
284
299
cltv_expiry_delta: $directional_info. cltv_expiry_delta as u32 ,
285
- }
300
+ } ;
301
+ old_entry. 4 = available_msat;
286
302
}
287
303
}
288
304
}
@@ -293,7 +309,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
293
309
( $node: expr, $node_id: expr, $fee_to_target_msat: expr ) => {
294
310
if first_hops. is_some( ) {
295
311
if let Some ( & ( ref first_hop, ref features) ) = first_hop_targets. get( & $node_id) {
296
- add_entry!( first_hop, * our_node_id, $node_id, dummy_directional_info, features. to_context( ) , $fee_to_target_msat) ;
312
+ add_entry!( first_hop, * our_node_id, $node_id, dummy_directional_info, None :: < u64 > , features. to_context( ) , $fee_to_target_msat) ;
297
313
}
298
314
}
299
315
@@ -313,15 +329,15 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
313
329
if first_hops. is_none( ) || chan. node_two != * our_node_id {
314
330
if let Some ( two_to_one) = chan. two_to_one. as_ref( ) {
315
331
if two_to_one. enabled {
316
- add_entry!( chan_id, chan. node_two, chan. node_one, two_to_one, chan. features, $fee_to_target_msat) ;
332
+ add_entry!( chan_id, chan. node_two, chan. node_one, two_to_one, chan. capacity_sats , chan . features, $fee_to_target_msat) ;
317
333
}
318
334
}
319
335
}
320
336
} else {
321
337
if first_hops. is_none( ) || chan. node_one != * our_node_id {
322
338
if let Some ( one_to_two) = chan. one_to_two. as_ref( ) {
323
339
if one_to_two. enabled {
324
- add_entry!( chan_id, chan. node_one, chan. node_two, one_to_two, chan. features, $fee_to_target_msat) ;
340
+ add_entry!( chan_id, chan. node_one, chan. node_two, one_to_two, chan. capacity_sats , chan . features, $fee_to_target_msat) ;
325
341
}
326
342
}
327
343
@@ -349,12 +365,12 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, targ
349
365
// bit lazy here. In the future, we should pull them out via our
350
366
// ChannelManager, but there's no reason to waste the space until we
351
367
// need them.
352
- add_entry ! ( first_hop, * our_node_id , hop. src_node_id, dummy_directional_info, features. to_context( ) , 0 ) ;
368
+ add_entry ! ( first_hop, * our_node_id , hop. src_node_id, dummy_directional_info, None :: < u64 > , features. to_context( ) , 0 ) ;
353
369
}
354
370
}
355
371
// BOLT 11 doesn't allow inclusion of features for the last hop hints, which
356
372
// really sucks, cause we're gonna need that eventually.
357
- add_entry ! ( hop. short_channel_id, hop. src_node_id, target, hop, ChannelFeatures :: empty( ) , 0 ) ;
373
+ add_entry ! ( hop. short_channel_id, hop. src_node_id, target, hop, None :: < u64 > , ChannelFeatures :: empty( ) , 0 ) ;
358
374
}
359
375
}
360
376
}
@@ -1047,6 +1063,7 @@ mod tests {
1047
1063
fees: zero_fees,
1048
1064
cltv_expiry_delta: ( 8 << 8 ) | 1 ,
1049
1065
htlc_minimum_msat: 0 ,
1066
+ htlc_maximum_msat: None ,
1050
1067
} , RouteHint {
1051
1068
src_node_id: nodes[ 4 ] . clone( ) ,
1052
1069
short_channel_id: 9 ,
@@ -1056,12 +1073,14 @@ mod tests {
1056
1073
} ,
1057
1074
cltv_expiry_delta: ( 9 << 8 ) | 1 ,
1058
1075
htlc_minimum_msat: 0 ,
1076
+ htlc_maximum_msat: None ,
1059
1077
} , RouteHint {
1060
1078
src_node_id: nodes[ 5 ] . clone( ) ,
1061
1079
short_channel_id: 10 ,
1062
1080
fees: zero_fees,
1063
1081
cltv_expiry_delta: ( 10 << 8 ) | 1 ,
1064
1082
htlc_minimum_msat: 0 ,
1083
+ htlc_maximum_msat: None ,
1065
1084
} )
1066
1085
}
1067
1086
0 commit comments