use ln::msgs;
use ln::msgs::{ErrorAction, HandleError, MsgEncodable};
use ln::channelmonitor::ChannelMonitor;
-use ln::channelmanager::{PendingHTLCStatus, PendingForwardHTLCInfo, HTLCFailReason};
+use ln::channelmanager::{PendingHTLCStatus, PendingForwardHTLCInfo, HTLCFailReason, HTLCFailureMsg};
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
let mut to_forward_infos = Vec::new();
let mut revoked_htlcs = Vec::new();
- let mut failed_htlcs = Vec::new();
+ let mut update_fail_htlcs = Vec::new();
+ let mut update_fail_malformed_htlcs = Vec::new();
let mut require_commitment = false;
let mut value_to_self_msat_diff: i64 = 0;
// We really shouldnt have two passes here, but retain gives a non-mutable ref (Rust bug)
PendingHTLCStatus::Fail(fail_msg) => {
htlc.state = HTLCState::LocalRemoved;
require_commitment = true;
- failed_htlcs.push(fail_msg);
+ match fail_msg {
+ HTLCFailureMsg::Relay(msg) => update_fail_htlcs.push(msg),
+ HTLCFailureMsg::Malformed(msg) => update_fail_malformed_htlcs.push(msg),
+ }
},
PendingHTLCStatus::Forward(forward_info) => {
to_forward_infos.push(forward_info);
match self.free_holding_cell_htlcs()? {
Some(mut commitment_update) => {
- commitment_update.0.update_fail_htlcs.reserve(failed_htlcs.len());
- for fail_msg in failed_htlcs.drain(..) {
+ commitment_update.0.update_fail_htlcs.reserve(update_fail_htlcs.len());
+ for fail_msg in update_fail_htlcs.drain(..) {
commitment_update.0.update_fail_htlcs.push(fail_msg);
}
+ commitment_update.0.update_fail_malformed_htlcs.reserve(update_fail_malformed_htlcs.len());
+ for fail_msg in update_fail_malformed_htlcs.drain(..) {
+ commitment_update.0.update_fail_malformed_htlcs.push(fail_msg);
+ }
Ok((Some(commitment_update.0), to_forward_infos, revoked_htlcs, commitment_update.1))
},
None => {
Ok((Some(msgs::CommitmentUpdate {
update_add_htlcs: Vec::new(),
update_fulfill_htlcs: Vec::new(),
- update_fail_htlcs: failed_htlcs,
- update_fail_malformed_htlcs: Vec::new(),
+ update_fail_htlcs,
+ update_fail_malformed_htlcs,
commitment_signed
}), to_forward_infos, revoked_htlcs, monitor_update))
} else {
pub(super) outgoing_cltv_value: u32,
}
+ #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
+ pub enum HTLCFailureMsg {
+ Relay(msgs::UpdateFailHTLC),
+ Malformed(msgs::UpdateFailMalformedHTLC),
+ }
+
/// Stores whether we can't forward an HTLC or relevant forwarding info
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
pub enum PendingHTLCStatus {
Forward(PendingForwardHTLCInfo),
- Fail(msgs::UpdateFailHTLC),
+ Fail(HTLCFailureMsg),
}
#[cfg(feature = "fuzztarget")]
if channel_state.is_none() {
channel_state = Some(self.channel_state.lock().unwrap());
}
- return (PendingHTLCStatus::Fail(msgs::UpdateFailHTLC {
+ return (PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
channel_id: msg.channel_id,
htlc_id: msg.htlc_id,
reason: ChannelManager::build_first_hop_failure_packet(&shared_secret, $err_code, $data),
- }), shared_secret, channel_state.unwrap());
+ })), shared_secret, channel_state.unwrap());
}
}
}
}
if !acceptable_cycle {
log_info!(self, "Failed to accept incoming HTLC: Payment looped through us twice");
- pending_forward_info = PendingHTLCStatus::Fail(msgs::UpdateFailHTLC {
+ pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
channel_id: msg.channel_id,
htlc_id: msg.htlc_id,
reason: ChannelManager::build_first_hop_failure_packet(&shared_secret, 0x4000 | 0x2000 | 2, &[0;0]),
- });
+ }));
} else {
will_forward = true;
}