Skip to content

Commit 649b29b

Browse files
jkczyzwpaulino
andcommitted
Update next_funding_txid logic for channel_reestablish
The splicing spec updates the logic pertaining to next_funding_txid when handling a channel_reestablish message. Specifically: A receiving node: - if `next_funding_txid` is set: - if `next_funding_txid` matches the latest interactive funding transaction or the current channel funding transaction: - if `next_commitment_number` is equal to the commitment number of the `commitment_signed` message it sent for this funding transaction: - MUST retransmit its `commitment_signed` for that funding transaction. - if it has already received `commitment_signed` and it should sign first, as specified in the [`tx_signatures` requirements](#the-tx_signatures-message): - MUST send its `tx_signatures` for that funding transaction. - if it has already received `tx_signatures` for that funding transaction: - MUST send its `tx_signatures` for that funding transaction. - if it also sets `next_funding_txid` in its own `channel_reestablish`, but the values don't match: - MUST send an `error` and fail the channel. - otherwise: - MUST send `tx_abort` to let the sending node know that they can forget this funding transaction. This commit updates FundedChannel::channel_reestablish accordingly. Co-authored-by: Wilmer Paulino <[email protected]> Co-authored-by: Jeffrey Czyz <[email protected]>
1 parent 53c9f09 commit 649b29b

File tree

1 file changed

+102
-81
lines changed

1 file changed

+102
-81
lines changed

lightning/src/ln/channel.rs

Lines changed: 102 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -8808,91 +8808,107 @@ where
88088808
.and_then(|_| self.get_channel_ready(logger))
88098809
} else { None };
88108810

8811-
if msg.next_local_commitment_number == next_counterparty_commitment_number {
8812-
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
8813-
log_debug!(logger, "Reconnected channel {} with only lost outbound RAA", &self.context.channel_id());
8814-
} else {
8815-
log_debug!(logger, "Reconnected channel {} with no loss", &self.context.channel_id());
8816-
}
8811+
let mut commitment_update = None;
8812+
let mut tx_signatures = None;
8813+
let mut tx_abort = None;
8814+
8815+
// if next_funding_txid is set:
8816+
if let Some(next_funding_txid) = msg.next_funding_txid {
8817+
// - if `next_funding_txid` matches the latest interactive funding transaction
8818+
// or the current channel funding transaction:
8819+
if let Some(session) = &self.interactive_tx_signing_session {
8820+
let our_next_funding_txid = self.maybe_get_next_funding_txid();
8821+
if let Some(our_next_funding_txid) = our_next_funding_txid {
8822+
if our_next_funding_txid != next_funding_txid {
8823+
return Err(ChannelError::close(format!(
8824+
"Unexpected next_funding_txid: {}; expected: {}",
8825+
next_funding_txid, our_next_funding_txid,
8826+
)));
8827+
}
88178828

8818-
// if next_funding_txid is set:
8819-
let (commitment_update, tx_signatures, tx_abort) = if let Some(next_funding_txid) = msg.next_funding_txid {
8820-
if let Some(session) = &self.interactive_tx_signing_session {
8821-
// if next_funding_txid matches the latest interactive funding transaction:
8822-
let our_next_funding_txid = session.unsigned_tx().compute_txid();
8823-
if our_next_funding_txid == next_funding_txid {
8824-
debug_assert_eq!(session.unsigned_tx().compute_txid(), self.maybe_get_next_funding_txid().unwrap());
8825-
8826-
let commitment_update = if !self.context.channel_state.is_their_tx_signatures_sent() && msg.next_local_commitment_number == 0 {
8827-
// if it has not received tx_signatures for that funding transaction AND
8828-
// if next_commitment_number is zero:
8829-
// MUST retransmit its commitment_signed for that funding transaction.
8830-
let commitment_signed = self.context.get_initial_commitment_signed_v2(&self.funding, logger)
8831-
// TODO(splicing): Support async signing
8832-
.ok_or_else(|| {
8833-
let message = "Failed to get signatures for new commitment_signed".to_owned();
8834-
ChannelError::Close(
8835-
(
8836-
message.clone(),
8837-
ClosureReason::HolderForceClosed { message, broadcasted_latest_txn: Some(false) },
8838-
)
8839-
)})?;
8840-
Some(msgs::CommitmentUpdate {
8841-
commitment_signed: vec![commitment_signed],
8842-
update_add_htlcs: vec![],
8843-
update_fulfill_htlcs: vec![],
8844-
update_fail_htlcs: vec![],
8845-
update_fail_malformed_htlcs: vec![],
8846-
update_fee: None,
8847-
})
8848-
} else { None };
8849-
let tx_signatures = if (
8850-
// if it has not received tx_signatures for that funding transaction AND
8851-
// if it has already received commitment_signed AND it should sign first, as specified in the tx_signatures requirements:
8852-
// MUST send its tx_signatures for that funding transaction.
8853-
!self.context.channel_state.is_their_tx_signatures_sent() && session.has_received_commitment_signed() && session.holder_sends_tx_signatures_first()
8854-
// else if it has already received tx_signatures for that funding transaction:
8855-
// MUST send its tx_signatures for that funding transaction.
8856-
) || self.context.channel_state.is_their_tx_signatures_sent() {
8857-
// If `holder_tx_signatures` is `None` here, the `tx_signatures` message will be sent
8858-
// when the holder provides their witnesses as this will queue a `tx_signatures` if the
8859-
// holder must send one.
8860-
if session.holder_tx_signatures().is_none() {
8861-
log_debug!(logger, "Waiting for funding transaction signatures to be provided");
8862-
None
8863-
} else {
8864-
session.holder_tx_signatures().clone()
8865-
}
8829+
if !session.has_received_commitment_signed() {
8830+
self.context.expecting_peer_commitment_signed = true;
8831+
}
8832+
8833+
// - if `next_commitment_number` is equal to the commitment number of the
8834+
// `commitment_signed` message it sent for this funding transaction:
8835+
// - MUST retransmit its `commitment_signed` for that funding transaction.
8836+
if msg.next_local_commitment_number == next_counterparty_commitment_number {
8837+
// `next_counterparty_commitment_number` is guaranteed to always be the
8838+
// commitment number of the `commitment_signed` message we sent for this
8839+
// funding transaction. If they set `next_funding_txid`, then they should
8840+
// not have processed our `tx_signatures` yet, which implies that our state
8841+
// machine is still paused and no updates can happen that would increment
8842+
// our `next_counterparty_commitment_number`.
8843+
//
8844+
// If they did set `next_funding_txid` even after processing our
8845+
// `tx_signatures` erroneously, this may end up resulting in a force close.
8846+
let commitment_signed = self.context.get_initial_commitment_signed_v2(&self.funding, logger)
8847+
// TODO(splicing): Support async signing
8848+
.ok_or_else(|| {
8849+
let message = "Failed to get signatures for new commitment_signed".to_owned();
8850+
ChannelError::Close(
8851+
(
8852+
message.clone(),
8853+
ClosureReason::HolderForceClosed { message, broadcasted_latest_txn: Some(false) },
8854+
)
8855+
)})?;
8856+
commitment_update = Some(msgs::CommitmentUpdate {
8857+
commitment_signed: vec![commitment_signed],
8858+
update_add_htlcs: vec![],
8859+
update_fulfill_htlcs: vec![],
8860+
update_fail_htlcs: vec![],
8861+
update_fail_malformed_htlcs: vec![],
8862+
update_fee: None,
8863+
});
8864+
}
8865+
8866+
// - if it has already received `commitment_signed` and it should sign first,
8867+
// as specified in the [`tx_signatures` requirements](#the-tx_signatures-message):
8868+
// - MUST send its `tx_signatures` for that funding transaction.
8869+
//
8870+
// - if it has already received `tx_signatures` for that funding transaction:
8871+
// - MUST send its `tx_signatures` for that funding transaction.
8872+
if (session.has_received_commitment_signed() && session.holder_sends_tx_signatures_first())
8873+
|| self.context.channel_state.is_their_tx_signatures_sent()
8874+
{
8875+
// If `holder_tx_signatures` is `None` here, the `tx_signatures` message will be sent
8876+
// when the holder provides their witnesses as this will queue a `tx_signatures` if the
8877+
// holder must send one.
8878+
if session.holder_tx_signatures().is_none() {
8879+
log_debug!(logger, "Waiting for funding transaction signatures to be provided");
88668880
} else {
8867-
None
8868-
};
8869-
if !session.has_received_commitment_signed() {
8870-
self.context.expecting_peer_commitment_signed = true;
8881+
tx_signatures = session.holder_tx_signatures().clone();
88718882
}
8872-
(commitment_update, tx_signatures, None)
8873-
} else {
8874-
// The `next_funding_txid` does not match the latest interactive funding transaction so we
8875-
// MUST send tx_abort to let the remote know that they can forget this funding transaction.
8876-
(None, None, Some(msgs::TxAbort {
8877-
channel_id: self.context.channel_id(),
8878-
data: format!(
8879-
"next_funding_txid {} does match our latest interactive funding txid {}",
8880-
next_funding_txid, our_next_funding_txid,
8881-
).into_bytes() }))
88828883
}
88838884
} else {
8884-
// We'll just send a `tx_abort` here if we don't have a signing session for this channel
8885-
// on reestablish and tell our peer to just forget about it.
8886-
// Our peer is doing something strange, but it doesn't warrant closing the channel.
8887-
(None, None, Some(msgs::TxAbort {
8885+
// The `next_funding_txid` does not match the latest interactive funding
8886+
// transaction so we MUST send tx_abort to let the remote know that they can
8887+
// forget this funding transaction.
8888+
tx_abort = Some(msgs::TxAbort {
88888889
channel_id: self.context.channel_id(),
8889-
data:
8890-
"No active signing session. The associated funding transaction may have already been broadcast.".as_bytes().to_vec() }))
8890+
data: format!(
8891+
"Unexpected next_funding_txid {}",
8892+
next_funding_txid,
8893+
).into_bytes() });
88918894
}
88928895
} else {
8893-
// Don't send anything related to interactive signing if `next_funding_txid` is not set.
8894-
(None, None, None)
8895-
};
8896+
// We'll just send a `tx_abort` here if we don't have a signing session for this channel
8897+
// on reestablish and tell our peer to just forget about it.
8898+
// Our peer is doing something strange, but it doesn't warrant closing the channel.
8899+
tx_abort = Some(msgs::TxAbort {
8900+
channel_id: self.context.channel_id(),
8901+
data:
8902+
"No active signing session. The associated funding transaction may have already been broadcast.".as_bytes().to_vec() });
8903+
}
8904+
}
8905+
8906+
if msg.next_local_commitment_number == next_counterparty_commitment_number {
8907+
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
8908+
log_debug!(logger, "Reconnected channel {} with only lost outbound RAA", &self.context.channel_id());
8909+
} else {
8910+
log_debug!(logger, "Reconnected channel {} with no loss", &self.context.channel_id());
8911+
}
88968912

88978913
Ok(ReestablishResponses {
88988914
channel_ready, shutdown_msg, announcement_sigs,
@@ -8903,6 +8919,11 @@ where
89038919
tx_abort,
89048920
})
89058921
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
8922+
// We've made an update so we must have exchanged `tx_signatures`, implying that
8923+
// `commitment_signed` was also exchanged. However, we may still need to retransmit our
8924+
// `tx_signatures` if the counterparty sent theirs first but didn't get to process ours.
8925+
debug_assert!(commitment_update.is_none());
8926+
89068927
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
89078928
log_debug!(logger, "Reconnected channel {} with lost outbound RAA and lost remote commitment tx", &self.context.channel_id());
89088929
} else {
@@ -8915,8 +8936,8 @@ where
89158936
channel_ready, shutdown_msg, announcement_sigs,
89168937
commitment_update: None, raa: None,
89178938
order: self.context.resend_order.clone(),
8918-
tx_signatures: None,
8919-
tx_abort: None,
8939+
tx_signatures,
8940+
tx_abort,
89208941
})
89218942
} else {
89228943
let commitment_update = if self.context.resend_order == RAACommitmentOrder::RevokeAndACKFirst
@@ -8939,8 +8960,8 @@ where
89398960
channel_ready, shutdown_msg, announcement_sigs,
89408961
raa, commitment_update,
89418962
order: self.context.resend_order.clone(),
8942-
tx_signatures: None,
8943-
tx_abort: None,
8963+
tx_signatures,
8964+
tx_abort,
89448965
})
89458966
}
89468967
} else if msg.next_local_commitment_number < next_counterparty_commitment_number {

0 commit comments

Comments
 (0)