@@ -5055,34 +5055,45 @@ where
5055
5055
// applying non-strict forwarding.
5056
5056
// The channel with the least amount of outbound liquidity will be used to maximize the
5057
5057
// probability of being able to successfully forward a subsequent HTLC.
5058
- let mut channels_with_peer = peer_state.channel_by_id.values_mut().filter_map(|phase| match phase {
5059
- ChannelPhase::Funded(chan) => Some(chan),
5058
+ let maybe_optimal_channel = peer_state.channel_by_id.values_mut().filter_map(|phase| match phase {
5059
+ ChannelPhase::Funded(chan) => {
5060
+ let balances = chan.context.get_available_balances(&self.fee_estimator);
5061
+ if outgoing_amt_msat <= balances.next_outbound_htlc_limit_msat &&
5062
+ outgoing_amt_msat >= balances.next_outbound_htlc_minimum_msat {
5063
+ Some((chan, balances))
5064
+ } else {
5065
+ None
5066
+ }
5067
+ },
5060
5068
_ => None,
5061
- }).collect::<Vec<&mut Channel<_>>>();
5062
- channels_with_peer.sort_by_key(|chan| chan.context.get_available_balances(&self.fee_estimator).outbound_capacity_msat);
5063
- let successfully_added = channels_with_peer.iter_mut().any(|chan| {
5064
- let logger = WithChannelContext::from(&self.logger, &chan.context, Some(payment_hash));
5065
- let add_result = chan.queue_add_htlc(outgoing_amt_msat, payment_hash,
5066
- outgoing_cltv_value, htlc_source.clone(), onion_packet.clone(),
5067
- skimmed_fee_msat, next_blinding_point, &self.fee_estimator, &&logger);
5068
- match add_result {
5069
- Ok(_) => {
5070
- log_trace!(logger, "Forwarding HTLC from SCID {} with payment_hash {} and specified next hop SCID {} over channel {} with corresponding peer {}",
5071
- prev_short_channel_id, &payment_hash, short_chan_id, chan.context.channel_id(), &counterparty_node_id);
5072
- },
5073
- Err(ChannelError::Ignore(ref msg)) => {
5074
- log_trace!(logger, "Not forwarding HTLC with payment_hash {} over channel {} with peer {}: {}. Will attempt other channels with the same peer if possible.",
5075
- &payment_hash, chan.context.channel_id(), &counterparty_node_id, msg);
5076
- },
5077
- Err(_) => {
5078
- panic!("Stated return value requirements in send_htlc() were not met");
5079
- },
5069
+ }).min_by_key(|(_, balances)| balances.next_outbound_htlc_limit_msat).map(|(c, _)| c);
5070
+ let optimal_channel = match maybe_optimal_channel {
5071
+ Some(chan) => chan,
5072
+ None => {
5073
+ // Fall back to the specified channel to return an appropriate error.
5074
+ if let Some(ChannelPhase::Funded(ref mut chan)) = peer_state.channel_by_id.get_mut(&forward_chan_id) {
5075
+ chan
5076
+ } else {
5077
+ forwarding_channel_not_found!(core::iter::once(forward_info).chain(draining_pending_forwards));
5078
+ break;
5079
+ }
5080
+ }
5081
+ };
5082
+
5083
+ let logger = WithChannelContext::from(&self.logger, &optimal_channel.context, Some(payment_hash));
5084
+ log_trace!(logger, "Forwarding HTLC from SCID {} with payment_hash {} and specified next hop SCID {} over optimal channel {} with corresponding peer {}",
5085
+ prev_short_channel_id, &payment_hash, short_chan_id, optimal_channel.context.channel_id(), &counterparty_node_id);
5086
+ if let Err(e) = optimal_channel.queue_add_htlc(outgoing_amt_msat,
5087
+ payment_hash, outgoing_cltv_value, htlc_source.clone(),
5088
+ onion_packet.clone(), skimmed_fee_msat, next_blinding_point, &self.fee_estimator,
5089
+ &&logger)
5090
+ {
5091
+ if let ChannelError::Ignore(msg) = e {
5092
+ log_trace!(logger, "Failed to forward HTLC with payment_hash {} to peer {}: {}", &payment_hash, &counterparty_node_id, msg);
5093
+ } else {
5094
+ panic!("Stated return value requirements in send_htlc() were not met");
5080
5095
}
5081
- add_result.is_ok()
5082
- });
5083
5096
5084
- if !successfully_added {
5085
- log_trace!(self.logger, "Failed to forward HTLC with payment_hash {} to peer {}", &payment_hash, &counterparty_node_id);
5086
5097
if let Some(ChannelPhase::Funded(ref mut chan)) = peer_state.channel_by_id.get_mut(&forward_chan_id) {
5087
5098
let (failure_code, data) = self.get_htlc_temp_fail_err_and_data(0x1000|7, short_chan_id, chan);
5088
5099
failed_forwards.push((htlc_source, payment_hash,
0 commit comments