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