Skip to content

Commit 5a5cb97

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 3189e0a commit 5a5cb97

File tree

1 file changed

+101
-81
lines changed

1 file changed

+101
-81
lines changed

lightning/src/ln/channel.rs

Lines changed: 101 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -8795,91 +8795,106 @@ where
87958795
self.get_channel_ready(logger)
87968796
} else { None };
87978797

8798-
if msg.next_local_commitment_number == next_counterparty_commitment_number {
8799-
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
8800-
log_debug!(logger, "Reconnected channel {} with only lost outbound RAA", &self.context.channel_id());
8801-
} else {
8802-
log_debug!(logger, "Reconnected channel {} with no loss", &self.context.channel_id());
8803-
}
8798+
let mut commitment_update = None;
8799+
let mut tx_signatures = None;
8800+
let mut tx_abort = None;
8801+
8802+
// if next_funding_txid is set:
8803+
if let Some(next_funding_txid) = msg.next_funding_txid {
8804+
// - if `next_funding_txid` matches the latest interactive funding transaction
8805+
// or the current channel funding transaction:
8806+
if let Some(session) = &self.interactive_tx_signing_session {
8807+
let our_next_funding_txid = self.maybe_get_next_funding_txid();
8808+
if let Some(our_next_funding_txid) = our_next_funding_txid {
8809+
if our_next_funding_txid != next_funding_txid {
8810+
return Err(ChannelError::close(format!(
8811+
"Unexpected next_funding_txid: {}; expected: {}",
8812+
next_funding_txid, our_next_funding_txid,
8813+
)));
8814+
}
88048815

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

88848899
Ok(ReestablishResponses {
88858900
channel_ready, shutdown_msg, announcement_sigs,
@@ -8890,6 +8905,11 @@ where
88908905
tx_abort,
88918906
})
88928907
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
8908+
// We've made an update so we must have exchanged `tx_signatures`, implying that
8909+
// `commitment_signed` was also exchanged. However, we may still need to retransmit our
8910+
// `tx_signatures` if the counterparty sent theirs first but didn't get to process ours.
8911+
debug_assert!(commitment_update.is_none());
8912+
88938913
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
88948914
log_debug!(logger, "Reconnected channel {} with lost outbound RAA and lost remote commitment tx", &self.context.channel_id());
88958915
} else {
@@ -8902,8 +8922,8 @@ where
89028922
channel_ready, shutdown_msg, announcement_sigs,
89038923
commitment_update: None, raa: None,
89048924
order: self.context.resend_order.clone(),
8905-
tx_signatures: None,
8906-
tx_abort: None,
8925+
tx_signatures,
8926+
tx_abort,
89078927
})
89088928
} else {
89098929
let commitment_update = if self.context.resend_order == RAACommitmentOrder::RevokeAndACKFirst
@@ -8926,8 +8946,8 @@ where
89268946
channel_ready, shutdown_msg, announcement_sigs,
89278947
raa, commitment_update,
89288948
order: self.context.resend_order.clone(),
8929-
tx_signatures: None,
8930-
tx_abort: None,
8949+
tx_signatures,
8950+
tx_abort,
89318951
})
89328952
}
89338953
} else if msg.next_local_commitment_number < next_counterparty_commitment_number {

0 commit comments

Comments
 (0)