@@ -878,6 +878,190 @@ fn pays_for_refund_without_blinded_paths() {
878878 expect_recent_payment ! ( bob, RecentPaymentDetails :: Fulfilled , payment_id) ;
879879}
880880
881+ /// This test checks that when multiple potential introduction nodes are available for the payer,
882+ /// multiple `invoice_request` messages are sent for the offer, each with a different `reply_path`.
883+ #[ test]
884+ fn send_invoice_requests_with_distinct_reply_path ( ) {
885+ let mut accept_forward_cfg = test_default_channel_config ( ) ;
886+ accept_forward_cfg. accept_forwards_to_priv_channels = true ;
887+
888+ let mut features = channelmanager:: provided_init_features ( & accept_forward_cfg) ;
889+ features. set_onion_messages_optional ( ) ;
890+ features. set_route_blinding_optional ( ) ;
891+
892+ let chanmon_cfgs = create_chanmon_cfgs ( 7 ) ;
893+ let node_cfgs = create_node_cfgs ( 7 , & chanmon_cfgs) ;
894+
895+ * node_cfgs[ 1 ] . override_init_features . borrow_mut ( ) = Some ( features) ;
896+
897+ let node_chanmgrs = create_node_chanmgrs (
898+ 7 , & node_cfgs, & [ None , Some ( accept_forward_cfg) , None , None , None , None , None ]
899+ ) ;
900+ let nodes = create_network ( 7 , & node_cfgs, & node_chanmgrs) ;
901+
902+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
903+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
904+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
905+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
906+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
907+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
908+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
909+
910+ // Introduce another potential introduction node, node[6], as a candidate
911+ create_unannounced_chan_between_nodes_with_value ( & nodes, 3 , 6 , 10_000_000 , 1_000_000_000 ) ;
912+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 6 , 10_000_000 , 1_000_000_000 ) ;
913+ create_announced_chan_between_nodes_with_value ( & nodes, 4 , 6 , 10_000_000 , 1_000_000_000 ) ;
914+ create_announced_chan_between_nodes_with_value ( & nodes, 5 , 6 , 10_000_000 , 1_000_000_000 ) ;
915+
916+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
917+ let alice_id = alice. node . get_our_node_id ( ) ;
918+ let bob_id = bob. node . get_our_node_id ( ) ;
919+ let charlie_id = charlie. node . get_our_node_id ( ) ;
920+ let david_id = david. node . get_our_node_id ( ) ;
921+
922+ disconnect_peers ( alice, & [ charlie, david, & nodes[ 4 ] , & nodes[ 5 ] , & nodes[ 6 ] ] ) ;
923+ disconnect_peers ( david, & [ bob, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
924+
925+ let offer = alice. node
926+ . create_offer_builder ( None )
927+ . unwrap ( )
928+ . amount_msats ( 10_000_000 )
929+ . build ( ) . unwrap ( ) ;
930+ assert_ne ! ( offer. signing_pubkey( ) , Some ( alice_id) ) ;
931+ assert ! ( !offer. paths( ) . is_empty( ) ) ;
932+ for path in offer. paths ( ) {
933+ assert_eq ! ( path. introduction_node, IntroductionNode :: NodeId ( bob_id) ) ;
934+ }
935+
936+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
937+ david. node . pay_for_offer ( & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None )
938+ . unwrap ( ) ;
939+ expect_recent_payment ! ( david, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
940+ connect_peers ( david, bob) ;
941+
942+ // Send, extract and verify the first Invoice Request message
943+ let onion_message = david. onion_messenger . next_onion_message_for_peer ( bob_id) . unwrap ( ) ;
944+ bob. onion_messenger . handle_onion_message ( & david_id, & onion_message) ;
945+
946+ connect_peers ( alice, charlie) ;
947+
948+ let onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
949+ alice. onion_messenger . handle_onion_message ( & bob_id, & onion_message) ;
950+
951+ let ( invoice_request, reply_path) = extract_invoice_request ( alice, & onion_message) ;
952+ assert_eq ! ( invoice_request. amount_msats( ) , None ) ;
953+ assert_ne ! ( invoice_request. payer_id( ) , david_id) ;
954+ assert_eq ! ( reply_path. introduction_node, IntroductionNode :: NodeId ( charlie_id) ) ;
955+
956+ // Send, extract and verify the second Invoice Request message
957+ let onion_message = david. onion_messenger . next_onion_message_for_peer ( bob_id) . unwrap ( ) ;
958+ bob. onion_messenger . handle_onion_message ( & david_id, & onion_message) ;
959+
960+ let onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
961+ alice. onion_messenger . handle_onion_message ( & bob_id, & onion_message) ;
962+
963+ let ( invoice_request, reply_path) = extract_invoice_request ( alice, & onion_message) ;
964+
965+ assert_eq ! ( invoice_request. amount_msats( ) , None ) ;
966+ assert_ne ! ( invoice_request. payer_id( ) , david_id) ;
967+ assert_eq ! ( reply_path. introduction_node, IntroductionNode :: NodeId ( nodes[ 6 ] . node. get_our_node_id( ) ) ) ;
968+ }
969+
970+ /// This test checks that when multiple potential introduction nodes are available for the payee,
971+ /// multiple `Invoice` messages are sent for the Refund, each with a different `reply_path`.
972+ #[ test]
973+ fn send_invoice_for_refund_with_distinct_reply_path ( ) {
974+ let mut accept_forward_cfg = test_default_channel_config ( ) ;
975+ accept_forward_cfg. accept_forwards_to_priv_channels = true ;
976+
977+ let mut features = channelmanager:: provided_init_features ( & accept_forward_cfg) ;
978+ features. set_onion_messages_optional ( ) ;
979+ features. set_route_blinding_optional ( ) ;
980+
981+ let chanmon_cfgs = create_chanmon_cfgs ( 7 ) ;
982+ let node_cfgs = create_node_cfgs ( 7 , & chanmon_cfgs) ;
983+
984+ * node_cfgs[ 1 ] . override_init_features . borrow_mut ( ) = Some ( features) ;
985+
986+ let node_chanmgrs = create_node_chanmgrs (
987+ 7 , & node_cfgs, & [ None , Some ( accept_forward_cfg) , None , None , None , None , None ]
988+ ) ;
989+ let nodes = create_network ( 7 , & node_cfgs, & node_chanmgrs) ;
990+
991+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
992+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
993+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
994+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
995+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
996+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
997+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
998+
999+ // Introduce another potential introduction node, node[6], as a candidate
1000+ create_unannounced_chan_between_nodes_with_value ( & nodes, 3 , 6 , 10_000_000 , 1_000_000_000 ) ;
1001+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 6 , 10_000_000 , 1_000_000_000 ) ;
1002+ create_announced_chan_between_nodes_with_value ( & nodes, 4 , 6 , 10_000_000 , 1_000_000_000 ) ;
1003+ create_announced_chan_between_nodes_with_value ( & nodes, 5 , 6 , 10_000_000 , 1_000_000_000 ) ;
1004+
1005+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
1006+ let alice_id = alice. node . get_our_node_id ( ) ;
1007+ let bob_id = bob. node . get_our_node_id ( ) ;
1008+ let charlie_id = charlie. node . get_our_node_id ( ) ;
1009+ let david_id = david. node . get_our_node_id ( ) ;
1010+
1011+ disconnect_peers ( alice, & [ charlie, david, & nodes[ 4 ] , & nodes[ 5 ] , & nodes[ 6 ] ] ) ;
1012+ disconnect_peers ( david, & [ bob, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
1013+
1014+ let absolute_expiry = Duration :: from_secs ( u64:: MAX ) ;
1015+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
1016+ let refund = alice. node
1017+ . create_refund_builder ( 10_000_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None )
1018+ . unwrap ( )
1019+ . build ( ) . unwrap ( ) ;
1020+ assert_eq ! ( refund. amount_msats( ) , 10_000_000 ) ;
1021+ assert_eq ! ( refund. absolute_expiry( ) , Some ( absolute_expiry) ) ;
1022+ assert_ne ! ( refund. payer_id( ) , alice_id) ;
1023+ for path in refund. paths ( ) {
1024+ assert_eq ! ( path. introduction_node, IntroductionNode :: NodeId ( bob_id) ) ;
1025+ }
1026+ expect_recent_payment ! ( alice, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
1027+
1028+ let expected_invoice = david. node . request_refund_payment ( & refund) . unwrap ( ) ;
1029+
1030+ connect_peers ( david, bob) ;
1031+
1032+ // Send, extract and verify the first Invoice Request message
1033+ let onion_message = david. onion_messenger . next_onion_message_for_peer ( bob_id) . unwrap ( ) ;
1034+ bob. onion_messenger . handle_onion_message ( & david_id, & onion_message) ;
1035+
1036+ connect_peers ( alice, charlie) ;
1037+
1038+ let onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
1039+
1040+ let ( invoice, reply_path) = extract_invoice ( alice, & onion_message) ;
1041+ assert_eq ! ( invoice, expected_invoice) ;
1042+
1043+ assert_eq ! ( invoice. amount_msats( ) , 10_000_000 ) ;
1044+ assert_ne ! ( invoice. signing_pubkey( ) , david_id) ;
1045+ assert ! ( !invoice. payment_paths( ) . is_empty( ) ) ;
1046+
1047+ assert_eq ! ( reply_path. unwrap( ) . introduction_node, IntroductionNode :: NodeId ( charlie_id) ) ;
1048+
1049+ // Send, extract and verify the second Invoice Request message
1050+ let onion_message = david. onion_messenger . next_onion_message_for_peer ( bob_id) . unwrap ( ) ;
1051+ bob. onion_messenger . handle_onion_message ( & david_id, & onion_message) ;
1052+
1053+ let onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
1054+
1055+ let ( invoice, reply_path) = extract_invoice ( alice, & onion_message) ;
1056+ assert_eq ! ( invoice, expected_invoice) ;
1057+
1058+ assert_eq ! ( invoice. amount_msats( ) , 10_000_000 ) ;
1059+ assert_ne ! ( invoice. signing_pubkey( ) , david_id) ;
1060+ assert ! ( !invoice. payment_paths( ) . is_empty( ) ) ;
1061+
1062+ assert_eq ! ( reply_path. unwrap( ) . introduction_node, IntroductionNode :: NodeId ( nodes[ 6 ] . node. get_our_node_id( ) ) ) ;
1063+ }
1064+
8811065/// Checks that a deferred invoice can be paid asynchronously from an Event::InvoiceReceived.
8821066#[ test]
8831067fn pays_bolt12_invoice_asynchronously ( ) {
0 commit comments