@@ -1075,3 +1075,99 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
10751075 ( 2 , payment_hash, required) ,
10761076 } ,
10771077) ;
1078+
1079+ #[ cfg( test) ]
1080+ mod tests {
1081+ use bitcoin:: blockdata:: constants:: genesis_block;
1082+ use bitcoin:: network:: constants:: Network ;
1083+ use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
1084+
1085+ use crate :: ln:: PaymentHash ;
1086+ use crate :: ln:: channelmanager:: { PaymentId , PaymentSendFailure } ;
1087+ use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
1088+ use crate :: ln:: outbound_payment:: { OutboundPayments , Retry } ;
1089+ use crate :: routing:: gossip:: NetworkGraph ;
1090+ use crate :: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteParameters } ;
1091+ use crate :: sync:: Arc ;
1092+ use crate :: util:: errors:: APIError ;
1093+ use crate :: util:: test_utils;
1094+
1095+ #[ test]
1096+ #[ cfg( feature = "std" ) ]
1097+ fn fails_paying_after_expiration ( ) {
1098+ do_fails_paying_after_expiration ( false ) ;
1099+ do_fails_paying_after_expiration ( true ) ;
1100+ }
1101+ #[ cfg( feature = "std" ) ]
1102+ fn do_fails_paying_after_expiration ( on_retry : bool ) {
1103+ let outbound_payments = OutboundPayments :: new ( ) ;
1104+ let logger = test_utils:: TestLogger :: new ( ) ;
1105+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1106+ let network_graph = Arc :: new ( NetworkGraph :: new ( genesis_hash, & logger) ) ;
1107+ let router = test_utils:: TestRouter :: new ( network_graph) ;
1108+ let secp_ctx = Secp256k1 :: new ( ) ;
1109+ let keys_manager = test_utils:: TestKeysInterface :: new ( & [ 0 ; 32 ] , Network :: Testnet ) ;
1110+
1111+ let past_expiry_time = std:: time:: SystemTime :: UNIX_EPOCH . elapsed ( ) . unwrap ( ) . as_secs ( ) - 2 ;
1112+ let payment_params = PaymentParameters :: from_node_id (
1113+ PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) )
1114+ . with_expiry_time ( past_expiry_time) ;
1115+ let expired_route_params = RouteParameters {
1116+ payment_params,
1117+ final_value_msat : 0 ,
1118+ final_cltv_expiry_delta : 0 ,
1119+ } ;
1120+ let err = if on_retry {
1121+ outbound_payments. retry_payment (
1122+ PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] , InFlightHtlcs :: new ( ) ,
1123+ & & keys_manager, 0 , & |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1124+ } else {
1125+ outbound_payments. send_payment (
1126+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , expired_route_params,
1127+ & & router, vec ! [ ] , InFlightHtlcs :: new ( ) , & & keys_manager, 0 , & & logger, |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1128+ } ;
1129+ if let PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err } ) = err {
1130+ assert ! ( err. contains( "Invoice expired" ) ) ;
1131+ } else { panic ! ( "Unexpected error" ) ; }
1132+ }
1133+
1134+ #[ test]
1135+ fn find_route_error ( ) {
1136+ do_find_route_error ( false ) ;
1137+ do_find_route_error ( true ) ;
1138+ }
1139+ fn do_find_route_error ( on_retry : bool ) {
1140+ let outbound_payments = OutboundPayments :: new ( ) ;
1141+ let logger = test_utils:: TestLogger :: new ( ) ;
1142+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1143+ let network_graph = Arc :: new ( NetworkGraph :: new ( genesis_hash, & logger) ) ;
1144+ let router = test_utils:: TestRouter :: new ( network_graph) ;
1145+ let secp_ctx = Secp256k1 :: new ( ) ;
1146+ let keys_manager = test_utils:: TestKeysInterface :: new ( & [ 0 ; 32 ] , Network :: Testnet ) ;
1147+
1148+ router. expect_find_route ( Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } ) ) ;
1149+
1150+ let payment_params = PaymentParameters :: from_node_id (
1151+ PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ) ;
1152+ let route_params = RouteParameters {
1153+ payment_params,
1154+ final_value_msat : 0 ,
1155+ final_cltv_expiry_delta : 0 ,
1156+ } ;
1157+ let err = if on_retry {
1158+ outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , None , PaymentId ( [ 0 ; 32 ] ) ,
1159+ & Route { paths : vec ! [ ] , payment_params : None } , Retry :: Attempts ( 1 ) ,
1160+ & & keys_manager, 0 ) . unwrap ( ) ;
1161+ outbound_payments. retry_payment (
1162+ PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] , InFlightHtlcs :: new ( ) ,
1163+ & & keys_manager, 0 , & |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1164+ } else {
1165+ outbound_payments. send_payment (
1166+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , route_params,
1167+ & & router, vec ! [ ] , InFlightHtlcs :: new ( ) , & & keys_manager, 0 , & & logger, |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1168+ } ;
1169+ if let PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err } ) = err {
1170+ assert ! ( err. contains( "Failed to find a route" ) ) ;
1171+ } else { panic ! ( "Unexpected error" ) ; }
1172+ }
1173+ }
0 commit comments