Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,7 @@ pub(super) struct ReestablishResponses {
pub shutdown_msg: Option<msgs::Shutdown>,
pub tx_signatures: Option<msgs::TxSignatures>,
pub tx_abort: Option<msgs::TxAbort>,
pub splice_locked: Option<msgs::SpliceLocked>,
pub inferred_splice_locked: Option<msgs::SpliceLocked>,
}

Expand Down Expand Up @@ -3503,6 +3504,12 @@ pub(super) struct ChannelContext<SP: SignerProvider> {
/// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
pub workaround_lnd_bug_4006: Option<msgs::ChannelReady>,

/// The `my_current_funding_locked` txid included in our `channel_reestablish` for the current
/// reconnect, if any. We track this as we cannot tell what was included after we've already
/// sent it, as it's possible it was unconfirmed at the time we sent it, but confirmed shortly
/// after.
funding_locked_txid_sent_in_reestablish: Option<Txid>,

/// An option set when we wish to track how many ticks have elapsed while waiting for a response
/// from our counterparty after entering specific states. If the peer has yet to respond after
/// reaching `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`, a reconnection should be attempted to
Expand Down Expand Up @@ -4225,6 +4232,7 @@ impl<SP: SignerProvider> ChannelContext<SP> {
announcement_sigs: None,

workaround_lnd_bug_4006: None,
funding_locked_txid_sent_in_reestablish: None,
sent_message_awaiting_response: None,

latest_inbound_scid_alias: None,
Expand Down Expand Up @@ -4536,6 +4544,7 @@ impl<SP: SignerProvider> ChannelContext<SP> {
announcement_sigs: None,

workaround_lnd_bug_4006: None,
funding_locked_txid_sent_in_reestablish: None,
sent_message_awaiting_response: None,

latest_inbound_scid_alias: None,
Expand Down Expand Up @@ -10512,6 +10521,8 @@ where
// remaining cases either succeed or ErrorMessage-fail).
self.context.channel_state.clear_peer_disconnected();
self.mark_response_received();
let funding_locked_txid_sent_in_reestablish =
self.context.funding_locked_txid_sent_in_reestablish.take();

let shutdown_msg = self.get_outbound_shutdown();

Expand Down Expand Up @@ -10663,6 +10674,7 @@ where
shutdown_msg, announcement_sigs,
tx_signatures,
tx_abort: None,
splice_locked: None,
inferred_splice_locked: None,
});
}
Expand All @@ -10676,6 +10688,7 @@ where
shutdown_msg, announcement_sigs,
tx_signatures,
tx_abort,
splice_locked: None,
inferred_splice_locked: None,
});
}
Expand Down Expand Up @@ -10745,6 +10758,15 @@ where
splice_txid,
})
});
let splice_locked = self.pending_splice.as_ref().and_then(|pending_splice| {
pending_splice
.sent_funding_txid
.filter(|splice_txid| Some(*splice_txid) != funding_locked_txid_sent_in_reestablish)
.map(|splice_txid| msgs::SpliceLocked {
channel_id: self.context.channel_id,
splice_txid,
})
});

if msg.next_local_commitment_number == next_counterparty_commitment_number {
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
Expand All @@ -10763,6 +10785,7 @@ where
commitment_order: self.context.resend_order.clone(),
tx_signatures,
tx_abort,
splice_locked,
inferred_splice_locked,
})
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
Expand All @@ -10788,6 +10811,7 @@ where
commitment_order: self.context.resend_order.clone(),
tx_signatures: None,
tx_abort,
splice_locked,
inferred_splice_locked,
})
} else {
Expand Down Expand Up @@ -10815,6 +10839,7 @@ where
commitment_order: self.context.resend_order.clone(),
tx_signatures: None,
tx_abort,
splice_locked,
inferred_splice_locked,
})
}
Expand Down Expand Up @@ -12492,6 +12517,9 @@ where
log_info!(logger, "Sending a data_loss_protect with no previous remote per_commitment_secret for channel {}", &self.context.channel_id());
[0;32]
};
let my_current_funding_locked = self.maybe_get_my_current_funding_locked();
self.context.funding_locked_txid_sent_in_reestablish =
my_current_funding_locked.as_ref().map(|funding_locked| funding_locked.txid);
msgs::ChannelReestablish {
channel_id: self.context.channel_id(),
// The protocol has two different commitment number concepts - the "commitment
Expand All @@ -12515,7 +12543,7 @@ where
your_last_per_commitment_secret: remote_last_secret,
my_current_per_commitment_point: dummy_pubkey,
next_funding: self.maybe_get_next_funding(),
my_current_funding_locked: self.maybe_get_my_current_funding_locked(),
my_current_funding_locked,
}
}

Expand Down Expand Up @@ -17196,6 +17224,7 @@ impl<'a, 'b, 'c, ES: EntropySource, SP: SignerProvider>
announcement_sigs,

workaround_lnd_bug_4006: None,
funding_locked_txid_sent_in_reestablish: None,
sent_message_awaiting_response: None,

latest_inbound_scid_alias,
Expand Down
78 changes: 56 additions & 22 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12365,6 +12365,14 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
})?;
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
self.internal_channel_ready_with_peer_state(counterparty_node_id, msg, peer_state)
}

#[rustfmt::skip]
fn internal_channel_ready_with_peer_state(
&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady,
peer_state: &mut PeerState<SP>,
) -> Result<(), MsgHandleErrInternal> {
match peer_state.channel_by_id.entry(msg.channel_id) {
hash_map::Entry::Occupied(mut chan_entry) => {
if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
Expand Down Expand Up @@ -13240,7 +13248,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/

#[rustfmt::skip]
fn internal_channel_reestablish(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
let (inferred_splice_locked, need_lnd_workaround, holding_cell_res) = {
let (post_splice_locked_update, holding_cell_res) = {
let per_peer_state = self.per_peer_state.read().unwrap();

let peer_state_mutex = per_peer_state.get(counterparty_node_id).ok_or_else(|| {
Expand All @@ -13249,7 +13257,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id), None);
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
match peer_state.channel_by_id.entry(msg.channel_id) {
let (inferred_splice_locked, need_lnd_workaround) = match peer_state.channel_by_id.entry(msg.channel_id) {
hash_map::Entry::Occupied(mut chan_entry) => {
if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
// Currently, we expect all holding cell update_adds to be dropped on peer
Expand Down Expand Up @@ -13285,10 +13293,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
}
}
let need_lnd_workaround = chan.context.workaround_lnd_bug_4006.take();
let funding_tx_signed = responses.tx_signatures.map(|tx_signatures| FundingTxSigned {
tx_signatures: Some(tx_signatures),
..Default::default()
});
let funding_tx_signed = if responses.tx_signatures.is_some() || responses.splice_locked.is_some() {
Some(FundingTxSigned {
tx_signatures: responses.tx_signatures,
splice_locked: responses.splice_locked,
..Default::default()
})
} else {
None
};
let (htlc_forwards, decode_update_add_htlcs) = self.handle_channel_resumption(
&mut peer_state.pending_msg_events, chan, responses.raa, responses.commitment_update, responses.commitment_order,
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs,
Expand All @@ -13300,8 +13313,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
peer_state.pending_msg_events.push(upd);
}

let holding_cell_res = self.check_free_peer_holding_cells(peer_state);
(responses.inferred_splice_locked, need_lnd_workaround, holding_cell_res)
(responses.inferred_splice_locked, need_lnd_workaround)
} else {
return try_channel_entry!(self, peer_state, Err(ChannelError::close(
"Got a channel_reestablish message for an unfunded channel!".into())), chan_entry);
Expand Down Expand Up @@ -13339,18 +13351,28 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
return Err(MsgHandleErrInternal::no_such_channel_for_peer(counterparty_node_id, msg.channel_id)
)
}
};

if let Some(channel_ready_msg) = need_lnd_workaround {
self.internal_channel_ready_with_peer_state(counterparty_node_id, &channel_ready_msg, peer_state)?;
}
};

self.handle_holding_cell_free_result(holding_cell_res);
// A reestablish may infer a missed `splice_locked`; apply it before freeing holding
// cells so we don't generate commitment updates against stale splice state.
let post_splice_locked_update = if let Some(splice_locked) = inferred_splice_locked {
self.internal_splice_locked_with_peer_state(counterparty_node_id, &splice_locked, peer_state)?
} else {
None
};

if let Some(channel_ready_msg) = need_lnd_workaround {
self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?;
}
let holding_cell_res = self.check_free_peer_holding_cells(peer_state);
(post_splice_locked_update, holding_cell_res)
};

if let Some(splice_locked) = inferred_splice_locked {
self.internal_splice_locked(counterparty_node_id, &splice_locked)?;
if let Some(data) = post_splice_locked_update {
self.handle_post_monitor_update_chan_resume(data);
}
self.handle_holding_cell_free_result(holding_cell_res);

Ok(())
}
Expand Down Expand Up @@ -13580,8 +13602,24 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
})?;
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
let post_update_data =
self.internal_splice_locked_with_peer_state(counterparty_node_id, msg, peer_state)?;
mem::drop(peer_state_lock);
mem::drop(per_peer_state);

if let Some(data) = post_update_data {
self.handle_post_monitor_update_chan_resume(data);
}

Ok(())
}

fn internal_splice_locked_with_peer_state(
&self, counterparty_node_id: &PublicKey, msg: &msgs::SpliceLocked,
peer_state: &mut PeerState<SP>,
) -> Result<Option<PostMonitorUpdateChanResume>, MsgHandleErrInternal> {
// Look for the channel
let mut post_update_data = None;
match peer_state.channel_by_id.entry(msg.channel_id) {
hash_map::Entry::Vacant(_) => {
return Err(MsgHandleErrInternal::no_such_channel_for_peer(
Expand Down Expand Up @@ -13643,19 +13681,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
}

if let Some(monitor_update) = splice_promotion.monitor_update {
if let Some(data) = self.handle_new_monitor_update(
post_update_data = self.handle_new_monitor_update(
&mut peer_state.in_flight_monitor_updates,
&mut peer_state.monitor_update_blocked_actions,
&mut peer_state.pending_msg_events,
peer_state.is_connected,
chan,
splice_promotion.funding_txo,
monitor_update,
) {
mem::drop(peer_state_lock);
mem::drop(per_peer_state);
self.handle_post_monitor_update_chan_resume(data);
}
);
}
}
} else {
Expand All @@ -13667,7 +13701,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
},
};

Ok(())
Ok(post_update_data)
}

/// Process pending events from the [`chain::Watch`], returning whether any events were processed.
Expand Down
Loading
Loading