@@ -4744,6 +4744,94 @@ where
4744
4744
}
4745
4745
}
4746
4746
4747
+ #[cfg(test)]
4748
+ pub(crate) fn abandon_splice(
4749
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4750
+ ) -> Result<(), APIError> {
4751
+ let mut res = Ok(());
4752
+ PersistenceNotifierGuard::optionally_notify(self, || {
4753
+ let result = self.internal_abandon_splice(channel_id, counterparty_node_id);
4754
+ res = result;
4755
+ match res {
4756
+ Ok(_) => NotifyOption::SkipPersistHandleEvents,
4757
+ Err(_) => NotifyOption::SkipPersistNoEvents,
4758
+ }
4759
+ });
4760
+ res
4761
+ }
4762
+
4763
+ #[cfg(test)]
4764
+ fn internal_abandon_splice(
4765
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4766
+ ) -> Result<(), APIError> {
4767
+ let per_peer_state = self.per_peer_state.read().unwrap();
4768
+
4769
+ let peer_state_mutex = match per_peer_state.get(counterparty_node_id).ok_or_else(|| {
4770
+ APIError::ChannelUnavailable {
4771
+ err: format!("Can't find a peer matching the passed counterparty node_id {counterparty_node_id}"),
4772
+ }
4773
+ }) {
4774
+ Ok(p) => p,
4775
+ Err(e) => return Err(e),
4776
+ };
4777
+
4778
+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4779
+ let peer_state = &mut *peer_state_lock;
4780
+
4781
+ // Look for the channel
4782
+ match peer_state.channel_by_id.entry(*channel_id) {
4783
+ hash_map::Entry::Occupied(mut chan_phase_entry) => {
4784
+ if !chan_phase_entry.get().context().is_connected() {
4785
+ // TODO: We should probably support this, but right now `splice_channel` refuses when
4786
+ // the peer is disconnected, so we just check it here.
4787
+ return Err(APIError::ChannelUnavailable {
4788
+ err: "Cannot abandon splice while peer is disconnected".to_owned(),
4789
+ });
4790
+ }
4791
+
4792
+ if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() {
4793
+ let (tx_abort, splice_funding_failed) = chan.abandon_splice()?;
4794
+
4795
+ peer_state.pending_msg_events.push(MessageSendEvent::SendTxAbort {
4796
+ node_id: *counterparty_node_id,
4797
+ msg: tx_abort,
4798
+ });
4799
+
4800
+ if let Some(splice_funding_failed) = splice_funding_failed {
4801
+ let pending_events = &mut self.pending_events.lock().unwrap();
4802
+ pending_events.push_back((
4803
+ events::Event::SpliceFailed {
4804
+ channel_id: *channel_id,
4805
+ counterparty_node_id: *counterparty_node_id,
4806
+ user_channel_id: chan.context.get_user_id(),
4807
+ abandoned_funding_txo: splice_funding_failed.funding_txo,
4808
+ channel_type: splice_funding_failed.channel_type,
4809
+ contributed_inputs: splice_funding_failed.contributed_inputs,
4810
+ contributed_outputs: splice_funding_failed.contributed_outputs,
4811
+ },
4812
+ None,
4813
+ ));
4814
+ }
4815
+
4816
+ Ok(())
4817
+ } else {
4818
+ Err(APIError::ChannelUnavailable {
4819
+ err: format!(
4820
+ "Channel with id {} is not funded, cannot abandon splice",
4821
+ channel_id
4822
+ ),
4823
+ })
4824
+ }
4825
+ },
4826
+ hash_map::Entry::Vacant(_) => Err(APIError::ChannelUnavailable {
4827
+ err: format!(
4828
+ "Channel with id {} not found for the passed counterparty node_id {}",
4829
+ channel_id, counterparty_node_id,
4830
+ ),
4831
+ }),
4832
+ }
4833
+ }
4834
+
4747
4835
#[rustfmt::skip]
4748
4836
fn can_forward_htlc_to_outgoing_channel(
4749
4837
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
@@ -10501,7 +10589,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
10501
10589
10502
10590
#[rustfmt::skip]
10503
10591
fn internal_tx_abort(&self, counterparty_node_id: &PublicKey, msg: &msgs::TxAbort)
10504
- -> Result<() , MsgHandleErrInternal> {
10592
+ -> Result<NotifyOption , MsgHandleErrInternal> {
10505
10593
let per_peer_state = self.per_peer_state.read().unwrap();
10506
10594
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
10507
10595
.ok_or_else(|| {
@@ -10515,13 +10603,35 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
10515
10603
match peer_state.channel_by_id.entry(msg.channel_id) {
10516
10604
hash_map::Entry::Occupied(mut chan_entry) => {
10517
10605
let res = chan_entry.get_mut().tx_abort(msg, &self.logger);
10518
- if let Some(msg) = try_channel_entry!(self, peer_state, res, chan_entry) {
10606
+ let (tx_abort, splice_failed) = try_channel_entry!(self, peer_state, res, chan_entry);
10607
+
10608
+ let persist = if tx_abort.is_some() || splice_failed.is_some() {
10609
+ NotifyOption::DoPersist
10610
+ } else {
10611
+ NotifyOption::SkipPersistNoEvents
10612
+ };
10613
+
10614
+ if let Some(tx_abort_msg) = tx_abort {
10519
10615
peer_state.pending_msg_events.push(MessageSendEvent::SendTxAbort {
10520
10616
node_id: *counterparty_node_id,
10521
- msg,
10617
+ msg: tx_abort_msg ,
10522
10618
});
10523
10619
}
10524
- Ok(())
10620
+
10621
+ if let Some(splice_funding_failed) = splice_failed {
10622
+ let pending_events = &mut self.pending_events.lock().unwrap();
10623
+ pending_events.push_back((events::Event::SpliceFailed {
10624
+ channel_id: msg.channel_id,
10625
+ counterparty_node_id: *counterparty_node_id,
10626
+ user_channel_id: chan_entry.get().context().get_user_id(),
10627
+ abandoned_funding_txo: splice_funding_failed.funding_txo,
10628
+ channel_type: splice_funding_failed.channel_type,
10629
+ contributed_inputs: splice_funding_failed.contributed_inputs,
10630
+ contributed_outputs: splice_funding_failed.contributed_outputs,
10631
+ }, None));
10632
+ }
10633
+
10634
+ Ok(persist)
10525
10635
},
10526
10636
hash_map::Entry::Vacant(_) => {
10527
10637
Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
@@ -14868,8 +14978,13 @@ where
14868
14978
// be persisted before any signatures are exchanged.
14869
14979
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
14870
14980
let res = self.internal_tx_abort(&counterparty_node_id, msg);
14981
+ let persist = match &res {
14982
+ Err(e) if e.closes_channel() => NotifyOption::DoPersist,
14983
+ Err(_) => NotifyOption::SkipPersistHandleEvents,
14984
+ Ok(persist) => *persist,
14985
+ };
14871
14986
let _ = handle_error!(self, res, counterparty_node_id);
14872
- NotifyOption::SkipPersistHandleEvents
14987
+ persist
14873
14988
});
14874
14989
}
14875
14990
0 commit comments