Skip to content

Commit 890fbe5

Browse files
committed
Avoid resetting splice state on FundingNegotiation::AwaitingSignatures
Otherwise, we won't ever be able to resume a pending negotiation after a reconnection via `channel_reestablish`. Along the way, we also merge `should_reset_pending_splice_state` into `PendingFunding::can_abandon_state` to simplify the logic around when we're able to reset specific parts of the pending splice state.
1 parent f567834 commit 890fbe5

File tree

2 files changed

+59
-76
lines changed

2 files changed

+59
-76
lines changed

lightning/src/ln/channel.rs

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,8 +1694,7 @@ where
16941694
pending_v2_channel.interactive_tx_constructor.take();
16951695
},
16961696
ChannelPhase::Funded(funded_channel) => {
1697-
if funded_channel.should_reset_pending_splice_funding_negotiation().unwrap_or(true)
1698-
{
1697+
if funded_channel.should_reset_pending_splice_state() {
16991698
funded_channel.reset_pending_splice_state();
17001699
} else {
17011700
debug_assert!(false, "We should never fail an interactive funding negotiation once we're exchanging tx_signatures");
@@ -1829,18 +1828,15 @@ where
18291828
pending_v2_channel.interactive_tx_constructor.take().is_some()
18301829
},
18311830
ChannelPhase::Funded(funded_channel) => {
1832-
if let Some(should_reset) =
1833-
funded_channel.should_reset_pending_splice_funding_negotiation()
1834-
{
1835-
if should_reset {
1836-
// We may have still tracked the pending funding negotiation state, so we
1837-
// should ack with our own `tx_abort`.
1838-
funded_channel.reset_pending_splice_state()
1839-
} else {
1840-
return Err(ChannelError::close(
1841-
"Received tx_abort while awaiting tx_signatures exchange".to_owned(),
1842-
));
1843-
}
1831+
if funded_channel.has_pending_splice_awaiting_signatures() {
1832+
return Err(ChannelError::close(
1833+
"Received tx_abort while awaiting tx_signatures exchange".to_owned(),
1834+
));
1835+
}
1836+
if funded_channel.should_reset_pending_splice_state() {
1837+
let has_funding_negotiation = funded_channel.reset_pending_splice_state();
1838+
debug_assert!(has_funding_negotiation);
1839+
true
18441840
} else {
18451841
// We were not tracking the pending funding negotiation state anymore, likely
18461842
// due to a disconnection or already having sent our own `tx_abort`.
@@ -2583,13 +2579,17 @@ impl FundingNegotiation {
25832579
}
25842580

25852581
impl PendingFunding {
2586-
fn can_abandon_funding_negotiation(&self) -> bool {
2582+
fn can_abandon_state(&self) -> bool {
25872583
self.funding_negotiation
25882584
.as_ref()
25892585
.map(|funding_negotiation| {
25902586
!matches!(funding_negotiation, FundingNegotiation::AwaitingSignatures { .. })
25912587
})
2592-
.unwrap_or(true)
2588+
.unwrap_or_else(|| {
2589+
let has_negotiated_candidates = !self.negotiated_candidates.is_empty();
2590+
debug_assert!(has_negotiated_candidates);
2591+
!has_negotiated_candidates
2592+
})
25932593
}
25942594

25952595
fn check_get_splice_locked<SP: Deref>(
@@ -6773,40 +6773,35 @@ where
67736773
)
67746774
}
67756775

6776-
/// Returns `None` if there is no [`FundedChannel::pending_splice`], otherwise a boolean
6777-
/// indicating whether we should reset the splice's [`PendingFunding::funding_negotiation`].
6778-
fn should_reset_pending_splice_funding_negotiation(&self) -> Option<bool> {
6779-
self.pending_splice.as_ref().map(|pending_splice| {
6780-
if pending_splice.can_abandon_funding_negotiation() {
6781-
true
6782-
} else {
6783-
self.context
6784-
.interactive_tx_signing_session
6785-
.as_ref()
6786-
.map(|signing_session| !signing_session.has_received_commitment_signed())
6787-
.unwrap_or_else(|| {
6788-
debug_assert!(false);
6789-
false
6790-
})
6791-
}
6792-
})
6776+
fn has_pending_splice_awaiting_signatures(&self) -> bool {
6777+
self.pending_splice
6778+
.as_ref()
6779+
.and_then(|pending_splice| pending_splice.funding_negotiation.as_ref())
6780+
.map(|funding_negotiation| {
6781+
matches!(funding_negotiation, FundingNegotiation::AwaitingSignatures { .. })
6782+
})
6783+
.unwrap_or(false)
67936784
}
67946785

6786+
/// Returns a boolean indicating whether we should reset the splice's
6787+
/// [`PendingFunding::funding_negotiation`].
67956788
fn should_reset_pending_splice_state(&self) -> bool {
6796-
self.should_reset_pending_splice_funding_negotiation().unwrap_or(true)
6797-
&& self.pending_funding().is_empty()
6789+
self.pending_splice
6790+
.as_ref()
6791+
.map(|pending_splice| pending_splice.can_abandon_state())
6792+
.unwrap_or(false)
67986793
}
67996794

68006795
fn reset_pending_splice_state(&mut self) -> bool {
6801-
debug_assert!(self.should_reset_pending_splice_funding_negotiation().unwrap_or(true));
6796+
debug_assert!(self.should_reset_pending_splice_state());
6797+
debug_assert!(self.context.interactive_tx_signing_session.is_none());
68026798
self.context.channel_state.clear_quiescent();
6803-
self.context.interactive_tx_signing_session.take();
68046799
let has_funding_negotiation = self
68056800
.pending_splice
68066801
.as_mut()
68076802
.and_then(|pending_splice| pending_splice.funding_negotiation.take())
68086803
.is_some();
6809-
if self.should_reset_pending_splice_state() {
6804+
if self.pending_funding().is_empty() {
68106805
self.pending_splice.take();
68116806
}
68126807
has_funding_negotiation
@@ -8948,13 +8943,16 @@ where
89488943
}
89498944
self.context.channel_state.clear_local_stfu_sent();
89508945
self.context.channel_state.clear_remote_stfu_sent();
8951-
if self.should_reset_pending_splice_funding_negotiation().unwrap_or(true) {
8952-
// If we were in quiescence but a splice was never negotiated, or the negotiation
8953-
// failed due to disconnecting, we shouldn't be quiescent anymore upon reconnecting.
8954-
// If there was a pending splice negotiation that has failed due to disconnecting,
8955-
// we also take the opportunity to clean up our state.
8946+
if self.should_reset_pending_splice_state() {
8947+
// If there was a pending splice negotiation that failed due to disconnecting, we
8948+
// also take the opportunity to clean up our state.
89568949
self.reset_pending_splice_state();
89578950
debug_assert!(!self.context.channel_state.is_quiescent());
8951+
} else if !self.has_pending_splice_awaiting_signatures() {
8952+
// We shouldn't be quiescent anymore upon reconnecting if:
8953+
// - We were in quiescence but a splice/RBF was never negotiated or
8954+
// - We were in quiescence but the splice negotiation failed due to disconnecting
8955+
self.context.channel_state.clear_quiescent();
89588956
}
89598957
}
89608958

@@ -13992,10 +13990,13 @@ where
1399213990
}
1399313991
channel_state.clear_local_stfu_sent();
1399413992
channel_state.clear_remote_stfu_sent();
13995-
if self.should_reset_pending_splice_funding_negotiation().unwrap_or(true) {
13996-
// If we were in quiescence but a splice was never negotiated, or the
13997-
// negotiation failed due to disconnecting, we shouldn't be quiescent
13998-
// anymore upon reconnecting.
13993+
if self.should_reset_pending_splice_state()
13994+
|| !self.has_pending_splice_awaiting_signatures()
13995+
{
13996+
// We shouldn't be quiescent anymore upon reconnecting if:
13997+
// - We were in quiescence but a splice/RBF was never negotiated or
13998+
// - We were in quiescence but the splice negotiation failed due to
13999+
// disconnecting
1399914000
channel_state.clear_quiescent();
1400014001
}
1400114002
},
@@ -14360,19 +14361,10 @@ where
1436014361
let holder_commitment_point_next = self.holder_commitment_point.next_point();
1436114362
let holder_commitment_point_pending_next = self.holder_commitment_point.pending_next_point;
1436214363

14363-
let interactive_tx_signing_session =
14364-
if self.should_reset_pending_splice_funding_negotiation().unwrap_or(false) {
14365-
None
14366-
} else {
14367-
self.context.interactive_tx_signing_session.as_ref()
14368-
};
14369-
let pending_splice = if self.should_reset_pending_splice_state() {
14370-
None
14371-
} else {
14372-
// We don't have to worry about resetting the pending `FundingNegotiation` because we
14373-
// can only read `FundingNegotiation::AwaitingSignatures` variants anyway.
14374-
self.pending_splice.as_ref()
14375-
};
14364+
// We don't have to worry about resetting the pending `FundingNegotiation` because we
14365+
// can only read `FundingNegotiation::AwaitingSignatures` variants anyway.
14366+
let pending_splice =
14367+
self.pending_splice.as_ref().filter(|_| !self.should_reset_pending_splice_state());
1437614368

1437714369
write_tlv_fields!(writer, {
1437814370
(0, self.context.announcement_sigs, option),
@@ -14417,7 +14409,7 @@ where
1441714409
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
1441814410
(55, removed_htlc_attribution_data, optional_vec), // Added in 0.2
1441914411
(57, holding_cell_attribution_data, optional_vec), // Added in 0.2
14420-
(58, interactive_tx_signing_session, option), // Added in 0.2
14412+
(58, self.context.interactive_tx_signing_session, option), // Added in 0.2
1442114413
(59, self.funding.minimum_depth_override, option), // Added in 0.2
1442214414
(60, self.context.historical_scids, optional_vec), // Added in 0.2
1442314415
(61, fulfill_attribution_data, optional_vec), // Added in 0.2

lightning/src/ln/splicing_tests.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,9 @@ fn do_test_splice_state_reset_on_disconnect(reload: bool) {
414414
)
415415
.unwrap();
416416

417-
// Attempt a splice negotiation that only goes up to exchanging `tx_complete`. Reconnecting
418-
// should implicitly abort the negotiation and reset the splice state such that we're able to
419-
// retry another splice later.
417+
// Attempt a splice negotiation that ends mid-construction of the funding transaction.
418+
// Reconnecting should implicitly abort the negotiation and reset the splice state such that
419+
// we're able to retry another splice later.
420420
let stfu = get_event_msg!(nodes[0], MessageSendEvent::SendStfu, node_id_1);
421421
nodes[1].node.handle_stfu(node_id_0, &stfu);
422422
let stfu = get_event_msg!(nodes[1], MessageSendEvent::SendStfu, node_id_0);
@@ -427,18 +427,9 @@ fn do_test_splice_state_reset_on_disconnect(reload: bool) {
427427
let splice_ack = get_event_msg!(nodes[1], MessageSendEvent::SendSpliceAck, node_id_0);
428428
nodes[0].node.handle_splice_ack(node_id_1, &splice_ack);
429429

430-
let new_funding_script = chan_utils::make_funding_redeemscript(
431-
&splice_init.funding_pubkey,
432-
&splice_ack.funding_pubkey,
433-
)
434-
.to_p2wsh();
435-
let _ = complete_interactive_funding_negotiation(
436-
&nodes[0],
437-
&nodes[1],
438-
channel_id,
439-
contribution.clone(),
440-
new_funding_script,
441-
);
430+
let tx_add_input = get_event_msg!(nodes[0], MessageSendEvent::SendTxAddInput, node_id_1);
431+
nodes[1].node.handle_tx_add_input(node_id_0, &tx_add_input);
432+
let _ = get_event_msg!(nodes[1], MessageSendEvent::SendTxComplete, node_id_0);
442433

443434
if reload {
444435
let encoded_monitor_0 = get_monitor!(nodes[0], channel_id).encode();

0 commit comments

Comments
 (0)