@@ -4723,6 +4723,94 @@ where
4723
4723
}
4724
4724
}
4725
4725
4726
+ #[cfg(test)]
4727
+ pub(crate) fn abandon_splice(
4728
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4729
+ ) -> Result<(), APIError> {
4730
+ let mut res = Ok(());
4731
+ PersistenceNotifierGuard::optionally_notify(self, || {
4732
+ let result = self.internal_abandon_splice(channel_id, counterparty_node_id);
4733
+ res = result;
4734
+ match res {
4735
+ Ok(_) => NotifyOption::SkipPersistHandleEvents,
4736
+ Err(_) => NotifyOption::SkipPersistNoEvents,
4737
+ }
4738
+ });
4739
+ res
4740
+ }
4741
+
4742
+ #[cfg(test)]
4743
+ fn internal_abandon_splice(
4744
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4745
+ ) -> Result<(), APIError> {
4746
+ let per_peer_state = self.per_peer_state.read().unwrap();
4747
+
4748
+ let peer_state_mutex = match per_peer_state.get(counterparty_node_id).ok_or_else(|| {
4749
+ APIError::ChannelUnavailable {
4750
+ err: format!("Can't find a peer matching the passed counterparty node_id {counterparty_node_id}"),
4751
+ }
4752
+ }) {
4753
+ Ok(p) => p,
4754
+ Err(e) => return Err(e),
4755
+ };
4756
+
4757
+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4758
+ let peer_state = &mut *peer_state_lock;
4759
+
4760
+ // Look for the channel
4761
+ match peer_state.channel_by_id.entry(*channel_id) {
4762
+ hash_map::Entry::Occupied(mut chan_phase_entry) => {
4763
+ if !chan_phase_entry.get().context().is_connected() {
4764
+ // TODO: We should probably support this, but right now `splice_channel` refuses when
4765
+ // the peer is disconnected, so we just check it here.
4766
+ return Err(APIError::ChannelUnavailable {
4767
+ err: "Cannot abandon splice while peer is disconnected".to_owned(),
4768
+ });
4769
+ }
4770
+
4771
+ if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() {
4772
+ let (tx_abort, splice_funding_failed) = chan.abandon_splice()?;
4773
+
4774
+ peer_state.pending_msg_events.push(MessageSendEvent::SendTxAbort {
4775
+ node_id: *counterparty_node_id,
4776
+ msg: tx_abort,
4777
+ });
4778
+
4779
+ if let Some(splice_funding_failed) = splice_funding_failed {
4780
+ let pending_events = &mut self.pending_events.lock().unwrap();
4781
+ pending_events.push_back((
4782
+ events::Event::SpliceFailed {
4783
+ channel_id: *channel_id,
4784
+ counterparty_node_id: *counterparty_node_id,
4785
+ user_channel_id: chan.context.get_user_id(),
4786
+ abandoned_funding_txo: splice_funding_failed.funding_txo,
4787
+ channel_type: splice_funding_failed.channel_type,
4788
+ contributed_inputs: splice_funding_failed.contributed_inputs,
4789
+ contributed_outputs: splice_funding_failed.contributed_outputs,
4790
+ },
4791
+ None,
4792
+ ));
4793
+ }
4794
+
4795
+ Ok(())
4796
+ } else {
4797
+ Err(APIError::ChannelUnavailable {
4798
+ err: format!(
4799
+ "Channel with id {} is not funded, cannot abandon splice",
4800
+ channel_id
4801
+ ),
4802
+ })
4803
+ }
4804
+ },
4805
+ hash_map::Entry::Vacant(_) => Err(APIError::ChannelUnavailable {
4806
+ err: format!(
4807
+ "Channel with id {} not found for the passed counterparty node_id {}",
4808
+ channel_id, counterparty_node_id,
4809
+ ),
4810
+ }),
4811
+ }
4812
+ }
4813
+
4726
4814
#[rustfmt::skip]
4727
4815
fn can_forward_htlc_to_outgoing_channel(
4728
4816
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
0 commit comments