@@ -160,8 +160,21 @@ where
160160{
161161 // Marshall route hints.
162162 let our_channels = channelmanager. list_usable_channels ( ) ;
163- let mut route_hints = vec ! [ ] ;
163+ let mut route_hints: HashMap < PublicKey , ( u64 , RouteHint ) > = HashMap :: new ( ) ;
164+ let min_capacity_required = match amt_msat {
165+ Some ( amt) => amt,
166+ None => 0 ,
167+ } ;
164168 for channel in our_channels {
169+ // Filter the channels to ensure that the `route_hints` only include the highest inbound
170+ // capacity channel per counterparty node, and that channels with a lower inbound capacity
171+ // than the invoice amount aren't included in the hints.
172+ if !channel. is_public {
173+ // If any of our channels are private, the invoice shouldn't include any `route_hints`
174+ // and the sender will need to look at our public channels instead.
175+ route_hints. clear ( ) ;
176+ break ;
177+ }
165178 let short_channel_id = match channel. short_channel_id {
166179 Some ( id) => id,
167180 None => continue ,
@@ -170,17 +183,45 @@ where
170183 Some ( info) => info,
171184 None => continue ,
172185 } ;
173- route_hints. push ( RouteHint ( vec ! [ RouteHintHop {
174- src_node_id: channel. counterparty. node_id,
175- short_channel_id,
176- fees: RoutingFees {
177- base_msat: forwarding_info. fee_base_msat,
178- proportional_millionths: forwarding_info. fee_proportional_millionths,
179- } ,
180- cltv_expiry_delta: forwarding_info. cltv_expiry_delta,
181- htlc_minimum_msat: None ,
182- htlc_maximum_msat: None ,
183- } ] ) ) ;
186+ if channel. inbound_capacity_msat < min_capacity_required {
187+ continue ;
188+ } ;
189+ match route_hints. entry ( channel. counterparty . node_id ) {
190+ hash_map:: Entry :: Occupied ( mut entry) => {
191+ let current_max_capacity = entry. get ( ) . 0 ;
192+ if channel. inbound_capacity_msat < current_max_capacity {
193+ continue ;
194+ }
195+ entry. insert ( (
196+ channel. inbound_capacity_msat ,
197+ RouteHint ( vec ! [ RouteHintHop {
198+ src_node_id: channel. counterparty. node_id,
199+ short_channel_id,
200+ fees: RoutingFees {
201+ base_msat: forwarding_info. fee_base_msat,
202+ proportional_millionths: forwarding_info. fee_proportional_millionths,
203+ } ,
204+ cltv_expiry_delta: forwarding_info. cltv_expiry_delta,
205+ htlc_minimum_msat: None ,
206+ htlc_maximum_msat: None ,
207+ } ] ) ) ) ;
208+ }
209+ hash_map:: Entry :: Vacant ( entry) => {
210+ entry. insert ( (
211+ channel. inbound_capacity_msat ,
212+ RouteHint ( vec ! [ RouteHintHop {
213+ src_node_id: channel. counterparty. node_id,
214+ short_channel_id,
215+ fees: RoutingFees {
216+ base_msat: forwarding_info. fee_base_msat,
217+ proportional_millionths: forwarding_info. fee_proportional_millionths,
218+ } ,
219+ cltv_expiry_delta: forwarding_info. cltv_expiry_delta,
220+ htlc_minimum_msat: None ,
221+ htlc_maximum_msat: None ,
222+ } ] ) ) ) ;
223+ }
224+ }
184225 }
185226
186227 // `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
@@ -200,8 +241,8 @@ where
200241 if let Some ( amt) = amt_msat {
201242 invoice = invoice. amount_milli_satoshis ( amt) ;
202243 }
203- for hint in route_hints {
204- invoice = invoice. private_route ( hint) ;
244+ for ( _ , ( _ , hint) ) in & route_hints {
245+ invoice = invoice. private_route ( hint. clone ( ) ) ;
205246 }
206247
207248 let raw_invoice = match invoice. build_raw ( ) {
0 commit comments