@@ -2443,6 +2443,15 @@ impl PendingSplice {
2443
2443
}
2444
2444
}
2445
2445
2446
+ pub(crate) enum QuiescentAction {
2447
+ // TODO: Make this test-only once we have another variant (as some code requires *a* variant).
2448
+ DoNothing,
2449
+ }
2450
+
2451
+ impl_writeable_tlv_based_enum_upgradable!(QuiescentAction,
2452
+ (99, DoNothing) => {},
2453
+ );
2454
+
2446
2455
/// Wrapper around a [`Transaction`] useful for caching the result of [`Transaction::compute_txid`].
2447
2456
struct ConfirmedTransaction<'a> {
2448
2457
tx: &'a Transaction,
@@ -2742,6 +2751,12 @@ where
2742
2751
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
2743
2752
/// store it here and only release it to the `ChannelManager` once it asks for it.
2744
2753
blocked_monitor_updates: Vec<PendingChannelMonitorUpdate>,
2754
+
2755
+ /// Once we become quiescent, if we're the initiator, there's some action we'll want to take.
2756
+ /// This keeps track of that action. Note that if we become quiescent and we're not the
2757
+ /// initiator we may be able to merge this action into what the counterparty wanted to do (e.g.
2758
+ /// in the case of splicing).
2759
+ post_quiescence_action: Option<QuiescentAction>,
2745
2760
}
2746
2761
2747
2762
/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3316,6 +3331,8 @@ where
3316
3331
blocked_monitor_updates: Vec::new(),
3317
3332
3318
3333
is_manual_broadcast: false,
3334
+
3335
+ post_quiescence_action: None,
3319
3336
};
3320
3337
3321
3338
Ok((funding, channel_context))
@@ -3552,6 +3569,8 @@ where
3552
3569
blocked_monitor_updates: Vec::new(),
3553
3570
local_initiated_shutdown: None,
3554
3571
is_manual_broadcast: false,
3572
+
3573
+ post_quiescence_action: None,
3555
3574
};
3556
3575
3557
3576
Ok((funding, channel_context))
@@ -11548,7 +11567,7 @@ where
11548
11567
#[cfg(any(test, fuzzing))]
11549
11568
#[rustfmt::skip]
11550
11569
pub fn propose_quiescence<L: Deref>(
11551
- &mut self, logger: &L,
11570
+ &mut self, logger: &L, action: QuiescentAction,
11552
11571
) -> Result<Option<msgs::Stfu>, ChannelError>
11553
11572
where
11554
11573
L::Target: Logger,
@@ -11560,11 +11579,13 @@ where
11560
11579
"Channel is not in a live state to propose quiescence".to_owned()
11561
11580
));
11562
11581
}
11563
- if self.context.channel_state.is_quiescent () {
11564
- return Err(ChannelError::Ignore("Channel is already quiescent ".to_owned()));
11582
+ if self.context.post_quiescence_action.is_some () {
11583
+ return Err(ChannelError::Ignore("Channel is already quiescing ".to_owned()));
11565
11584
}
11566
11585
11567
- if self.context.channel_state.is_awaiting_quiescence()
11586
+ self.context.post_quiescence_action = Some(action);
11587
+ if self.context.channel_state.is_quiescent()
11588
+ || self.context.channel_state.is_awaiting_quiescence()
11568
11589
|| self.context.channel_state.is_local_stfu_sent()
11569
11590
{
11570
11591
return Ok(None);
@@ -11683,6 +11704,21 @@ where
11683
11704
if !is_holder_quiescence_initiator { " not" } else { "" }
11684
11705
);
11685
11706
11707
+ if is_holder_quiescence_initiator {
11708
+ match self.context.post_quiescence_action.take() {
11709
+ None => {
11710
+ debug_assert!(false);
11711
+ return Err(ChannelError::WarnAndDisconnect(
11712
+ "Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
11713
+ ));
11714
+ },
11715
+ Some(QuiescentAction::DoNothing) => {
11716
+ // In quiescence test we want to just hang out here, letting the test manually
11717
+ // leave quiescence.
11718
+ },
11719
+ }
11720
+ }
11721
+
11686
11722
Ok(None)
11687
11723
}
11688
11724
@@ -13986,6 +14022,8 @@ where
13986
14022
13987
14023
blocked_monitor_updates: blocked_monitor_updates.unwrap(),
13988
14024
is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
14025
+
14026
+ post_quiescence_action: None,
13989
14027
},
13990
14028
interactive_tx_signing_session,
13991
14029
holder_commitment_point,
0 commit comments