Skip to content

Commit 6c984bf

Browse files
committed
Decode HTLCFailReasons in a util method on the enum
1 parent 9a2e26b commit 6c984bf

File tree

1 file changed

+51
-73
lines changed

1 file changed

+51
-73
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,26 @@ impl HTLCFailReason {
326326
}
327327
}
328328
}
329+
330+
fn decode_onion_failure<T: secp256k1::Signing, L: Deref>(&self, secp_ctx: &Secp256k1<T>, logger: &L, htlc_source: &HTLCSource) -> (Option<crate::routing::gossip::NetworkUpdate>, Option<u64>, bool, Option<u16>, Option<Vec<u8>>) where L::Target: Logger {
331+
match self {
332+
HTLCFailReason::LightningError { ref err } => {
333+
onion_utils::process_onion_failure(secp_ctx, logger, &htlc_source, err.data.clone())
334+
},
335+
HTLCFailReason::Reason { ref failure_code, ref data, .. } => {
336+
// we get a fail_malformed_htlc from the first hop
337+
// TODO: We'd like to generate a NetworkUpdate for temporary
338+
// failures here, but that would be insufficient as find_route
339+
// generally ignores its view of our own channels as we provide them via
340+
// ChannelDetails.
341+
// TODO: For non-temporary failures, we really should be closing the
342+
// channel here as we apparently can't relay through them anyway.
343+
if let &HTLCSource::OutboundRoute { ref path, .. } = htlc_source {
344+
(None, Some(path.first().unwrap().short_channel_id), true, Some(*failure_code), Some(data.clone()))
345+
} else { unreachable!(); }
346+
}
347+
}
348+
}
329349
}
330350

331351
struct ReceiveError {
@@ -4080,90 +4100,48 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
40804100
} else { None };
40814101
log_trace!(self.logger, "Failing outbound payment HTLC with payment_hash {}", log_bytes!(payment_hash.0));
40824102

4083-
let path_failure = match &onion_error {
4084-
&HTLCFailReason::LightningError { ref err } => {
4103+
let path_failure = {
40854104
#[cfg(test)]
4086-
let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
4105+
let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(&self.secp_ctx, &self.logger, &source);
40874106
#[cfg(not(test))]
4088-
let (network_update, short_channel_id, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
4089-
4090-
if self.payment_is_probe(payment_hash, &payment_id) {
4091-
if !payment_retryable {
4092-
events::Event::ProbeSuccessful {
4093-
payment_id: *payment_id,
4094-
payment_hash: payment_hash.clone(),
4095-
path: path.clone(),
4096-
}
4097-
} else {
4098-
events::Event::ProbeFailed {
4099-
payment_id: *payment_id,
4100-
payment_hash: payment_hash.clone(),
4101-
path: path.clone(),
4102-
short_channel_id,
4103-
}
4104-
}
4105-
} else {
4106-
// TODO: If we decided to blame ourselves (or one of our channels) in
4107-
// process_onion_failure we should close that channel as it implies our
4108-
// next-hop is needlessly blaming us!
4109-
if let Some(scid) = short_channel_id {
4110-
retry.as_mut().map(|r| r.payment_params.previously_failed_channels.push(scid));
4111-
}
4112-
events::Event::PaymentPathFailed {
4113-
payment_id: Some(*payment_id),
4114-
payment_hash: payment_hash.clone(),
4115-
payment_failed_permanently: !payment_retryable,
4116-
network_update,
4117-
all_paths_failed,
4118-
path: path.clone(),
4119-
short_channel_id,
4120-
retry,
4121-
#[cfg(test)]
4122-
error_code: onion_error_code,
4123-
#[cfg(test)]
4124-
error_data: onion_error_data
4125-
}
4126-
}
4127-
},
4128-
&HTLCFailReason::Reason {
4129-
#[cfg(test)]
4130-
ref failure_code,
4131-
#[cfg(test)]
4132-
ref data,
4133-
.. } => {
4134-
// we get a fail_malformed_htlc from the first hop
4135-
// TODO: We'd like to generate a NetworkUpdate for temporary
4136-
// failures here, but that would be insufficient as find_route
4137-
// generally ignores its view of our own channels as we provide them via
4138-
// ChannelDetails.
4139-
// TODO: For non-temporary failures, we really should be closing the
4140-
// channel here as we apparently can't relay through them anyway.
4141-
let scid = path.first().unwrap().short_channel_id;
4142-
retry.as_mut().map(|r| r.payment_params.previously_failed_channels.push(scid));
4143-
4144-
if self.payment_is_probe(payment_hash, &payment_id) {
4145-
events::Event::ProbeFailed {
4107+
let (network_update, short_channel_id, payment_retryable, _, _) = onion_error.decode_onion_failure(&self.secp_ctx, &self.logger, &source);
4108+
4109+
if self.payment_is_probe(payment_hash, &payment_id) {
4110+
if !payment_retryable {
4111+
events::Event::ProbeSuccessful {
41464112
payment_id: *payment_id,
41474113
payment_hash: payment_hash.clone(),
41484114
path: path.clone(),
4149-
short_channel_id: Some(scid),
41504115
}
41514116
} else {
4152-
events::Event::PaymentPathFailed {
4153-
payment_id: Some(*payment_id),
4117+
events::Event::ProbeFailed {
4118+
payment_id: *payment_id,
41544119
payment_hash: payment_hash.clone(),
4155-
payment_failed_permanently: false,
4156-
network_update: None,
4157-
all_paths_failed,
41584120
path: path.clone(),
4159-
short_channel_id: Some(scid),
4160-
retry,
4161-
#[cfg(test)]
4162-
error_code: Some(*failure_code),
4163-
#[cfg(test)]
4164-
error_data: Some(data.clone()),
4121+
short_channel_id,
41654122
}
41664123
}
4124+
} else {
4125+
// TODO: If we decided to blame ourselves (or one of our channels) in
4126+
// process_onion_failure we should close that channel as it implies our
4127+
// next-hop is needlessly blaming us!
4128+
if let Some(scid) = short_channel_id {
4129+
retry.as_mut().map(|r| r.payment_params.previously_failed_channels.push(scid));
4130+
}
4131+
events::Event::PaymentPathFailed {
4132+
payment_id: Some(*payment_id),
4133+
payment_hash: payment_hash.clone(),
4134+
payment_failed_permanently: !payment_retryable,
4135+
network_update,
4136+
all_paths_failed,
4137+
path: path.clone(),
4138+
short_channel_id,
4139+
retry,
4140+
#[cfg(test)]
4141+
error_code: onion_error_code,
4142+
#[cfg(test)]
4143+
error_data: onion_error_data
4144+
}
41674145
}
41684146
};
41694147
let mut pending_events = self.pending_events.lock().unwrap();

0 commit comments

Comments
 (0)