Skip to content

Commit 8ca96e3

Browse files
committed
Address ChannelState inconsistency throughout splicing
Once a channel open has become locked (i.e., we've entered `ChannelState::ChannelReady`), the channel is intended to remain within this state for the rest of its lifetime until shutdown. Previously, we had assumed a channel being spliced would go through the `ChannelState` lifecycle again starting from `NegotiatingFunding` but skipping `AwaitingChannelReady`. This inconsistency departs from what we strive to achieve with `ChannelState` and also makes the state of a channel harder to reason about. This commit ensures a channel undergoing a splice remains in `ChannelReady`, clearing the quiescent flag once the negotiation is complete. Dual funding is unaffected by this change as the channel is being opened and we want to maintain the same `ChannelState` lifecycle.
1 parent 34cc806 commit 8ca96e3

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

lightning/src/ln/channel.rs

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -699,9 +699,9 @@ enum ChannelState {
699699
/// `AwaitingChannelReady`. Note that this is nonsense for an inbound channel as we immediately generate
700700
/// `funding_signed` upon receipt of `funding_created`, so simply skip this state.
701701
///
702-
/// For inbound and outbound interactively funded channels (dual-funding/splicing), this flag indicates
702+
/// For inbound and outbound interactively funded channels (dual-funding/splicing), this state indicates
703703
/// that interactive transaction construction has been completed and we are now interactively signing
704-
/// the funding/splice transaction.
704+
/// the initial funding transaction.
705705
FundingNegotiated(FundingNegotiatedFlags),
706706
/// We've received/sent `funding_created` and `funding_signed` and are thus now waiting on the
707707
/// funding transaction to confirm.
@@ -1913,6 +1913,14 @@ where
19131913
let logger = WithChannelContext::from(logger, self.context(), None);
19141914
match &mut self.phase {
19151915
ChannelPhase::UnfundedV2(chan) => {
1916+
debug_assert_eq!(
1917+
chan.context.channel_state,
1918+
ChannelState::NegotiatingFunding(
1919+
NegotiatingFundingFlags::OUR_INIT_SENT
1920+
| NegotiatingFundingFlags::THEIR_INIT_SENT
1921+
),
1922+
);
1923+
19161924
let signing_session = chan
19171925
.interactive_tx_constructor
19181926
.take()
@@ -6068,7 +6076,6 @@ where
60686076
funding
60696077
.channel_transaction_parameters.funding_outpoint = Some(outpoint);
60706078
self.interactive_tx_signing_session = Some(signing_session);
6071-
self.channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
60726079

60736080
if is_splice {
60746081
debug_assert_eq!(
@@ -6079,6 +6086,7 @@ where
60796086
return Err(AbortReason::InternalError("Splicing not yet supported"));
60806087
} else {
60816088
self.assert_no_commitment_advancement(holder_commitment_transaction_number, "initial commitment_signed");
6089+
self.channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
60826090
}
60836091

60846092
let commitment_signed = self.get_initial_commitment_signed_v2(&funding, logger);
@@ -6163,9 +6171,7 @@ where
61636171
SP::Target: SignerProvider,
61646172
L::Target: Logger,
61656173
{
6166-
assert!(
6167-
matches!(self.channel_state, ChannelState::FundingNegotiated(_) if self.interactive_tx_signing_session.is_some())
6168-
);
6174+
debug_assert!(self.interactive_tx_signing_session.is_some());
61696175

61706176
let signature = self.get_initial_counterparty_commitment_signature(funding, logger);
61716177
if let Some(signature) = signature {
@@ -8587,9 +8593,25 @@ where
85878593
.map_err(|err| APIError::APIMisuseError { err })?;
85888594

85898595
if funding_tx_opt.is_some() {
8590-
self.funding.funding_transaction = funding_tx_opt.clone();
8591-
self.context.channel_state =
8592-
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8596+
debug_assert!(tx_signatures_opt.is_some());
8597+
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
8598+
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
8599+
8600+
if let Some(pending_splice) = self.pending_splice.as_mut() {
8601+
if let Some(FundingNegotiation::AwaitingSignatures(mut funding)) =
8602+
pending_splice.funding_negotiation.take()
8603+
{
8604+
funding.funding_transaction = funding_tx_opt.clone();
8605+
self.pending_funding.push(funding);
8606+
} else {
8607+
debug_assert!(false, "We checked we were in the right state above");
8608+
}
8609+
self.context.channel_state.clear_quiescent();
8610+
} else {
8611+
self.funding.funding_transaction = funding_tx_opt.clone();
8612+
self.context.channel_state =
8613+
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8614+
}
85938615
}
85948616

85958617
Ok((tx_signatures_opt, funding_tx_opt))
@@ -8627,12 +8649,24 @@ where
86278649
.map_err(|msg| ChannelError::Warn(msg))?;
86288650

86298651
if funding_tx_opt.is_some() {
8630-
// TODO(splicing): Transition back to `ChannelReady` and not `AwaitingChannelReady`
8631-
// We will also need to use the pending `FundingScope` in the splicing case.
8632-
//
8633-
// We have a finalized funding transaction, so we can set the funding transaction.
8634-
self.funding.funding_transaction = funding_tx_opt.clone();
8635-
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8652+
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
8653+
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
8654+
8655+
if let Some(pending_splice) = self.pending_splice.as_mut() {
8656+
if let Some(FundingNegotiation::AwaitingSignatures(mut funding)) =
8657+
pending_splice.funding_negotiation.take()
8658+
{
8659+
funding.funding_transaction = funding_tx_opt.clone();
8660+
self.pending_funding.push(funding);
8661+
} else {
8662+
debug_assert!(false, "We checked we were in the right state above");
8663+
}
8664+
self.context.channel_state.clear_quiescent();
8665+
} else {
8666+
self.funding.funding_transaction = funding_tx_opt.clone();
8667+
self.context.channel_state =
8668+
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8669+
}
86368670
}
86378671

86388672
Ok((holder_tx_signatures_opt, funding_tx_opt))

0 commit comments

Comments
 (0)