Skip to content

Commit dd02498

Browse files
committed
Stop skipping the line in quiescence if our peer speaks first
In the case where we prepare to initiate quiescence, but cannot yet send our `stfu` because we're waiting on some channel operations to settle, and our peer ultimately sends their `stfu` before we can, we would detect this case and, if we were able, send an `stfu` which would allow us to send "something fundamental" first. While this is a nifty optimization, its a bit overkill - the chance that both us and our peer decide to attempt something fundamental at the same time is pretty low, and worse this required additional state tracking. We simply remove this optimization here, simplifying the quiescence state machine a good bit.
1 parent 7bb1652 commit dd02498

File tree

2 files changed

+18
-51
lines changed

2 files changed

+18
-51
lines changed

lightning/src/ln/channel.rs

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,10 +2728,6 @@ where
27282728
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
27292729
/// store it here and only release it to the `ChannelManager` once it asks for it.
27302730
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>,
27352731
}
27362732

27372733
/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3306,8 +3302,6 @@ where
33063302
blocked_monitor_updates: Vec::new(),
33073303

33083304
is_manual_broadcast: false,
3309-
3310-
is_holder_quiescence_initiator: None,
33113305
};
33123306

33133307
Ok((funding, channel_context))
@@ -3544,8 +3538,6 @@ where
35443538
blocked_monitor_updates: Vec::new(),
35453539
local_initiated_shutdown: None,
35463540
is_manual_broadcast: false,
3547-
3548-
is_holder_quiescence_initiator: None,
35493541
};
35503542

35513543
Ok((funding, channel_context))
@@ -8202,7 +8194,6 @@ where
82028194
self.context.channel_state.clear_local_stfu_sent();
82038195
self.context.channel_state.clear_remote_stfu_sent();
82048196
self.context.channel_state.clear_quiescent();
8205-
self.context.is_holder_quiescence_initiator.take();
82068197
}
82078198

82088199
self.context.channel_state.set_peer_disconnected();
@@ -11591,18 +11582,10 @@ where
1159111582
self.context.channel_state.clear_awaiting_quiescence();
1159211583
self.context.channel_state.clear_remote_stfu_sent();
1159311584
self.context.channel_state.set_quiescent();
11594-
if let Some(initiator) = self.context.is_holder_quiescence_initiator.as_ref() {
11595-
log_debug!(
11596-
logger,
11597-
"Responding to counterparty stfu with our own, channel is now quiescent and we are{} the initiator",
11598-
if !initiator { " not" } else { "" }
11599-
);
11600-
11601-
*initiator
11602-
} else {
11603-
debug_assert!(false, "Quiescence initiator must have been set when we received stfu");
11604-
false
11605-
}
11585+
// We are sending an stfu in response to our couterparty's stfu, but had not yet sent
11586+
// our own stfu (even if `awaiting_quiescence` was set). Thus, the counterparty is the
11587+
// initiator and they can do "something fundamental".
11588+
false
1160611589
} else {
1160711590
log_debug!(logger, "Sending stfu as quiescence initiator");
1160811591
debug_assert!(self.context.channel_state.is_awaiting_quiescence());
@@ -11633,9 +11616,7 @@ where
1163311616
));
1163411617
}
1163511618

11636-
if self.context.channel_state.is_awaiting_quiescence()
11637-
|| !self.context.channel_state.is_local_stfu_sent()
11638-
{
11619+
if !self.context.channel_state.is_local_stfu_sent() {
1163911620
if !msg.initiator {
1164011621
return Err(ChannelError::WarnAndDisconnect(
1164111622
"Peer sent unexpected `stfu` without signaling as initiator".to_owned()
@@ -11649,23 +11630,13 @@ where
1164911630
// then.
1165011631
self.context.channel_state.set_remote_stfu_sent();
1165111632

11652-
let is_holder_initiator = if self.context.channel_state.is_awaiting_quiescence() {
11653-
// We were also planning to propose quiescence, let the tie-breaker decide the
11654-
// initiator.
11655-
self.funding.is_outbound()
11656-
} else {
11657-
false
11658-
};
11659-
self.context.is_holder_quiescence_initiator = Some(is_holder_initiator);
11660-
1166111633
log_debug!(logger, "Received counterparty stfu proposing quiescence");
1166211634
return self.send_stfu(logger).map(|stfu| Some(stfu));
1166311635
}
1166411636

1166511637
// We already sent `stfu` and are now processing theirs. It may be in response to ours, or
1166611638
// we happened to both send `stfu` at the same time and a tie-break is needed.
1166711639
let is_holder_quiescence_initiator = !msg.initiator || self.funding.is_outbound();
11668-
self.context.is_holder_quiescence_initiator = Some(is_holder_quiescence_initiator);
1166911640

1167011641
// We were expecting to receive `stfu` because we already sent ours.
1167111642
self.mark_response_received();
@@ -11733,13 +11704,10 @@ where
1173311704
debug_assert!(!self.context.channel_state.is_local_stfu_sent());
1173411705
debug_assert!(!self.context.channel_state.is_remote_stfu_sent());
1173511706

11736-
if self.context.channel_state.is_quiescent() {
11737-
self.mark_response_received();
11738-
self.context.channel_state.clear_quiescent();
11739-
self.context.is_holder_quiescence_initiator.take().expect("Must always be set while quiescent")
11740-
} else {
11741-
false
11742-
}
11707+
self.mark_response_received();
11708+
let was_quiescent = self.context.channel_state.is_quiescent();
11709+
self.context.channel_state.clear_quiescent();
11710+
was_quiescent
1174311711
}
1174411712

1174511713
pub fn remove_legacy_scids_before_block(&mut self, height: u32) -> alloc::vec::Drain<'_, u64> {
@@ -14001,8 +13969,6 @@ where
1400113969

1400213970
blocked_monitor_updates: blocked_monitor_updates.unwrap(),
1400313971
is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
14004-
14005-
is_holder_quiescence_initiator: None,
1400613972
},
1400713973
interactive_tx_signing_session,
1400813974
holder_commitment_point,

lightning/src/ln/quiescence_tests.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn test_quiescence_tie() {
3333
assert!(stfu_node_0.initiator && stfu_node_1.initiator);
3434

3535
assert!(nodes[0].node.exit_quiescence(&nodes[1].node.get_our_node_id(), &chan_id).unwrap());
36-
assert!(!nodes[1].node.exit_quiescence(&nodes[0].node.get_our_node_id(), &chan_id).unwrap());
36+
assert!(nodes[1].node.exit_quiescence(&nodes[0].node.get_our_node_id(), &chan_id).unwrap());
3737
}
3838

3939
#[test]
@@ -173,7 +173,8 @@ fn allow_shutdown_while_awaiting_quiescence(local_shutdown: bool) {
173173

174174
// Now that the state machine is no longer pending, and `closing_signed` is ready to be sent,
175175
// make sure we're still not waiting for the quiescence handshake to complete.
176-
local_node.node.exit_quiescence(&remote_node_id, &chan_id).unwrap();
176+
// Note that we never actually reached full quiescence here.
177+
assert!(!local_node.node.exit_quiescence(&remote_node_id, &chan_id).unwrap());
177178

178179
let _ = get_event_msg!(local_node, MessageSendEvent::SendClosingSigned, remote_node_id);
179180
check_added_monitors(local_node, 2); // One for the last revoke_and_ack, another for closing_signed
@@ -279,8 +280,8 @@ fn test_quiescence_waits_for_async_signer_and_monitor_update() {
279280
let stfu = get_event_msg!(&nodes[0], MessageSendEvent::SendStfu, node_id_1);
280281
nodes[1].node.handle_stfu(node_id_0, &stfu);
281282

282-
nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap();
283-
nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap();
283+
assert!(nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap());
284+
assert!(nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap());
284285

285286
// After exiting quiescence, we should be able to resume payments from nodes[0].
286287
send_payment(&nodes[0], &[&nodes[1]], payment_amount);
@@ -336,8 +337,8 @@ fn test_quiescence_on_final_revoke_and_ack_pending_monitor_update() {
336337
panic!();
337338
}
338339

339-
nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap();
340-
nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap();
340+
assert!(nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap());
341+
assert!(nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap());
341342
}
342343

343344
#[test]
@@ -406,8 +407,8 @@ fn quiescence_updates_go_to_holding_cell(fail_htlc: bool) {
406407
let stfu = get_event_msg!(&nodes[0], MessageSendEvent::SendStfu, node_id_1);
407408
nodes[1].node.handle_stfu(node_id_0, &stfu);
408409

409-
nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap();
410-
nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap();
410+
assert!(nodes[0].node.exit_quiescence(&node_id_1, &chan_id).unwrap());
411+
assert!(nodes[1].node.exit_quiescence(&node_id_0, &chan_id).unwrap());
411412

412413
// Now that quiescence is over, nodes are allowed to make updates again. nodes[1] will have its
413414
// outbound HTLC finally go out, along with the fail/claim of nodes[0]'s payment.

0 commit comments

Comments
 (0)