@@ -4828,65 +4828,139 @@ where
4828
4828
})
4829
4829
}
4830
4830
4831
- #[rustfmt::skip]
4832
4831
fn send_payment_along_path(&self, args: SendAlongPathArgs) -> Result<(), APIError> {
4833
4832
let SendAlongPathArgs {
4834
- path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
4835
- invoice_request, bolt12_invoice, session_priv_bytes
4833
+ path,
4834
+ payment_hash,
4835
+ recipient_onion,
4836
+ total_value,
4837
+ cur_height,
4838
+ payment_id,
4839
+ keysend_preimage,
4840
+ invoice_request,
4841
+ bolt12_invoice,
4842
+ session_priv_bytes,
4836
4843
} = args;
4837
4844
// The top-level caller should hold the total_consistency_lock read lock.
4838
4845
debug_assert!(self.total_consistency_lock.try_write().is_err());
4839
4846
let prng_seed = self.entropy_source.get_secure_random_bytes();
4840
4847
let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
4841
4848
4842
4849
let (onion_packet, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion(
4843
- &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height,
4844
- payment_hash, keysend_preimage, invoice_request, prng_seed
4845
- ).map_err(|e| {
4846
- let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
4847
- log_error!(logger, "Failed to build an onion for path for payment hash {}", payment_hash);
4850
+ &self.secp_ctx,
4851
+ &path,
4852
+ &session_priv,
4853
+ total_value,
4854
+ recipient_onion,
4855
+ cur_height,
4856
+ payment_hash,
4857
+ keysend_preimage,
4858
+ invoice_request,
4859
+ prng_seed,
4860
+ )
4861
+ .map_err(|e| {
4862
+ let logger = WithContext::from(
4863
+ &self.logger,
4864
+ Some(path.hops.first().unwrap().pubkey),
4865
+ None,
4866
+ Some(*payment_hash),
4867
+ );
4868
+ log_error!(
4869
+ logger,
4870
+ "Failed to build an onion for path for payment hash {}",
4871
+ payment_hash
4872
+ );
4848
4873
e
4849
4874
})?;
4850
4875
4851
4876
let err: Result<(), _> = loop {
4852
- let (counterparty_node_id, id) = match self.short_to_chan_info.read().unwrap().get(&path.hops.first().unwrap().short_channel_id) {
4877
+ let (counterparty_node_id, id) = match self
4878
+ .short_to_chan_info
4879
+ .read()
4880
+ .unwrap()
4881
+ .get(&path.hops.first().unwrap().short_channel_id)
4882
+ {
4853
4883
None => {
4854
- let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash));
4855
- log_error!(logger, "Failed to find first-hop for payment hash {}", payment_hash);
4856
- return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()})
4884
+ let logger = WithContext::from(
4885
+ &self.logger,
4886
+ Some(path.hops.first().unwrap().pubkey),
4887
+ None,
4888
+ Some(*payment_hash),
4889
+ );
4890
+ log_error!(
4891
+ logger,
4892
+ "Failed to find first-hop for payment hash {}",
4893
+ payment_hash
4894
+ );
4895
+ return Err(APIError::ChannelUnavailable {
4896
+ err: "No channel available with first hop!".to_owned(),
4897
+ });
4857
4898
},
4858
4899
Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()),
4859
4900
};
4860
4901
4861
- let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(id), Some(*payment_hash));
4862
- log_trace!(logger,
4902
+ let logger = WithContext::from(
4903
+ &self.logger,
4904
+ Some(counterparty_node_id),
4905
+ Some(id),
4906
+ Some(*payment_hash),
4907
+ );
4908
+ log_trace!(
4909
+ logger,
4863
4910
"Attempting to send payment with payment hash {} along path with next hop {}",
4864
- payment_hash, path.hops.first().unwrap().short_channel_id);
4911
+ payment_hash,
4912
+ path.hops.first().unwrap().short_channel_id
4913
+ );
4865
4914
4866
4915
let per_peer_state = self.per_peer_state.read().unwrap();
4867
- let peer_state_mutex = per_peer_state.get(&counterparty_node_id)
4868
- .ok_or_else(|| APIError::ChannelUnavailable{err: "No peer matching the path's first hop found!".to_owned() })?;
4916
+ let peer_state_mutex = per_peer_state.get(&counterparty_node_id).ok_or_else(|| {
4917
+ APIError::ChannelUnavailable {
4918
+ err: "No peer matching the path's first hop found!".to_owned(),
4919
+ }
4920
+ })?;
4869
4921
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4870
4922
let peer_state = &mut *peer_state_lock;
4871
4923
if let hash_map::Entry::Occupied(mut chan_entry) = peer_state.channel_by_id.entry(id) {
4872
4924
match chan_entry.get_mut().as_funded_mut() {
4873
4925
Some(chan) => {
4874
4926
if !chan.context.is_live() {
4875
- return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected".to_owned()});
4927
+ return Err(APIError::ChannelUnavailable {
4928
+ err: "Peer for first hop currently disconnected".to_owned(),
4929
+ });
4876
4930
}
4877
4931
let funding_txo = chan.funding.get_funding_txo().unwrap();
4878
- let logger = WithChannelContext::from(&self.logger, &chan.context, Some(*payment_hash));
4879
- let send_res = chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(),
4880
- htlc_cltv, HTLCSource::OutboundRoute {
4932
+ let logger = WithChannelContext::from(
4933
+ &self.logger,
4934
+ &chan.context,
4935
+ Some(*payment_hash),
4936
+ );
4937
+ let send_res = chan.send_htlc_and_commit(
4938
+ htlc_msat,
4939
+ payment_hash.clone(),
4940
+ htlc_cltv,
4941
+ HTLCSource::OutboundRoute {
4881
4942
path: path.clone(),
4882
4943
session_priv: session_priv.clone(),
4883
4944
first_hop_htlc_msat: htlc_msat,
4884
4945
payment_id,
4885
4946
bolt12_invoice: bolt12_invoice.cloned(),
4886
- }, onion_packet, None, &self.fee_estimator, &&logger);
4947
+ },
4948
+ onion_packet,
4949
+ None,
4950
+ &self.fee_estimator,
4951
+ &&logger,
4952
+ );
4887
4953
match break_channel_entry!(self, peer_state, send_res, chan_entry) {
4888
4954
Some(monitor_update) => {
4889
- match handle_new_monitor_update!(self, funding_txo, monitor_update, peer_state_lock, peer_state, per_peer_state, chan) {
4955
+ match handle_new_monitor_update!(
4956
+ self,
4957
+ funding_txo,
4958
+ monitor_update,
4959
+ peer_state_lock,
4960
+ peer_state,
4961
+ per_peer_state,
4962
+ chan
4963
+ ) {
4890
4964
false => {
4891
4965
// Note that MonitorUpdateInProgress here indicates (per function
4892
4966
// docs) that we will resend the commitment update once monitor
@@ -4902,22 +4976,26 @@ where
4902
4976
None => {},
4903
4977
}
4904
4978
},
4905
- None => return Err(APIError::ChannelUnavailable{err: "Channel to first hop is unfunded".to_owned()}),
4979
+ None => {
4980
+ return Err(APIError::ChannelUnavailable {
4981
+ err: "Channel to first hop is unfunded".to_owned(),
4982
+ })
4983
+ },
4906
4984
};
4907
4985
} else {
4908
4986
// The channel was likely removed after we fetched the id from the
4909
4987
// `short_to_chan_info` map, but before we successfully locked the
4910
4988
// `channel_by_id` map.
4911
4989
// This can occur as no consistency guarantees exists between the two maps.
4912
- return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()});
4990
+ return Err(APIError::ChannelUnavailable {
4991
+ err: "No channel available with first hop!".to_owned(),
4992
+ });
4913
4993
}
4914
4994
return Ok(());
4915
4995
};
4916
4996
match handle_error!(self, err, path.hops.first().unwrap().pubkey) {
4917
4997
Ok(_) => unreachable!(),
4918
- Err(e) => {
4919
- Err(APIError::ChannelUnavailable { err: e.err })
4920
- },
4998
+ Err(e) => Err(APIError::ChannelUnavailable { err: e.err }),
4921
4999
}
4922
5000
}
4923
5001
@@ -5979,60 +6057,89 @@ where
5979
6057
/// [`HTLCIntercepted::expected_outbound_amount_msat`]: events::Event::HTLCIntercepted::expected_outbound_amount_msat
5980
6058
// TODO: when we move to deciding the best outbound channel at forward time, only take
5981
6059
// `next_node_id` and not `next_hop_channel_id`
5982
- #[rustfmt::skip]
5983
- 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> {
6060
+ pub fn forward_intercepted_htlc(
6061
+ &self, intercept_id: InterceptId, next_hop_channel_id: &ChannelId, next_node_id: PublicKey,
6062
+ amt_to_forward_msat: u64,
6063
+ ) -> Result<(), APIError> {
5984
6064
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
5985
6065
5986
6066
let next_hop_scid = {
5987
6067
let peer_state_lock = self.per_peer_state.read().unwrap();
5988
- let peer_state_mutex = peer_state_lock.get(&next_node_id)
5989
- .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", next_node_id) })?;
6068
+ let peer_state_mutex =
6069
+ peer_state_lock.get(&next_node_id).ok_or_else(|| APIError::ChannelUnavailable {
6070
+ err: format!(
6071
+ "Can't find a peer matching the passed counterparty node_id {}",
6072
+ next_node_id
6073
+ ),
6074
+ })?;
5990
6075
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
5991
6076
let peer_state = &mut *peer_state_lock;
5992
6077
match peer_state.channel_by_id.get(next_hop_channel_id) {
5993
- Some(chan) => if let Some(funded_chan) = chan.as_funded() {
5994
- if !funded_chan.context.is_usable() {
6078
+ Some(chan) => {
6079
+ if let Some(funded_chan) = chan.as_funded() {
6080
+ if !funded_chan.context.is_usable() {
6081
+ return Err(APIError::ChannelUnavailable {
6082
+ err: format!(
6083
+ "Channel with id {} not fully established",
6084
+ next_hop_channel_id
6085
+ ),
6086
+ });
6087
+ }
6088
+ funded_chan
6089
+ .funding
6090
+ .get_short_channel_id()
6091
+ .unwrap_or(funded_chan.context.outbound_scid_alias())
6092
+ } else {
5995
6093
return Err(APIError::ChannelUnavailable {
5996
- err: format!("Channel with id {} not fully established", next_hop_channel_id)
5997
- })
5998
- }
5999
- funded_chan.funding.get_short_channel_id().unwrap_or(funded_chan.context.outbound_scid_alias())
6000
- } else {
6001
- return Err(APIError::ChannelUnavailable {
6002
6094
err: format!("Channel with id {} for the passed counterparty node_id {} is still opening.",
6003
6095
next_hop_channel_id, next_node_id)
6004
- })
6096
+ });
6097
+ }
6005
6098
},
6006
6099
None => {
6007
- let error = format!("Channel with id {} not found for the passed counterparty node_id {}",
6008
- next_hop_channel_id, next_node_id);
6009
- let logger = WithContext::from(&self.logger, Some(next_node_id), Some(*next_hop_channel_id), None);
6100
+ let error = format!(
6101
+ "Channel with id {} not found for the passed counterparty node_id {}",
6102
+ next_hop_channel_id, next_node_id
6103
+ );
6104
+ let logger = WithContext::from(
6105
+ &self.logger,
6106
+ Some(next_node_id),
6107
+ Some(*next_hop_channel_id),
6108
+ None,
6109
+ );
6010
6110
log_error!(logger, "{} when attempting to forward intercepted HTLC", error);
6011
- return Err(APIError::ChannelUnavailable {
6012
- err: error
6013
- })
6111
+ return Err(APIError::ChannelUnavailable { err: error });
6014
6112
},
6015
6113
}
6016
6114
};
6017
6115
6018
- let payment = self.pending_intercepted_htlcs.lock().unwrap().remove(&intercept_id)
6116
+ let payment = self
6117
+ .pending_intercepted_htlcs
6118
+ .lock()
6119
+ .unwrap()
6120
+ .remove(&intercept_id)
6019
6121
.ok_or_else(|| APIError::APIMisuseError {
6020
- err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
6122
+ err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0)),
6021
6123
})?;
6022
6124
6023
6125
let routing = match payment.forward_info.routing {
6024
6126
PendingHTLCRouting::Forward { onion_packet, blinded, incoming_cltv_expiry, .. } => {
6025
6127
PendingHTLCRouting::Forward {
6026
- onion_packet, blinded, incoming_cltv_expiry, short_channel_id: next_hop_scid,
6128
+ onion_packet,
6129
+ blinded,
6130
+ incoming_cltv_expiry,
6131
+ short_channel_id: next_hop_scid,
6027
6132
}
6028
6133
},
6029
- _ => unreachable!() // Only `PendingHTLCRouting::Forward`s are intercepted
6134
+ _ => unreachable!(), // Only `PendingHTLCRouting::Forward`s are intercepted
6030
6135
};
6031
6136
let skimmed_fee_msat =
6032
6137
payment.forward_info.outgoing_amt_msat.saturating_sub(amt_to_forward_msat);
6033
6138
let pending_htlc_info = PendingHTLCInfo {
6034
6139
skimmed_fee_msat: if skimmed_fee_msat == 0 { None } else { Some(skimmed_fee_msat) },
6035
- outgoing_amt_msat: amt_to_forward_msat, routing, ..payment.forward_info
6140
+ outgoing_amt_msat: amt_to_forward_msat,
6141
+ routing,
6142
+ ..payment.forward_info
6036
6143
};
6037
6144
6038
6145
let mut per_source_pending_forward = [(
@@ -6041,7 +6148,7 @@ where
6041
6148
payment.prev_funding_outpoint,
6042
6149
payment.prev_channel_id,
6043
6150
payment.prev_user_channel_id,
6044
- vec![(pending_htlc_info, payment.prev_htlc_id)]
6151
+ vec![(pending_htlc_info, payment.prev_htlc_id)],
6045
6152
)];
6046
6153
self.forward_htlcs(&mut per_source_pending_forward);
6047
6154
Ok(())
0 commit comments