@@ -10,7 +10,7 @@ use lightning::chain;
10
10
use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
11
11
use lightning:: chain:: keysinterface:: { Recipient , KeysInterface , Sign } ;
12
12
use lightning:: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
13
- use lightning:: ln:: channelmanager:: { ChannelDetails , ChannelManager , CounterpartyForwardingInfo , PaymentId , PaymentSendFailure , MIN_FINAL_CLTV_EXPIRY } ;
13
+ use lightning:: ln:: channelmanager:: { ChannelDetails , ChannelManager , PaymentId , PaymentSendFailure , MIN_FINAL_CLTV_EXPIRY } ;
14
14
#[ cfg( feature = "std" ) ]
15
15
use lightning:: ln:: channelmanager:: { PhantomRouteHints , MIN_CLTV_EXPIRY_DELTA } ;
16
16
use lightning:: ln:: msgs:: LightningError ;
@@ -198,50 +198,26 @@ where
198
198
}
199
199
}
200
200
201
- /// Filters channels for an invoice, and returns the corresponding route hints to include
201
+ /// Filters the ` channels` for an invoice, and returns the corresponding `RouteHint`s to include
202
202
/// in the invoice.
203
203
///
204
- /// The filtering ensures that the `RouteHints` returned only include the highest inbound capacity
205
- /// channel per counterparty node. If any channel with a higher inbound capacity than the given
206
- /// `min_inbound_capacity_msat` exists, channels to other counterparty nodes with a lower inbound
207
- /// capacity than `min_inbound_capacity_msat` will be filtered out, even if they are the highest
208
- /// inbound capacity channel for that specific counterparty node.
209
- /// If any public channel exists, the function returns no RouteHints, and the sender will need to
210
- /// look at the public channels to find a path instead.
211
- ///
212
- /// Input:
213
- /// `channels`: The channels to filter.
214
- /// `min_inbound_capacity_msat`: Defines the lowest inbound capacity channels must have to not
215
- /// be filtered out, if any other channel above that amount exists.
216
- ///
217
- /// Result:
218
- /// `Vec<RouteHint>`: The filtered `RouteHints`, which will be empty if any public channel exists.
204
+ /// The filtering is based on the following criteria:
205
+ /// * Only one channel per counterparty node
206
+ /// * Always select the channel with the highest inbound capacity per counterparty node
207
+ /// * Filter out channels with a lower inbound capacity than `min_inbound_capacity_msat`, if any
208
+ /// channel with a higher or equal inbound capacity than `min_inbound_capacity_msat` exists
209
+ /// * If any public channel exists, the returned `RouteHint`s will be empty, and the sender will
210
+ /// need to find the path by looking at the public channels instead
219
211
fn filter_channels ( channels : Vec < ChannelDetails > , min_inbound_capacity_msat : Option < u64 > ) -> Vec < RouteHint > {
220
- let mut filtered_channels: HashMap < PublicKey , ( u64 , RouteHint ) > = HashMap :: new ( ) ;
212
+ let mut filtered_channels: HashMap < PublicKey , ChannelDetails > = HashMap :: new ( ) ;
221
213
let min_inbound_capacity = min_inbound_capacity_msat. unwrap_or ( 0 ) ;
222
214
let mut min_capacity_channel_exists = false ;
223
215
224
- let route_hint_from_channel = |channel : & ChannelDetails , short_channel_id : u64 , forwarding_info : & CounterpartyForwardingInfo | {
225
- RouteHint ( vec ! [ RouteHintHop {
226
- src_node_id: channel. counterparty. node_id,
227
- short_channel_id,
228
- fees: RoutingFees {
229
- base_msat: forwarding_info. fee_base_msat,
230
- proportional_millionths: forwarding_info. fee_proportional_millionths,
231
- } ,
232
- cltv_expiry_delta: forwarding_info. cltv_expiry_delta,
233
- htlc_minimum_msat: None ,
234
- htlc_maximum_msat: None , } ] )
235
- } ;
236
216
for channel in channels {
237
- let short_channel_id = match channel. get_inbound_payment_scid ( ) {
238
- Some ( id) => id,
239
- None => continue ,
240
- } ;
241
- let forwarding_info = match & channel. counterparty . forwarding_info {
242
- Some ( info) => info,
243
- None => continue ,
244
- } ;
217
+ if channel. get_inbound_payment_scid ( ) . is_none ( ) || channel. counterparty . forwarding_info . is_none ( ) {
218
+ continue ;
219
+ }
220
+
245
221
if channel. is_public {
246
222
// If any public channel exists, return no hints and let the sender
247
223
// look at the public channels instead.
@@ -253,33 +229,40 @@ fn filter_channels(channels: Vec<ChannelDetails>, min_inbound_capacity_msat: Opt
253
229
} ;
254
230
match filtered_channels. entry ( channel. counterparty . node_id ) {
255
231
hash_map:: Entry :: Occupied ( mut entry) => {
256
- let current_max_capacity = entry. get ( ) . 0 ;
232
+ let current_max_capacity = entry. get ( ) . inbound_capacity_msat ;
257
233
if channel. inbound_capacity_msat < current_max_capacity {
258
234
continue ;
259
235
}
260
- entry. insert ( (
261
- channel. inbound_capacity_msat ,
262
- route_hint_from_channel ( & channel, short_channel_id, forwarding_info) ,
263
- ) ) ;
236
+ entry. insert ( channel) ;
264
237
}
265
238
hash_map:: Entry :: Vacant ( entry) => {
266
- entry. insert ( (
267
- channel. inbound_capacity_msat ,
268
- route_hint_from_channel ( & channel, short_channel_id, forwarding_info) ,
269
- ) ) ;
239
+ entry. insert ( channel) ;
270
240
}
271
241
}
272
242
}
273
243
244
+ let route_hint_from_channel = |channel : & ChannelDetails | {
245
+ let forwarding_info = channel. counterparty . forwarding_info . as_ref ( ) . unwrap ( ) ;
246
+ RouteHint ( vec ! [ RouteHintHop {
247
+ src_node_id: channel. counterparty. node_id,
248
+ short_channel_id: channel. get_inbound_payment_scid( ) . unwrap( ) ,
249
+ fees: RoutingFees {
250
+ base_msat: forwarding_info. fee_base_msat,
251
+ proportional_millionths: forwarding_info. fee_proportional_millionths,
252
+ } ,
253
+ cltv_expiry_delta: forwarding_info. cltv_expiry_delta,
254
+ htlc_minimum_msat: None ,
255
+ htlc_maximum_msat: None , } ] )
256
+ } ;
274
257
// If all channels are private, return the route hint for the highest inbound capacity channel
275
258
// per counterparty node. If channels with an higher inbound capacity than the
276
259
// min_inbound_capacity exists, filter out the channels with a lower capacity than that.
277
260
filtered_channels. into_iter ( )
278
- . filter ( |( _channel , ( capacity , _route_hint ) ) | {
279
- min_capacity_channel_exists && capacity >= & min_inbound_capacity ||
261
+ . filter ( |( _counterparty_id , channel ) | {
262
+ min_capacity_channel_exists && channel . inbound_capacity_msat >= min_inbound_capacity ||
280
263
!min_capacity_channel_exists
281
264
} )
282
- . map ( |( _channel , ( _max_capacity , route_hint ) ) | route_hint )
265
+ . map ( |( _counterparty_id , channel ) | route_hint_from_channel ( & channel ) )
283
266
. collect :: < Vec < RouteHint > > ( )
284
267
}
285
268
0 commit comments