@@ -4815,96 +4815,167 @@ where
48154815 })
48164816 }
48174817
4818- #[rustfmt::skip]
48194818 fn send_payment_along_path(&self, args: SendAlongPathArgs) -> Result<(), APIError> {
48204819 let SendAlongPathArgs {
4821- path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
4822- invoice_request, bolt12_invoice, session_priv_bytes
4820+ path,
4821+ payment_hash,
4822+ recipient_onion,
4823+ total_value,
4824+ cur_height,
4825+ payment_id,
4826+ keysend_preimage,
4827+ invoice_request,
4828+ bolt12_invoice,
4829+ session_priv_bytes,
48234830 } = args;
48244831 // The top-level caller should hold the total_consistency_lock read lock.
48254832 debug_assert!(self.total_consistency_lock.try_write().is_err());
48264833 let prng_seed = self.entropy_source.get_secure_random_bytes();
48274834 let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
48284835
48294836 let (onion_packet, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion(
4830- &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height,
4831- payment_hash, keysend_preimage, invoice_request, prng_seed
4832- ).map_err(|e| {
4833- let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
4834- log_error!(logger, "Failed to build an onion for path for payment hash {}", payment_hash);
4837+ &self.secp_ctx,
4838+ &path,
4839+ &session_priv,
4840+ total_value,
4841+ recipient_onion,
4842+ cur_height,
4843+ payment_hash,
4844+ keysend_preimage,
4845+ invoice_request,
4846+ prng_seed,
4847+ )
4848+ .map_err(|e| {
4849+ let first_hop_key = Some(path.hops.first().unwrap().pubkey);
4850+ let logger = WithContext::from(&self.logger, first_hop_key, None, Some(*payment_hash));
4851+ log_error!(
4852+ logger,
4853+ "Failed to build an onion for path for payment hash {}",
4854+ payment_hash
4855+ );
48354856 e
48364857 })?;
48374858
48384859 let err: Result<(), _> = loop {
4839- let (counterparty_node_id, id) = match self.short_to_chan_info.read().unwrap().get(&path.hops.first().unwrap().short_channel_id) {
4860+ let first_chan_id = &path.hops.first().unwrap().short_channel_id;
4861+ let (counterparty_node_id, id) = match self
4862+ .short_to_chan_info
4863+ .read()
4864+ .unwrap()
4865+ .get(first_chan_id)
4866+ {
48404867 None => {
4841- let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
4842- log_error!(logger, "Failed to find first-hop for payment hash {}", payment_hash);
4843- return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()})
4868+ let first_hop_key = Some(path.hops.first().unwrap().pubkey);
4869+ let logger =
4870+ WithContext::from(&self.logger, first_hop_key, None, Some(*payment_hash));
4871+ log_error!(
4872+ logger,
4873+ "Failed to find first-hop for payment hash {}",
4874+ payment_hash
4875+ );
4876+ return Err(APIError::ChannelUnavailable {
4877+ err: "No channel available with first hop!".to_owned(),
4878+ });
48444879 },
48454880 Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
48464881 };
48474882
4848- let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(id), Some(*payment_hash));
4849- log_trace!(logger,
4883+ let logger = WithContext::from(
4884+ &self.logger,
4885+ Some(counterparty_node_id),
4886+ Some(id),
4887+ Some(*payment_hash),
4888+ );
4889+ log_trace!(
4890+ logger,
48504891 "Attempting to send payment with payment hash {} along path with next hop {}",
4851- payment_hash, path.hops.first().unwrap().short_channel_id);
4892+ payment_hash,
4893+ first_chan_id,
4894+ );
48524895
48534896 let per_peer_state = self.per_peer_state.read().unwrap();
4854- let peer_state_mutex = per_peer_state.get(&counterparty_node_id)
4855- .ok_or_else(|| APIError::ChannelUnavailable{err: "No peer matching the path's first hop found!".to_owned() })?;
4897+ let peer_state_mutex = per_peer_state.get(&counterparty_node_id).ok_or_else(|| {
4898+ APIError::ChannelUnavailable {
4899+ err: "No peer matching the path's first hop found!".to_owned(),
4900+ }
4901+ })?;
48564902 let mut peer_state_lock = peer_state_mutex.lock().unwrap();
48574903 let peer_state = &mut *peer_state_lock;
48584904 if let hash_map::Entry::Occupied(mut chan_entry) = peer_state.channel_by_id.entry(id) {
48594905 match chan_entry.get_mut().as_funded_mut() {
48604906 Some(chan) => {
48614907 if !chan.context.is_live() {
4862- return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected".to_owned()});
4908+ return Err(APIError::ChannelUnavailable {
4909+ err: "Peer for first hop currently disconnected".to_owned(),
4910+ });
48634911 }
48644912 let funding_txo = chan.funding.get_funding_txo().unwrap();
4865- let logger = WithChannelContext::from(&self.logger, &chan.context, Some(*payment_hash));
4866- let send_res = chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(),
4867- htlc_cltv, HTLCSource::OutboundRoute {
4868- path: path.clone(),
4869- session_priv: session_priv.clone(),
4870- first_hop_htlc_msat: htlc_msat,
4871- payment_id,
4872- bolt12_invoice: bolt12_invoice.cloned(),
4873- }, onion_packet, None, &self.fee_estimator, &&logger);
4913+ let logger = WithChannelContext::from(
4914+ &self.logger,
4915+ &chan.context,
4916+ Some(*payment_hash),
4917+ );
4918+ let htlc_source = HTLCSource::OutboundRoute {
4919+ path: path.clone(),
4920+ session_priv: session_priv.clone(),
4921+ first_hop_htlc_msat: htlc_msat,
4922+ payment_id,
4923+ bolt12_invoice: bolt12_invoice.cloned(),
4924+ };
4925+ let send_res = chan.send_htlc_and_commit(
4926+ htlc_msat,
4927+ payment_hash.clone(),
4928+ htlc_cltv,
4929+ htlc_source,
4930+ onion_packet,
4931+ None,
4932+ &self.fee_estimator,
4933+ &&logger,
4934+ );
48744935 match break_channel_entry!(self, peer_state, send_res, chan_entry) {
48754936 Some(monitor_update) => {
4876- match handle_new_monitor_update!(self, funding_txo, monitor_update, peer_state_lock, peer_state, per_peer_state, chan) {
4877- false => {
4878- // Note that MonitorUpdateInProgress here indicates (per function
4879- // docs) that we will resend the commitment update once monitor
4880- // updating completes. Therefore, we must return an error
4881- // indicating that it is unsafe to retry the payment wholesale,
4882- // which we do in the send_payment check for
4883- // MonitorUpdateInProgress, below.
4884- return Err(APIError::MonitorUpdateInProgress);
4885- },
4886- true => {},
4937+ let ok = handle_new_monitor_update!(
4938+ self,
4939+ funding_txo,
4940+ monitor_update,
4941+ peer_state_lock,
4942+ peer_state,
4943+ per_peer_state,
4944+ chan
4945+ );
4946+ if !ok {
4947+ // Note that MonitorUpdateInProgress here indicates (per function
4948+ // docs) that we will resend the commitment update once monitor
4949+ // updating completes. Therefore, we must return an error
4950+ // indicating that it is unsafe to retry the payment wholesale,
4951+ // which we do in the send_payment check for
4952+ // MonitorUpdateInProgress, below.
4953+ return Err(APIError::MonitorUpdateInProgress);
48874954 }
48884955 },
48894956 None => {},
48904957 }
48914958 },
4892- None => return Err(APIError::ChannelUnavailable{err: "Channel to first hop is unfunded".to_owned()}),
4959+ None => {
4960+ return Err(APIError::ChannelUnavailable {
4961+ err: "Channel to first hop is unfunded".to_owned(),
4962+ })
4963+ },
48934964 };
48944965 } else {
48954966 // The channel was likely removed after we fetched the id from the
48964967 // `short_to_chan_info` map, but before we successfully locked the
48974968 // `channel_by_id` map.
48984969 // This can occur as no consistency guarantees exists between the two maps.
4899- return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()});
4970+ return Err(APIError::ChannelUnavailable {
4971+ err: "No channel available with first hop!".to_owned(),
4972+ });
49004973 }
49014974 return Ok(());
49024975 };
49034976 match handle_error!(self, err, path.hops.first().unwrap().pubkey) {
49044977 Ok(_) => unreachable!(),
4905- Err(e) => {
4906- Err(APIError::ChannelUnavailable { err: e.err })
4907- },
4978+ Err(e) => Err(APIError::ChannelUnavailable { err: e.err }),
49084979 }
49094980 }
49104981
@@ -5966,60 +6037,89 @@ where
59666037 /// [`HTLCIntercepted::expected_outbound_amount_msat`]: events::Event::HTLCIntercepted::expected_outbound_amount_msat
59676038 // TODO: when we move to deciding the best outbound channel at forward time, only take
59686039 // `next_node_id` and not `next_hop_channel_id`
5969- #[rustfmt::skip]
5970- pub fn forward_intercepted_htlc(&self, intercept_id: InterceptId, next_hop_channel_id: &ChannelId, next_node_id: PublicKey, amt_to_forward_msat: u64) -> Result<(), APIError> {
6040+ pub fn forward_intercepted_htlc(
6041+ &self, intercept_id: InterceptId, next_hop_channel_id: &ChannelId, next_node_id: PublicKey,
6042+ amt_to_forward_msat: u64,
6043+ ) -> Result<(), APIError> {
59716044 let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
59726045
59736046 let next_hop_scid = {
59746047 let peer_state_lock = self.per_peer_state.read().unwrap();
5975- let peer_state_mutex = peer_state_lock.get(&next_node_id)
5976- .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", next_node_id) })?;
6048+ let peer_state_mutex =
6049+ peer_state_lock.get(&next_node_id).ok_or_else(|| APIError::ChannelUnavailable {
6050+ err: format!(
6051+ "Can't find a peer matching the passed counterparty node_id {}",
6052+ next_node_id
6053+ ),
6054+ })?;
59776055 let mut peer_state_lock = peer_state_mutex.lock().unwrap();
59786056 let peer_state = &mut *peer_state_lock;
59796057 match peer_state.channel_by_id.get(next_hop_channel_id) {
5980- Some(chan) => if let Some(funded_chan) = chan.as_funded() {
5981- if !funded_chan.context.is_usable() {
6058+ Some(chan) => {
6059+ if let Some(funded_chan) = chan.as_funded() {
6060+ if !funded_chan.context.is_usable() {
6061+ return Err(APIError::ChannelUnavailable {
6062+ err: format!(
6063+ "Channel with id {} not fully established",
6064+ next_hop_channel_id
6065+ ),
6066+ });
6067+ }
6068+ funded_chan
6069+ .funding
6070+ .get_short_channel_id()
6071+ .unwrap_or(funded_chan.context.outbound_scid_alias())
6072+ } else {
59826073 return Err(APIError::ChannelUnavailable {
5983- err: format!("Channel with id {} not fully established", next_hop_channel_id)
5984- })
5985- }
5986- funded_chan.funding.get_short_channel_id().unwrap_or(funded_chan.context.outbound_scid_alias())
5987- } else {
5988- return Err(APIError::ChannelUnavailable {
59896074 err: format!("Channel with id {} for the passed counterparty node_id {} is still opening.",
59906075 next_hop_channel_id, next_node_id)
5991- })
6076+ });
6077+ }
59926078 },
59936079 None => {
5994- let error = format!("Channel with id {} not found for the passed counterparty node_id {}",
5995- next_hop_channel_id, next_node_id);
5996- let logger = WithContext::from(&self.logger, Some(next_node_id), Some(*next_hop_channel_id), None);
6080+ let error = format!(
6081+ "Channel with id {} not found for the passed counterparty node_id {}",
6082+ next_hop_channel_id, next_node_id
6083+ );
6084+ let logger = WithContext::from(
6085+ &self.logger,
6086+ Some(next_node_id),
6087+ Some(*next_hop_channel_id),
6088+ None,
6089+ );
59976090 log_error!(logger, "{} when attempting to forward intercepted HTLC", error);
5998- return Err(APIError::ChannelUnavailable {
5999- err: error
6000- })
6091+ return Err(APIError::ChannelUnavailable { err: error });
60016092 },
60026093 }
60036094 };
60046095
6005- let payment = self.pending_intercepted_htlcs.lock().unwrap().remove(&intercept_id)
6096+ let payment = self
6097+ .pending_intercepted_htlcs
6098+ .lock()
6099+ .unwrap()
6100+ .remove(&intercept_id)
60066101 .ok_or_else(|| APIError::APIMisuseError {
6007- err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
6102+ err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0)),
60086103 })?;
60096104
60106105 let routing = match payment.forward_info.routing {
60116106 PendingHTLCRouting::Forward { onion_packet, blinded, incoming_cltv_expiry, .. } => {
60126107 PendingHTLCRouting::Forward {
6013- onion_packet, blinded, incoming_cltv_expiry, short_channel_id: next_hop_scid,
6108+ onion_packet,
6109+ blinded,
6110+ incoming_cltv_expiry,
6111+ short_channel_id: next_hop_scid,
60146112 }
60156113 },
6016- _ => unreachable!() // Only `PendingHTLCRouting::Forward`s are intercepted
6114+ _ => unreachable!(), // Only `PendingHTLCRouting::Forward`s are intercepted
60176115 };
60186116 let skimmed_fee_msat =
60196117 payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat);
60206118 let pending_htlc_info = PendingHTLCInfo {
60216119 skimmed_fee_msat: if skimmed_fee_msat == 0 { None } else { Some(skimmed_fee_msat) },
6022- outgoing_amt_msat: amt_to_forward_msat, routing, ..payment.forward_info
6120+ outgoing_amt_msat: amt_to_forward_msat,
6121+ routing,
6122+ ..payment.forward_info
60236123 };
60246124
60256125 let mut per_source_pending_forward = [(
@@ -6028,7 +6128,7 @@ where
60286128 payment.prev_funding_outpoint,
60296129 payment.prev_channel_id,
60306130 payment.prev_user_channel_id,
6031- vec![(pending_htlc_info, payment.prev_htlc_id)]
6131+ vec![(pending_htlc_info, payment.prev_htlc_id)],
60326132 )];
60336133 self.forward_htlcs(&mut per_source_pending_forward);
60346134 Ok(())
0 commit comments