@@ -1863,6 +1863,7 @@ where
18631863 holder_commitment_point,
18641864 #[cfg(splicing)]
18651865 pending_splice: None,
1866+ quiescent_action: None,
18661867 };
18671868 let res = funded_channel.initial_commitment_signed_v2(msg, best_block, signer_provider, logger)
18681869 .map(|monitor| (Some(monitor), None))
@@ -2429,6 +2430,15 @@ impl PendingSplice {
24292430 }
24302431}
24312432
2433+ pub(crate) enum QuiescentAction {
2434+ // TODO: Make this test-only once we have another variant (as some code requires *a* variant).
2435+ DoNothing,
2436+ }
2437+
2438+ impl_writeable_tlv_based_enum_upgradable!(QuiescentAction,
2439+ (99, DoNothing) => {},
2440+ );
2441+
24322442/// Wrapper around a [`Transaction`] useful for caching the result of [`Transaction::compute_txid`].
24332443struct ConfirmedTransaction<'a> {
24342444 tx: &'a Transaction,
@@ -2728,10 +2738,6 @@ where
27282738 /// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
27292739 /// store it here and only release it to the `ChannelManager` once it asks for it.
27302740 blocked_monitor_updates: Vec<PendingChannelMonitorUpdate>,
2731-
2732- /// Only set when a counterparty `stfu` has been processed to track which node is allowed to
2733- /// propose "something fundamental" upon becoming quiescent.
2734- is_holder_quiescence_initiator: Option<bool>,
27352741}
27362742
27372743/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3306,8 +3312,6 @@ where
33063312 blocked_monitor_updates: Vec::new(),
33073313
33083314 is_manual_broadcast: false,
3309-
3310- is_holder_quiescence_initiator: None,
33113315 };
33123316
33133317 Ok((funding, channel_context))
@@ -3544,8 +3548,6 @@ where
35443548 blocked_monitor_updates: Vec::new(),
35453549 local_initiated_shutdown: None,
35463550 is_manual_broadcast: false,
3547-
3548- is_holder_quiescence_initiator: None,
35493551 };
35503552
35513553 Ok((funding, channel_context))
@@ -6058,6 +6060,12 @@ where
60586060 /// Info about an in-progress, pending splice (if any), on the pre-splice channel
60596061 #[cfg(splicing)]
60606062 pending_splice: Option<PendingSplice>,
6063+
6064+ /// Once we become quiescent, if we're the initiator, there's some action we'll want to take.
6065+ /// This keeps track of that action. Note that if we become quiescent and we're not the
6066+ /// initiator we may be able to merge this action into what the counterparty wanted to do (e.g.
6067+ /// in the case of splicing).
6068+ quiescent_action: Option<QuiescentAction>,
60616069}
60626070
60636071#[cfg(splicing)]
@@ -8198,11 +8206,13 @@ where
81988206
81998207 // Reset any quiescence-related state as it is implicitly terminated once disconnected.
82008208 if matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
8201- self.context.channel_state.clear_awaiting_quiescence();
8209+ if self.quiescent_action.is_some() {
8210+ // If we were trying to get quiescent, try again after reconnection.
8211+ self.context.channel_state.set_awaiting_quiescence();
8212+ }
82028213 self.context.channel_state.clear_local_stfu_sent();
82038214 self.context.channel_state.clear_remote_stfu_sent();
82048215 self.context.channel_state.clear_quiescent();
8205- self.context.is_holder_quiescence_initiator.take();
82068216 }
82078217
82088218 self.context.channel_state.set_peer_disconnected();
@@ -11540,30 +11550,36 @@ where
1154011550 #[cfg(any(test, fuzzing))]
1154111551 #[rustfmt::skip]
1154211552 pub fn propose_quiescence<L: Deref>(
11543- &mut self, logger: &L,
11553+ &mut self, logger: &L, action: QuiescentAction,
1154411554 ) -> Result<Option<msgs::Stfu>, ChannelError>
1154511555 where
1154611556 L::Target: Logger,
1154711557 {
1154811558 log_debug!(logger, "Attempting to initiate quiescence");
1154911559
11550- if !self.context.is_live () {
11560+ if !self.context.is_usable () {
1155111561 return Err(ChannelError::Ignore(
11552- "Channel is not in a live state to propose quiescence".to_owned()
11562+ "Channel is not in a usable state to propose quiescence".to_owned()
1155311563 ));
1155411564 }
11555- if self.context.channel_state.is_quiescent () {
11556- return Err(ChannelError::Ignore("Channel is already quiescent ".to_owned()));
11565+ if self.quiescent_action.is_some () {
11566+ return Err(ChannelError::Ignore("Channel is already quiescing ".to_owned()));
1155711567 }
1155811568
11559- if self.context.channel_state.is_awaiting_quiescence()
11569+ self.quiescent_action = Some(action);
11570+ if self.context.channel_state.is_quiescent()
11571+ || self.context.channel_state.is_awaiting_quiescence()
1156011572 || self.context.channel_state.is_local_stfu_sent()
1156111573 {
1156211574 return Ok(None);
1156311575 }
1156411576
1156511577 self.context.channel_state.set_awaiting_quiescence();
11566- Ok(Some(self.send_stfu(logger)?))
11578+ if self.context.is_live() {
11579+ Ok(Some(self.send_stfu(logger)?))
11580+ } else {
11581+ Ok(None)
11582+ }
1156711583 }
1156811584
1156911585 // Assumes we are either awaiting quiescence or our counterparty has requested quiescence.
@@ -11573,7 +11589,6 @@ where
1157311589 L::Target: Logger,
1157411590 {
1157511591 debug_assert!(!self.context.channel_state.is_local_stfu_sent());
11576- // Either state being set implies the channel is live.
1157711592 debug_assert!(
1157811593 self.context.channel_state.is_awaiting_quiescence()
1157911594 || self.context.channel_state.is_remote_stfu_sent()
@@ -11593,18 +11608,10 @@ where
1159311608 self.context.channel_state.clear_awaiting_quiescence();
1159411609 self.context.channel_state.clear_remote_stfu_sent();
1159511610 self.context.channel_state.set_quiescent();
11596- if let Some(initiator) = self.context.is_holder_quiescence_initiator.as_ref() {
11597- log_debug!(
11598- logger,
11599- "Responding to counterparty stfu with our own, channel is now quiescent and we are{} the initiator",
11600- if !initiator { " not" } else { "" }
11601- );
11602-
11603- *initiator
11604- } else {
11605- debug_assert!(false, "Quiescence initiator must have been set when we received stfu");
11606- false
11607- }
11611+ // We are sending an stfu in response to our couterparty's stfu, but had not yet sent
11612+ // our own stfu (even if `awaiting_quiescence` was set). Thus, the counterparty is the
11613+ // initiator and they can do "something fundamental".
11614+ false
1160811615 } else {
1160911616 log_debug!(logger, "Sending stfu as quiescence initiator");
1161011617 debug_assert!(self.context.channel_state.is_awaiting_quiescence());
@@ -11635,9 +11642,7 @@ where
1163511642 ));
1163611643 }
1163711644
11638- if self.context.channel_state.is_awaiting_quiescence()
11639- || !self.context.channel_state.is_local_stfu_sent()
11640- {
11645+ if !self.context.channel_state.is_local_stfu_sent() {
1164111646 if !msg.initiator {
1164211647 return Err(ChannelError::WarnAndDisconnect(
1164311648 "Peer sent unexpected `stfu` without signaling as initiator".to_owned()
@@ -11651,23 +11656,13 @@ where
1165111656 // then.
1165211657 self.context.channel_state.set_remote_stfu_sent();
1165311658
11654- let is_holder_initiator = if self.context.channel_state.is_awaiting_quiescence() {
11655- // We were also planning to propose quiescence, let the tie-breaker decide the
11656- // initiator.
11657- self.funding.is_outbound()
11658- } else {
11659- false
11660- };
11661- self.context.is_holder_quiescence_initiator = Some(is_holder_initiator);
11662-
1166311659 log_debug!(logger, "Received counterparty stfu proposing quiescence");
1166411660 return self.send_stfu(logger).map(|stfu| Some(stfu));
1166511661 }
1166611662
1166711663 // We already sent `stfu` and are now processing theirs. It may be in response to ours, or
1166811664 // we happened to both send `stfu` at the same time and a tie-break is needed.
1166911665 let is_holder_quiescence_initiator = !msg.initiator || self.funding.is_outbound();
11670- self.context.is_holder_quiescence_initiator = Some(is_holder_quiescence_initiator);
1167111666
1167211667 // We were expecting to receive `stfu` because we already sent ours.
1167311668 self.mark_response_received();
@@ -11695,6 +11690,21 @@ where
1169511690 if !is_holder_quiescence_initiator { " not" } else { "" }
1169611691 );
1169711692
11693+ if is_holder_quiescence_initiator {
11694+ match self.quiescent_action.take() {
11695+ None => {
11696+ debug_assert!(false);
11697+ return Err(ChannelError::WarnAndDisconnect(
11698+ "Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
11699+ ));
11700+ },
11701+ Some(QuiescentAction::DoNothing) => {
11702+ // In quiescence test we want to just hang out here, letting the test manually
11703+ // leave quiescence.
11704+ },
11705+ }
11706+ }
11707+
1169811708 Ok(None)
1169911709 }
1170011710
@@ -11710,6 +11720,10 @@ where
1171011720 && self.context.channel_state.is_remote_stfu_sent())
1171111721 );
1171211722
11723+ if !self.context.is_live() {
11724+ return Ok(None);
11725+ }
11726+
1171311727 // We need to send our `stfu`, either because we're trying to initiate quiescence, or the
1171411728 // counterparty is and we've yet to send ours.
1171511729 if self.context.channel_state.is_awaiting_quiescence()
@@ -11735,13 +11749,10 @@ where
1173511749 debug_assert!(!self.context.channel_state.is_local_stfu_sent());
1173611750 debug_assert!(!self.context.channel_state.is_remote_stfu_sent());
1173711751
11738- if self.context.channel_state.is_quiescent() {
11739- self.mark_response_received();
11740- self.context.channel_state.clear_quiescent();
11741- self.context.is_holder_quiescence_initiator.take().expect("Must always be set while quiescent")
11742- } else {
11743- false
11744- }
11752+ self.mark_response_received();
11753+ let was_quiescent = self.context.channel_state.is_quiescent();
11754+ self.context.channel_state.clear_quiescent();
11755+ was_quiescent
1174511756 }
1174611757
1174711758 pub fn remove_legacy_scids_before_block(&mut self, height: u32) -> alloc::vec::Drain<'_, u64> {
@@ -12063,6 +12074,7 @@ where
1206312074 holder_commitment_point,
1206412075 #[cfg(splicing)]
1206512076 pending_splice: None,
12077+ quiescent_action: None,
1206612078 };
1206712079
1206812080 let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some()
@@ -12349,6 +12361,7 @@ where
1234912361 holder_commitment_point,
1235012362 #[cfg(splicing)]
1235112363 pending_splice: None,
12364+ quiescent_action: None,
1235212365 };
1235312366 let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some()
1235412367 || channel.context.signer_pending_channel_ready;
@@ -12850,7 +12863,11 @@ where
1285012863 match channel_state {
1285112864 ChannelState::AwaitingChannelReady(_) => {},
1285212865 ChannelState::ChannelReady(_) => {
12853- channel_state.clear_awaiting_quiescence();
12866+ if self.quiescent_action.is_some() {
12867+ // If we're trying to get quiescent to do something, try again when we
12868+ // reconnect to the peer.
12869+ channel_state.set_awaiting_quiescence();
12870+ }
1285412871 channel_state.clear_local_stfu_sent();
1285512872 channel_state.clear_remote_stfu_sent();
1285612873 channel_state.clear_quiescent();
@@ -13258,6 +13275,7 @@ where
1325813275 (60, self.context.historical_scids, optional_vec), // Added in 0.2
1325913276 (61, fulfill_attribution_data, optional_vec), // Added in 0.2
1326013277 (63, holder_commitment_point_current, option), // Added in 0.2
13278+ (65, self.quiescent_action, option), // Added in 0.2
1326113279 });
1326213280
1326313281 Ok(())
@@ -13619,6 +13637,8 @@ where
1361913637
1362013638 let mut minimum_depth_override: Option<u32> = None;
1362113639
13640+ let mut quiescent_action = None;
13641+
1362213642 read_tlv_fields!(reader, {
1362313643 (0, announcement_sigs, option),
1362413644 (1, minimum_depth, option),
@@ -13662,6 +13682,7 @@ where
1366213682 (60, historical_scids, optional_vec), // Added in 0.2
1366313683 (61, fulfill_attribution_data, optional_vec), // Added in 0.2
1366413684 (63, holder_commitment_point_current_opt, option), // Added in 0.2
13685+ (65, quiescent_action, upgradable_option), // Added in 0.2
1366513686 });
1366613687
1366713688 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -14003,13 +14024,12 @@ where
1400314024
1400414025 blocked_monitor_updates: blocked_monitor_updates.unwrap(),
1400514026 is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
14006-
14007- is_holder_quiescence_initiator: None,
1400814027 },
1400914028 interactive_tx_signing_session,
1401014029 holder_commitment_point,
1401114030 #[cfg(splicing)]
1401214031 pending_splice: None,
14032+ quiescent_action,
1401314033 })
1401414034 }
1401514035}
0 commit comments