@@ -1124,3 +1124,99 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1124
1124
( 2 , payment_hash, required) ,
1125
1125
} ,
1126
1126
) ;
1127
+
1128
+ #[ cfg( test) ]
1129
+ mod tests {
1130
+ use bitcoin:: blockdata:: constants:: genesis_block;
1131
+ use bitcoin:: network:: constants:: Network ;
1132
+ use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
1133
+
1134
+ use crate :: ln:: PaymentHash ;
1135
+ use crate :: ln:: channelmanager:: { PaymentId , PaymentSendFailure } ;
1136
+ use crate :: ln:: msgs:: { ErrorAction , LightningError } ;
1137
+ use crate :: ln:: outbound_payment:: { OutboundPayments , Retry } ;
1138
+ use crate :: routing:: gossip:: NetworkGraph ;
1139
+ use crate :: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteParameters } ;
1140
+ use crate :: sync:: Arc ;
1141
+ use crate :: util:: errors:: APIError ;
1142
+ use crate :: util:: test_utils;
1143
+
1144
+ #[ test]
1145
+ #[ cfg( feature = "std" ) ]
1146
+ fn fails_paying_after_expiration ( ) {
1147
+ do_fails_paying_after_expiration ( false ) ;
1148
+ do_fails_paying_after_expiration ( true ) ;
1149
+ }
1150
+ #[ cfg( feature = "std" ) ]
1151
+ fn do_fails_paying_after_expiration ( on_retry : bool ) {
1152
+ let outbound_payments = OutboundPayments :: new ( ) ;
1153
+ let logger = test_utils:: TestLogger :: new ( ) ;
1154
+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1155
+ let network_graph = Arc :: new ( NetworkGraph :: new ( genesis_hash, & logger) ) ;
1156
+ let router = test_utils:: TestRouter :: new ( network_graph) ;
1157
+ let secp_ctx = Secp256k1 :: new ( ) ;
1158
+ let keys_manager = test_utils:: TestKeysInterface :: new ( & [ 0 ; 32 ] , Network :: Testnet ) ;
1159
+
1160
+ let past_expiry_time = std:: time:: SystemTime :: UNIX_EPOCH . elapsed ( ) . unwrap ( ) . as_secs ( ) - 2 ;
1161
+ let payment_params = PaymentParameters :: from_node_id (
1162
+ PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) )
1163
+ . with_expiry_time ( past_expiry_time) ;
1164
+ let expired_route_params = RouteParameters {
1165
+ payment_params,
1166
+ final_value_msat : 0 ,
1167
+ final_cltv_expiry_delta : 0 ,
1168
+ } ;
1169
+ let err = if on_retry {
1170
+ outbound_payments. pay_internal (
1171
+ PaymentId ( [ 0 ; 32 ] ) , None , expired_route_params, & & router, vec ! [ ] , InFlightHtlcs :: new ( ) ,
1172
+ & & keys_manager, & & keys_manager, 0 , & |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1173
+ } else {
1174
+ outbound_payments. send_payment (
1175
+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , expired_route_params,
1176
+ & & router, vec ! [ ] , InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1177
+ } ;
1178
+ if let PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err } ) = err {
1179
+ assert ! ( err. contains( "Invoice expired" ) ) ;
1180
+ } else { panic ! ( "Unexpected error" ) ; }
1181
+ }
1182
+
1183
+ #[ test]
1184
+ fn find_route_error ( ) {
1185
+ do_find_route_error ( false ) ;
1186
+ do_find_route_error ( true ) ;
1187
+ }
1188
+ fn do_find_route_error ( on_retry : bool ) {
1189
+ let outbound_payments = OutboundPayments :: new ( ) ;
1190
+ let logger = test_utils:: TestLogger :: new ( ) ;
1191
+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
1192
+ let network_graph = Arc :: new ( NetworkGraph :: new ( genesis_hash, & logger) ) ;
1193
+ let router = test_utils:: TestRouter :: new ( network_graph) ;
1194
+ let secp_ctx = Secp256k1 :: new ( ) ;
1195
+ let keys_manager = test_utils:: TestKeysInterface :: new ( & [ 0 ; 32 ] , Network :: Testnet ) ;
1196
+
1197
+ router. expect_find_route ( Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } ) ) ;
1198
+
1199
+ let payment_params = PaymentParameters :: from_node_id (
1200
+ PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ) ;
1201
+ let route_params = RouteParameters {
1202
+ payment_params,
1203
+ final_value_msat : 0 ,
1204
+ final_cltv_expiry_delta : 0 ,
1205
+ } ;
1206
+ let err = if on_retry {
1207
+ outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , None , PaymentId ( [ 0 ; 32 ] ) ,
1208
+ & Route { paths : vec ! [ ] , payment_params : None } , Retry :: Attempts ( 1 ) , Some ( route_params. clone ( ) ) ,
1209
+ & & keys_manager, 0 ) . unwrap ( ) ;
1210
+ outbound_payments. pay_internal (
1211
+ PaymentId ( [ 0 ; 32 ] ) , None , route_params, & & router, vec ! [ ] , InFlightHtlcs :: new ( ) ,
1212
+ & & keys_manager, & & keys_manager, 0 , & |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1213
+ } else {
1214
+ outbound_payments. send_payment (
1215
+ PaymentHash ( [ 0 ; 32 ] ) , & None , PaymentId ( [ 0 ; 32 ] ) , Retry :: Attempts ( 0 ) , route_params,
1216
+ & & router, vec ! [ ] , InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, |_, _, _, _, _, _, _, _, _| Ok ( ( ) ) ) . unwrap_err ( )
1217
+ } ;
1218
+ if let PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err } ) = err {
1219
+ assert ! ( err. contains( "Failed to find a route" ) ) ;
1220
+ } else { panic ! ( "Unexpected error" ) ; }
1221
+ }
1222
+ }
0 commit comments