@@ -1193,6 +1193,14 @@ pub(crate) struct ShutdownResult {
1193
1193
pub(crate) splice_funding_failed: Option<SpliceFundingFailed>,
1194
1194
}
1195
1195
1196
+ /// The result of a peer disconnection.
1197
+ pub(crate) struct DisconnectResult {
1198
+ pub(crate) is_resumable: bool,
1199
+ /// If a splice was in progress when the channel was shut down, this contains
1200
+ /// the splice funding information for emitting a SpliceFailed event.
1201
+ pub(crate) splice_funding_failed: Option<SpliceFundingFailed>,
1202
+ }
1203
+
1196
1204
/// Tracks the transaction number, along with current and next commitment points.
1197
1205
/// This consolidates the logic to advance our commitment number and request new
1198
1206
/// commitment points from our signer.
@@ -1585,11 +1593,15 @@ where
1585
1593
/// Should be called when the peer is disconnected. Returns true if the channel can be resumed
1586
1594
/// when the peer reconnects (via [`Self::peer_connected_get_handshake`]). If not, the channel
1587
1595
/// must be immediately closed.
1588
- #[rustfmt::skip]
1589
- pub fn peer_disconnected_is_resumable<L: Deref>(&mut self, logger: &L) -> bool where L::Target: Logger {
1590
- match &mut self.phase {
1596
+ pub fn peer_disconnected_is_resumable<L: Deref>(&mut self, logger: &L) -> DisconnectResult
1597
+ where
1598
+ L::Target: Logger,
1599
+ {
1600
+ let is_resumable = match &mut self.phase {
1591
1601
ChannelPhase::Undefined => unreachable!(),
1592
- ChannelPhase::Funded(chan) => chan.remove_uncommitted_htlcs_and_mark_paused(logger).is_ok(),
1602
+ ChannelPhase::Funded(chan) => {
1603
+ chan.remove_uncommitted_htlcs_and_mark_paused(logger).is_ok()
1604
+ },
1593
1605
// If we get disconnected and haven't yet committed to a funding
1594
1606
// transaction, we can replay the `open_channel` on reconnection, so don't
1595
1607
// bother dropping the channel here. However, if we already committed to
@@ -1599,7 +1611,15 @@ where
1599
1611
ChannelPhase::UnfundedOutboundV1(chan) => chan.is_resumable(),
1600
1612
ChannelPhase::UnfundedInboundV1(_) => false,
1601
1613
ChannelPhase::UnfundedV2(_) => false,
1602
- }
1614
+ };
1615
+
1616
+ let splice_funding_failed = if let ChannelPhase::Funded(chan) = &mut self.phase {
1617
+ chan.maybe_fail_splice_negotiation()
1618
+ } else {
1619
+ None
1620
+ };
1621
+
1622
+ DisconnectResult { is_resumable, splice_funding_failed }
1603
1623
}
1604
1624
1605
1625
/// Should be called when the peer re-connects, returning an initial message which we should
@@ -6811,8 +6831,15 @@ where
6811
6831
}
6812
6832
6813
6833
pub fn force_shutdown(&mut self, closure_reason: ClosureReason) -> ShutdownResult {
6814
- let splice_funding_failed = self
6815
- .pending_splice
6834
+ let splice_funding_failed = self.maybe_fail_splice_negotiation();
6835
+
6836
+ let mut shutdown_result = self.context.force_shutdown(&self.funding, closure_reason);
6837
+ shutdown_result.splice_funding_failed = splice_funding_failed;
6838
+ shutdown_result
6839
+ }
6840
+
6841
+ fn maybe_fail_splice_negotiation(&mut self) -> Option<SpliceFundingFailed> {
6842
+ self.pending_splice
6816
6843
.as_mut()
6817
6844
.and_then(|pending_splice| pending_splice.funding_negotiation.take())
6818
6845
.filter(|funding_negotiation| funding_negotiation.is_initiator())
@@ -6842,11 +6869,7 @@ where
6842
6869
None
6843
6870
},
6844
6871
})
6845
- });
6846
-
6847
- let mut shutdown_result = self.context.force_shutdown(&self.funding, closure_reason);
6848
- shutdown_result.splice_funding_failed = splice_funding_failed;
6849
- shutdown_result
6872
+ })
6850
6873
}
6851
6874
6852
6875
fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
@@ -11683,9 +11706,9 @@ where
11683
11706
.map_err(|e| APIError::APIMisuseError { err: e.to_owned() })
11684
11707
}
11685
11708
11686
- fn send_splice_init(
11687
- &mut self, instructions: SpliceInstructions,
11688
- ) -> Result<msgs::SpliceInit, String> {
11709
+ fn send_splice_init(&mut self, instructions: SpliceInstructions) -> msgs::SpliceInit {
11710
+ debug_assert!( self.pending_splice.is_none());
11711
+
11689
11712
let SpliceInstructions {
11690
11713
adjusted_funding_contribution,
11691
11714
our_funding_inputs,
@@ -11695,15 +11718,6 @@ where
11695
11718
locktime,
11696
11719
} = instructions;
11697
11720
11698
- // Check if a splice has been initiated already.
11699
- // Note: only a single outstanding splice is supported (per spec)
11700
- if self.pending_splice.is_some() {
11701
- return Err(format!(
11702
- "Channel {} cannot be spliced, as it has already a splice pending",
11703
- self.context.channel_id(),
11704
- ));
11705
- }
11706
-
11707
11721
let prev_funding_input = self.funding.to_splice_funding_input();
11708
11722
let context = FundingNegotiationContext {
11709
11723
is_initiator: true,
@@ -11727,14 +11741,14 @@ where
11727
11741
let prev_funding_txid = self.funding.get_funding_txid();
11728
11742
let funding_pubkey = self.context.holder_pubkeys(prev_funding_txid).funding_pubkey;
11729
11743
11730
- Ok( msgs::SpliceInit {
11744
+ msgs::SpliceInit {
11731
11745
channel_id: self.context.channel_id,
11732
11746
funding_contribution_satoshis: adjusted_funding_contribution.to_sat(),
11733
11747
funding_feerate_per_kw,
11734
11748
locktime,
11735
11749
funding_pubkey,
11736
11750
require_confirmed_inputs: None,
11737
- })
11751
+ }
11738
11752
}
11739
11753
11740
11754
/// Checks during handling splice_init
@@ -12879,10 +12893,21 @@ where
12879
12893
"Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
12880
12894
));
12881
12895
},
12882
- Some(QuiescentAction::Splice(_instructions)) => {
12883
- return self.send_splice_init(_instructions)
12884
- .map(|splice_init| Some(StfuResponse::SpliceInit(splice_init)))
12885
- .map_err(|e| ChannelError::WarnAndDisconnect(e.to_owned()));
12896
+ Some(QuiescentAction::Splice(instructions)) => {
12897
+ if self.pending_splice.is_some() {
12898
+ debug_assert!(false);
12899
+ self.quiescent_action = Some(QuiescentAction::Splice(instructions));
12900
+
12901
+ return Err(ChannelError::WarnAndDisconnect(
12902
+ format!(
12903
+ "Channel {} cannot be spliced as it already has a splice pending",
12904
+ self.context.channel_id(),
12905
+ ),
12906
+ ));
12907
+ }
12908
+
12909
+ let splice_init = self.send_splice_init(instructions);
12910
+ return Ok(Some(StfuResponse::SpliceInit(splice_init)));
12886
12911
},
12887
12912
#[cfg(any(test, fuzzing))]
12888
12913
Some(QuiescentAction::DoNothing) => {
0 commit comments