@@ -32,7 +32,7 @@ use crate::prelude::{new_hash_map, HashMap};
32
32
use crate :: sync:: { Arc , Mutex , MutexGuard , RwLock } ;
33
33
34
34
use lightning:: events:: HTLCDestination ;
35
- use lightning:: ln:: channelmanager:: { AChannelManager , InterceptId } ;
35
+ use lightning:: ln:: channelmanager:: { AChannelManager , FailureCode , InterceptId } ;
36
36
use lightning:: ln:: msgs:: { ErrorAction , LightningError } ;
37
37
use lightning:: ln:: types:: ChannelId ;
38
38
use lightning:: util:: errors:: APIError ;
@@ -1005,6 +1005,104 @@ where
1005
1005
Ok ( ( ) )
1006
1006
}
1007
1007
1008
+ /// Abandons a channel open attempt by pruning all state related to the channel open.
1009
+ ///
1010
+ /// This function should be used when a channel open attempt is to be abandoned entirely,
1011
+ /// without resetting the state for a potential payment retry. It removes the intercept SCID
1012
+ /// mapping along with any outbound channel state and related channel ID mappings associated with
1013
+ /// the specified `user_channel_id`.
1014
+ pub fn channel_open_abandoned (
1015
+ & self , counterparty_node_id : & PublicKey , user_channel_id : u128 ,
1016
+ ) -> Result < ( ) , APIError > {
1017
+ let outer_state_lock = self . per_peer_state . read ( ) . unwrap ( ) ;
1018
+ let inner_state_lock =
1019
+ outer_state_lock. get ( counterparty_node_id) . ok_or_else ( || APIError :: APIMisuseError {
1020
+ err : format ! ( "No counterparty state for: {}" , counterparty_node_id) ,
1021
+ } ) ?;
1022
+ let mut peer_state = inner_state_lock. lock ( ) . unwrap ( ) ;
1023
+
1024
+ let intercept_scid = peer_state
1025
+ . intercept_scid_by_user_channel_id
1026
+ . remove ( & user_channel_id)
1027
+ . ok_or_else ( || APIError :: APIMisuseError {
1028
+ err : format ! ( "Could not find a channel with user_channel_id {}" , user_channel_id) ,
1029
+ } ) ?;
1030
+
1031
+ peer_state. outbound_channels_by_intercept_scid . remove ( & intercept_scid) ;
1032
+
1033
+ peer_state. intercept_scid_by_channel_id . retain ( |_, & mut scid| scid != intercept_scid) ;
1034
+
1035
+ Ok ( ( ) )
1036
+ }
1037
+
1038
+ /// Used to fail intercepted HTLCs backwards when a channel open attempt ultimately fails.
1039
+ ///
1040
+ /// This function should be called after receiving an [`LSPS2ServiceEvent::OpenChannel`] event
1041
+ /// but only if the channel could not be successfully established. It resets the JIT channel
1042
+ /// state so that the payer may try the payment again.
1043
+ ///
1044
+ /// [`LSPS2ServiceEvent::OpenChannel`]: crate::lsps2::event::LSPS2ServiceEvent::OpenChannel
1045
+ pub fn channel_open_failed (
1046
+ & self , counterparty_node_id : & PublicKey , user_channel_id : u128 ,
1047
+ ) -> Result < ( ) , APIError > {
1048
+ let outer_state_lock = self . per_peer_state . read ( ) . unwrap ( ) ;
1049
+
1050
+ let inner_state_lock =
1051
+ outer_state_lock. get ( counterparty_node_id) . ok_or_else ( || APIError :: APIMisuseError {
1052
+ err : format ! ( "No counterparty state for: {}" , counterparty_node_id) ,
1053
+ } ) ?;
1054
+
1055
+ let mut peer_state = inner_state_lock. lock ( ) . unwrap ( ) ;
1056
+
1057
+ let intercept_scid = peer_state
1058
+ . intercept_scid_by_user_channel_id
1059
+ . get ( & user_channel_id)
1060
+ . copied ( )
1061
+ . ok_or_else ( || APIError :: APIMisuseError {
1062
+ err : format ! ( "Could not find a channel with user_channel_id {}" , user_channel_id) ,
1063
+ } ) ?;
1064
+
1065
+ let jit_channel = peer_state
1066
+ . outbound_channels_by_intercept_scid
1067
+ . get_mut ( & intercept_scid)
1068
+ . ok_or_else ( || APIError :: APIMisuseError {
1069
+ err : format ! (
1070
+ "Failed to map the stored intercept_scid {} for the provided user_channel_id {} to a channel." ,
1071
+ intercept_scid, user_channel_id,
1072
+ ) ,
1073
+ } ) ?;
1074
+
1075
+ jit_channel. state = match & jit_channel. state {
1076
+ OutboundJITChannelState :: PendingChannelOpen { payment_queue, .. } => {
1077
+ let mut queue = payment_queue. lock ( ) . unwrap ( ) ;
1078
+ let payment_hashes: Vec < _ > = queue
1079
+ . clear ( )
1080
+ . into_iter ( )
1081
+ . map ( |htlc| htlc. payment_hash )
1082
+ . collect :: < std:: collections:: HashSet < _ > > ( )
1083
+ . into_iter ( )
1084
+ . collect ( ) ;
1085
+
1086
+ for payment_hash in payment_hashes {
1087
+ self . channel_manager . get_cm ( ) . fail_htlc_backwards_with_reason (
1088
+ & payment_hash,
1089
+ FailureCode :: TemporaryNodeFailure ,
1090
+ ) ;
1091
+ }
1092
+ OutboundJITChannelState :: PendingInitialPayment {
1093
+ payment_queue : payment_queue. clone ( ) ,
1094
+ }
1095
+ } ,
1096
+ _ => {
1097
+ return Err ( APIError :: APIMisuseError {
1098
+ err : "Channel is not in the PendingChannelOpen state." . to_string ( ) ,
1099
+ } )
1100
+ } ,
1101
+ } ;
1102
+
1103
+ Ok ( ( ) )
1104
+ }
1105
+
1008
1106
/// Forward [`Event::ChannelReady`] event parameters into this function.
1009
1107
///
1010
1108
/// Will forward the intercepted HTLC if it matches a channel
0 commit comments