@@ -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