Skip to content

Commit 596afd1

Browse files
Antoine RiardTheBlueMatt
Antoine Riard
authored andcommitted
Time out AwatingRemoteRAA outgoing HTLCs when we reach cltv_expiry
In case of committing out-of-time outgoing HTLCs, we force ourselves to close the channel to avoid remote peer claims on a non-backed HTLC
1 parent 66c8be9 commit 596afd1

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

lightning/src/ln/channel.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,12 +2979,24 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
29792979
}
29802980

29812981
/// Called by channelmanager based on chain blocks being connected.
2982-
/// Note that we only need to use this to detect funding_signed, anything else is handled by
2983-
/// the channel_monitor.
2982+
/// We need to use this to detect funding_signed and outgoing HTLC timed out before we were able
2983+
/// to commit them on remote commitment tx, anything else is handled by the channel_monitor.
29842984
/// In case of Err, the channel may have been closed, at which point the standard requirements
29852985
/// apply - no calls may be made except those explicitly stated to be allowed post-shutdown.
29862986
/// Only returns an ErrorAction of DisconnectPeer, if Err.
2987-
pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> {
2987+
pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash, u64)>), msgs::ErrorMessage> {
2988+
let mut timed_out_htlcs = Vec::new();
2989+
self.holding_cell_htlc_updates.retain(|htlc_update| {
2990+
match htlc_update {
2991+
&HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, ref amount_msat, .. } => {
2992+
if cltv_expiry <= &height { // XXX follow 0a4821b
2993+
timed_out_htlcs.push((source.clone(), payment_hash.clone(), *amount_msat));
2994+
false
2995+
} else { true }
2996+
},
2997+
_ => true
2998+
}
2999+
});
29883000
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
29893001
if header.bitcoin_hash() != self.last_block_connected {
29903002
if self.funding_tx_confirmations > 0 {
@@ -3064,19 +3076,19 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
30643076
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
30653077
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
30663078
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
3067-
return Ok(Some(msgs::FundingLocked {
3079+
return Ok((Some(msgs::FundingLocked {
30683080
channel_id: self.channel_id,
30693081
next_per_commitment_point: next_per_commitment_point,
3070-
}));
3082+
}), timed_out_htlcs));
30713083
} else {
30723084
self.monitor_pending_funding_locked = true;
3073-
return Ok(None);
3085+
return Ok((None, timed_out_htlcs));
30743086
}
30753087
}
30763088
}
30773089
}
30783090
}
3079-
Ok(None)
3091+
Ok((None, timed_out_htlcs))
30803092
}
30813093

30823094
/// Called by channelmanager based on chain blocks being disconnected.

lightning/src/ln/channelmanager.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2814,23 +2814,29 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send> ChainListener for ChannelM
28142814
let short_to_id = &mut channel_state.short_to_id;
28152815
let pending_msg_events = &mut channel_state.pending_msg_events;
28162816
channel_state.by_id.retain(|_, channel| {
2817-
let chan_res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched);
2818-
if let Ok(Some(funding_locked)) = chan_res {
2819-
pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
2820-
node_id: channel.get_their_node_id(),
2821-
msg: funding_locked,
2822-
});
2823-
if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
2824-
log_trace!(self, "Sending funding_locked and announcement_signatures for {}", log_bytes!(channel.channel_id()));
2825-
pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
2817+
let res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched);
2818+
if let Ok((chan_res, mut timed_out_pending_htlcs)) = res {
2819+
timed_out_htlcs.reserve(timed_out_pending_htlcs.len());
2820+
for (htlc_src, payment_hash, value) in timed_out_pending_htlcs.drain(..) {
2821+
timed_out_htlcs.push((htlc_src, payment_hash, value));
2822+
}
2823+
if let Some(funding_locked) = chan_res {
2824+
pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
28262825
node_id: channel.get_their_node_id(),
2827-
msg: announcement_sigs,
2826+
msg: funding_locked,
28282827
});
2829-
} else {
2830-
log_trace!(self, "Sending funding_locked WITHOUT announcement_signatures for {}", log_bytes!(channel.channel_id()));
2828+
if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
2829+
log_trace!(self, "Sending funding_locked and announcement_signatures for {}", log_bytes!(channel.channel_id()));
2830+
pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
2831+
node_id: channel.get_their_node_id(),
2832+
msg: announcement_sigs,
2833+
});
2834+
} else {
2835+
log_trace!(self, "Sending funding_locked WITHOUT announcement_signatures for {}", log_bytes!(channel.channel_id()));
2836+
}
2837+
short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
28312838
}
2832-
short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
2833-
} else if let Err(e) = chan_res {
2839+
} else if let Err(e) = res {
28342840
pending_msg_events.push(events::MessageSendEvent::HandleError {
28352841
node_id: channel.get_their_node_id(),
28362842
action: msgs::ErrorAction::SendErrorMessage { msg: e },

0 commit comments

Comments
 (0)