Skip to content

Commit 9272b39

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 2dbab78 commit 9272b39

File tree

1 file changed

+65
-16
lines changed

1 file changed

+65
-16
lines changed

lightning/src/ln/channel.rs

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,18 @@ where
19371937
let logger = WithChannelContext::from(logger, self.context(), None);
19381938
match &mut self.phase {
19391939
ChannelPhase::UnfundedV2(chan) => {
1940+
debug_assert_eq!(
1941+
chan.context.channel_state,
1942+
ChannelState::NegotiatingFunding(
1943+
NegotiatingFundingFlags::OUR_INIT_SENT
1944+
| NegotiatingFundingFlags::THEIR_INIT_SENT
1945+
),
1946+
);
1947+
1948+
chan.context.channel_state =
1949+
ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
1950+
chan.context.channel_state.set_interactive_signing();
1951+
19401952
let mut signing_session = chan
19411953
.interactive_tx_constructor
19421954
.take()
@@ -6000,9 +6012,6 @@ where
60006012
funding
60016013
.channel_transaction_parameters.funding_outpoint = Some(outpoint);
60026014

6003-
self.channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
6004-
self.channel_state.set_interactive_signing();
6005-
60066015
if is_splice {
60076016
debug_assert_eq!(
60086017
holder_commitment_transaction_number,
@@ -6050,6 +6059,12 @@ where
60506059
SP::Target: SignerProvider,
60516060
L::Target: Logger,
60526061
{
6062+
let is_quiescent = matches!(
6063+
self.channel_state,
6064+
ChannelState::ChannelReady(f) if f.is_set(ChannelReadyFlags::QUIESCENT)
6065+
);
6066+
debug_assert!(self.channel_state.is_interactive_signing() || is_quiescent);
6067+
60536068
let mut commitment_number = self.counterparty_next_commitment_transaction_number;
60546069
let mut commitment_point = self.counterparty_next_commitment_point.unwrap();
60556070

@@ -6096,10 +6111,6 @@ where
60966111
SP::Target: SignerProvider,
60976112
L::Target: Logger,
60986113
{
6099-
assert!(
6100-
matches!(self.channel_state, ChannelState::FundingNegotiated(flags) if flags.is_interactive_signing())
6101-
);
6102-
61036114
let signature = self.get_initial_counterparty_commitment_signature(funding, logger);
61046115
if let Some(signature) = signature {
61056116
log_info!(
@@ -6130,6 +6141,8 @@ where
61306141
SP::Target: SignerProvider,
61316142
L::Target: Logger,
61326143
{
6144+
self.channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
6145+
self.channel_state.set_interactive_signing();
61336146
self.counterparty_next_commitment_point = Some(counterparty_next_commitment_point_override);
61346147
self.get_initial_counterparty_commitment_signature(funding, logger)
61356148
}
@@ -8510,6 +8523,10 @@ where
85108523
format!("Channel {} not expecting funding signatures", self.context.channel_id);
85118524
return Err(APIError::APIMisuseError { err });
85128525
}
8526+
debug_assert_eq!(
8527+
self.has_pending_splice_awaiting_signatures(),
8528+
matches!(self.context.channel_state, ChannelState::ChannelReady(f) if f.is_set(ChannelReadyFlags::QUIESCENT))
8529+
);
85138530

85148531
let signing_session =
85158532
if let Some(signing_session) = self.interactive_tx_signing_session.as_mut() {
@@ -8560,9 +8577,25 @@ where
85608577
.map_err(|err| APIError::APIMisuseError { err })?;
85618578

85628579
if funding_tx_opt.is_some() {
8563-
self.funding.funding_transaction = funding_tx_opt.clone();
8564-
self.context.channel_state =
8565-
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8580+
debug_assert!(tx_signatures_opt.is_some());
8581+
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
8582+
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
8583+
8584+
if let Some(pending_splice) = self.pending_splice.as_mut() {
8585+
if let Some(FundingNegotiation::AwaitingSignatures(mut funding)) =
8586+
pending_splice.funding_negotiation.take()
8587+
{
8588+
funding.funding_transaction = funding_tx_opt.clone();
8589+
self.pending_funding.push(funding);
8590+
} else {
8591+
debug_assert!(false, "We checked we were in the right state above");
8592+
}
8593+
self.context.channel_state.clear_quiescent();
8594+
} else {
8595+
self.funding.funding_transaction = funding_tx_opt.clone();
8596+
self.context.channel_state =
8597+
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8598+
}
85668599
}
85678600

85688601
Ok((tx_signatures_opt, funding_tx_opt))
@@ -8575,6 +8608,10 @@ where
85758608
{
85768609
return Err(ChannelError::Ignore("Ignoring unexpected tx_signatures".to_owned()));
85778610
}
8611+
debug_assert_eq!(
8612+
self.has_pending_splice_awaiting_signatures(),
8613+
matches!(self.context.channel_state, ChannelState::ChannelReady(f) if f.is_set(ChannelReadyFlags::QUIESCENT))
8614+
);
85788615

85798616
let signing_session = if let Some(signing_session) = self.interactive_tx_signing_session.as_mut() {
85808617
if signing_session.has_received_tx_signatures() {
@@ -8607,12 +8644,24 @@ where
86078644
.map_err(|msg| ChannelError::Warn(msg))?;
86088645

86098646
if funding_tx_opt.is_some() {
8610-
// TODO(splicing): Transition back to `ChannelReady` and not `AwaitingChannelReady`
8611-
// We will also need to use the pending `FundingScope` in the splicing case.
8612-
//
8613-
// We have a finalized funding transaction, so we can set the funding transaction.
8614-
self.funding.funding_transaction = funding_tx_opt.clone();
8615-
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8647+
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
8648+
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
8649+
8650+
if let Some(pending_splice) = self.pending_splice.as_mut() {
8651+
if let Some(FundingNegotiation::AwaitingSignatures(mut funding)) =
8652+
pending_splice.funding_negotiation.take()
8653+
{
8654+
funding.funding_transaction = funding_tx_opt.clone();
8655+
self.pending_funding.push(funding);
8656+
} else {
8657+
debug_assert!(false, "We checked we were in the right state above");
8658+
}
8659+
self.context.channel_state.clear_quiescent();
8660+
} else {
8661+
self.funding.funding_transaction = funding_tx_opt.clone();
8662+
self.context.channel_state =
8663+
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8664+
}
86168665
}
86178666

86188667
Ok((holder_tx_signatures_opt, funding_tx_opt))

0 commit comments

Comments
 (0)