@@ -1863,6 +1863,7 @@ where
1863
1863
holder_commitment_point,
1864
1864
#[cfg(splicing)]
1865
1865
pending_splice: None,
1866
+ quiescent_action: None,
1866
1867
};
1867
1868
let res = funded_channel.initial_commitment_signed_v2(msg, best_block, signer_provider, logger)
1868
1869
.map(|monitor| (Some(monitor), None))
@@ -2429,6 +2430,15 @@ impl PendingSplice {
2429
2430
}
2430
2431
}
2431
2432
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
+
2432
2442
/// Wrapper around a [`Transaction`] useful for caching the result of [`Transaction::compute_txid`].
2433
2443
struct ConfirmedTransaction<'a> {
2434
2444
tx: &'a Transaction,
@@ -2728,10 +2738,6 @@ where
2728
2738
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
2729
2739
/// store it here and only release it to the `ChannelManager` once it asks for it.
2730
2740
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>,
2735
2741
}
2736
2742
2737
2743
/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3306,8 +3312,6 @@ where
3306
3312
blocked_monitor_updates: Vec::new(),
3307
3313
3308
3314
is_manual_broadcast: false,
3309
-
3310
- is_holder_quiescence_initiator: None,
3311
3315
};
3312
3316
3313
3317
Ok((funding, channel_context))
@@ -3544,8 +3548,6 @@ where
3544
3548
blocked_monitor_updates: Vec::new(),
3545
3549
local_initiated_shutdown: None,
3546
3550
is_manual_broadcast: false,
3547
-
3548
- is_holder_quiescence_initiator: None,
3549
3551
};
3550
3552
3551
3553
Ok((funding, channel_context))
@@ -6058,6 +6060,12 @@ where
6058
6060
/// Info about an in-progress, pending splice (if any), on the pre-splice channel
6059
6061
#[cfg(splicing)]
6060
6062
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>,
6061
6069
}
6062
6070
6063
6071
#[cfg(splicing)]
@@ -8198,11 +8206,13 @@ where
8198
8206
8199
8207
// Reset any quiescence-related state as it is implicitly terminated once disconnected.
8200
8208
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
+ }
8202
8213
self.context.channel_state.clear_local_stfu_sent();
8203
8214
self.context.channel_state.clear_remote_stfu_sent();
8204
8215
self.context.channel_state.clear_quiescent();
8205
- self.context.is_holder_quiescence_initiator.take();
8206
8216
}
8207
8217
8208
8218
self.context.channel_state.set_peer_disconnected();
@@ -11540,30 +11550,36 @@ where
11540
11550
#[cfg(any(test, fuzzing))]
11541
11551
#[rustfmt::skip]
11542
11552
pub fn propose_quiescence<L: Deref>(
11543
- &mut self, logger: &L,
11553
+ &mut self, logger: &L, action: QuiescentAction,
11544
11554
) -> Result<Option<msgs::Stfu>, ChannelError>
11545
11555
where
11546
11556
L::Target: Logger,
11547
11557
{
11548
11558
log_debug!(logger, "Attempting to initiate quiescence");
11549
11559
11550
- if !self.context.is_live () {
11560
+ if !self.context.is_usable () {
11551
11561
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()
11553
11563
));
11554
11564
}
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()));
11557
11567
}
11558
11568
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()
11560
11572
|| self.context.channel_state.is_local_stfu_sent()
11561
11573
{
11562
11574
return Ok(None);
11563
11575
}
11564
11576
11565
11577
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
+ }
11567
11583
}
11568
11584
11569
11585
// Assumes we are either awaiting quiescence or our counterparty has requested quiescence.
@@ -11573,7 +11589,6 @@ where
11573
11589
L::Target: Logger,
11574
11590
{
11575
11591
debug_assert!(!self.context.channel_state.is_local_stfu_sent());
11576
- // Either state being set implies the channel is live.
11577
11592
debug_assert!(
11578
11593
self.context.channel_state.is_awaiting_quiescence()
11579
11594
|| self.context.channel_state.is_remote_stfu_sent()
@@ -11593,18 +11608,10 @@ where
11593
11608
self.context.channel_state.clear_awaiting_quiescence();
11594
11609
self.context.channel_state.clear_remote_stfu_sent();
11595
11610
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
11608
11615
} else {
11609
11616
log_debug!(logger, "Sending stfu as quiescence initiator");
11610
11617
debug_assert!(self.context.channel_state.is_awaiting_quiescence());
@@ -11635,9 +11642,7 @@ where
11635
11642
));
11636
11643
}
11637
11644
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() {
11641
11646
if !msg.initiator {
11642
11647
return Err(ChannelError::WarnAndDisconnect(
11643
11648
"Peer sent unexpected `stfu` without signaling as initiator".to_owned()
@@ -11651,23 +11656,13 @@ where
11651
11656
// then.
11652
11657
self.context.channel_state.set_remote_stfu_sent();
11653
11658
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
-
11663
11659
log_debug!(logger, "Received counterparty stfu proposing quiescence");
11664
11660
return self.send_stfu(logger).map(|stfu| Some(stfu));
11665
11661
}
11666
11662
11667
11663
// We already sent `stfu` and are now processing theirs. It may be in response to ours, or
11668
11664
// we happened to both send `stfu` at the same time and a tie-break is needed.
11669
11665
let is_holder_quiescence_initiator = !msg.initiator || self.funding.is_outbound();
11670
- self.context.is_holder_quiescence_initiator = Some(is_holder_quiescence_initiator);
11671
11666
11672
11667
// We were expecting to receive `stfu` because we already sent ours.
11673
11668
self.mark_response_received();
@@ -11695,6 +11690,21 @@ where
11695
11690
if !is_holder_quiescence_initiator { " not" } else { "" }
11696
11691
);
11697
11692
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
+
11698
11708
Ok(None)
11699
11709
}
11700
11710
@@ -11710,6 +11720,10 @@ where
11710
11720
&& self.context.channel_state.is_remote_stfu_sent())
11711
11721
);
11712
11722
11723
+ if !self.context.is_live() {
11724
+ return Ok(None);
11725
+ }
11726
+
11713
11727
// We need to send our `stfu`, either because we're trying to initiate quiescence, or the
11714
11728
// counterparty is and we've yet to send ours.
11715
11729
if self.context.channel_state.is_awaiting_quiescence()
@@ -11735,13 +11749,10 @@ where
11735
11749
debug_assert!(!self.context.channel_state.is_local_stfu_sent());
11736
11750
debug_assert!(!self.context.channel_state.is_remote_stfu_sent());
11737
11751
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
11745
11756
}
11746
11757
11747
11758
pub fn remove_legacy_scids_before_block(&mut self, height: u32) -> alloc::vec::Drain<'_, u64> {
@@ -12063,6 +12074,7 @@ where
12063
12074
holder_commitment_point,
12064
12075
#[cfg(splicing)]
12065
12076
pending_splice: None,
12077
+ quiescent_action: None,
12066
12078
};
12067
12079
12068
12080
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some()
@@ -12349,6 +12361,7 @@ where
12349
12361
holder_commitment_point,
12350
12362
#[cfg(splicing)]
12351
12363
pending_splice: None,
12364
+ quiescent_action: None,
12352
12365
};
12353
12366
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some()
12354
12367
|| channel.context.signer_pending_channel_ready;
@@ -12850,7 +12863,11 @@ where
12850
12863
match channel_state {
12851
12864
ChannelState::AwaitingChannelReady(_) => {},
12852
12865
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
+ }
12854
12871
channel_state.clear_local_stfu_sent();
12855
12872
channel_state.clear_remote_stfu_sent();
12856
12873
channel_state.clear_quiescent();
@@ -13258,6 +13275,7 @@ where
13258
13275
(60, self.context.historical_scids, optional_vec), // Added in 0.2
13259
13276
(61, fulfill_attribution_data, optional_vec), // Added in 0.2
13260
13277
(63, holder_commitment_point_current, option), // Added in 0.2
13278
+ (65, self.quiescent_action, option), // Added in 0.2
13261
13279
});
13262
13280
13263
13281
Ok(())
@@ -13619,6 +13637,8 @@ where
13619
13637
13620
13638
let mut minimum_depth_override: Option<u32> = None;
13621
13639
13640
+ let mut quiescent_action = None;
13641
+
13622
13642
read_tlv_fields!(reader, {
13623
13643
(0, announcement_sigs, option),
13624
13644
(1, minimum_depth, option),
@@ -13662,6 +13682,7 @@ where
13662
13682
(60, historical_scids, optional_vec), // Added in 0.2
13663
13683
(61, fulfill_attribution_data, optional_vec), // Added in 0.2
13664
13684
(63, holder_commitment_point_current_opt, option), // Added in 0.2
13685
+ (65, quiescent_action, upgradable_option), // Added in 0.2
13665
13686
});
13666
13687
13667
13688
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -14003,13 +14024,12 @@ where
14003
14024
14004
14025
blocked_monitor_updates: blocked_monitor_updates.unwrap(),
14005
14026
is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
14006
-
14007
- is_holder_quiescence_initiator: None,
14008
14027
},
14009
14028
interactive_tx_signing_session,
14010
14029
holder_commitment_point,
14011
14030
#[cfg(splicing)]
14012
14031
pending_splice: None,
14032
+ quiescent_action,
14013
14033
})
14014
14034
}
14015
14035
}
0 commit comments