@@ -904,6 +904,129 @@ fn fails_creating_refund_without_blinded_paths() {
904904 assert ! ( nodes[ 0 ] . node. list_recent_payments( ) . is_empty( ) ) ;
905905}
906906
907+ /// Fails creating or paying an offer when a blinded path cannot be created because no peers are
908+ /// connected.
909+ #[ test]
910+ fn fails_creating_or_paying_for_offer_without_connected_peers ( ) {
911+ let chanmon_cfgs = create_chanmon_cfgs ( 6 ) ;
912+ let node_cfgs = create_node_cfgs ( 6 , & chanmon_cfgs) ;
913+ let node_chanmgrs = create_node_chanmgrs ( 6 , & node_cfgs, & [ None , None , None , None , None , None ] ) ;
914+ let nodes = create_network ( 6 , & node_cfgs, & node_chanmgrs) ;
915+
916+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
917+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
918+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
919+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
920+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
921+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
922+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
923+
924+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
925+
926+ disconnect_peers ( alice, & [ bob, charlie, david, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
927+ disconnect_peers ( david, & [ bob, charlie, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
928+
929+ let absolute_expiry = alice. node . duration_since_epoch ( ) + MAX_SHORT_LIVED_RELATIVE_EXPIRY ;
930+ match alice. node . create_offer_builder ( Some ( absolute_expiry) ) {
931+ Ok ( _) => panic ! ( "Expected error" ) ,
932+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: MissingPaths ) ,
933+ }
934+
935+ let mut args = ReconnectArgs :: new ( alice, bob) ;
936+ args. send_channel_ready = ( true , true ) ;
937+ reconnect_nodes ( args) ;
938+
939+ let offer = alice. node
940+ . create_offer_builder ( Some ( absolute_expiry) ) . unwrap ( )
941+ . amount_msats ( 10_000_000 )
942+ . build ( ) . unwrap ( ) ;
943+
944+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
945+
946+ match david. node . pay_for_offer ( & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None ) {
947+ Ok ( _) => panic ! ( "Expected error" ) ,
948+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: MissingPaths ) ,
949+ }
950+
951+ assert ! ( nodes[ 0 ] . node. list_recent_payments( ) . is_empty( ) ) ;
952+
953+ let mut args = ReconnectArgs :: new ( charlie, david) ;
954+ args. send_channel_ready = ( true , true ) ;
955+ reconnect_nodes ( args) ;
956+
957+ assert ! (
958+ david. node. pay_for_offer(
959+ & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None
960+ ) . is_ok( )
961+ ) ;
962+
963+ expect_recent_payment ! ( david, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
964+ }
965+
966+ /// Fails creating or sending an invoice for a refund when a blinded path cannot be created because
967+ /// no peers are connected.
968+ #[ test]
969+ fn fails_creating_refund_or_sending_invoice_without_connected_peers ( ) {
970+ let mut accept_forward_cfg = test_default_channel_config ( ) ;
971+ accept_forward_cfg. accept_forwards_to_priv_channels = true ;
972+
973+ let mut features = channelmanager:: provided_init_features ( & accept_forward_cfg) ;
974+ features. set_onion_messages_optional ( ) ;
975+ features. set_route_blinding_optional ( ) ;
976+
977+ let chanmon_cfgs = create_chanmon_cfgs ( 6 ) ;
978+ let node_cfgs = create_node_cfgs ( 6 , & chanmon_cfgs) ;
979+
980+ * node_cfgs[ 1 ] . override_init_features . borrow_mut ( ) = Some ( features) ;
981+
982+ let node_chanmgrs = create_node_chanmgrs (
983+ 6 , & node_cfgs, & [ None , Some ( accept_forward_cfg) , None , None , None , None ]
984+ ) ;
985+ let nodes = create_network ( 6 , & node_cfgs, & node_chanmgrs) ;
986+
987+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
988+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
989+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
990+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
991+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
992+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
993+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
994+
995+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
996+
997+ disconnect_peers ( alice, & [ bob, charlie, david, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
998+ disconnect_peers ( david, & [ bob, charlie, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
999+
1000+ let absolute_expiry = david. node . duration_since_epoch ( ) + MAX_SHORT_LIVED_RELATIVE_EXPIRY ;
1001+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
1002+ match david. node . create_refund_builder (
1003+ 10_000_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None
1004+ ) {
1005+ Ok ( _) => panic ! ( "Expected error" ) ,
1006+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: MissingPaths ) ,
1007+ }
1008+
1009+ let mut args = ReconnectArgs :: new ( charlie, david) ;
1010+ args. send_channel_ready = ( true , true ) ;
1011+ reconnect_nodes ( args) ;
1012+
1013+ let refund = david. node
1014+ . create_refund_builder ( 10_000_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None )
1015+ . unwrap ( )
1016+ . build ( ) . unwrap ( ) ;
1017+
1018+ match alice. node . request_refund_payment ( & refund) {
1019+ Ok ( _) => panic ! ( "Expected error" ) ,
1020+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: MissingPaths ) ,
1021+ }
1022+
1023+ let mut args = ReconnectArgs :: new ( alice, bob) ;
1024+ args. send_channel_ready = ( true , true ) ;
1025+ reconnect_nodes ( args) ;
1026+
1027+ assert ! ( alice. node. request_refund_payment( & refund) . is_ok( ) ) ;
1028+ }
1029+
9071030/// Fails creating an invoice request when the offer contains an unsupported chain.
9081031#[ test]
9091032fn fails_creating_invoice_request_for_unsupported_chain ( ) {
0 commit comments