@@ -1056,6 +1056,78 @@ fn send_invoice_for_refund_with_distinct_reply_path() {
1056
1056
assert_eq ! ( reply_path. unwrap( ) . introduction_node( ) , & IntroductionNode :: NodeId ( nodes[ 6 ] . node. get_our_node_id( ) ) ) ;
1057
1057
}
1058
1058
1059
+ /// Verifies that the invoice request message can be retried if it fails to reach the
1060
+ /// payee on the first attempt.
1061
+ #[ test]
1062
+ fn creates_and_pays_for_offer_with_retry ( ) {
1063
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1064
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1065
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
1066
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1067
+
1068
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
1069
+
1070
+ let alice = & nodes[ 0 ] ;
1071
+ let alice_id = alice. node . get_our_node_id ( ) ;
1072
+ let bob = & nodes[ 1 ] ;
1073
+ let bob_id = bob. node . get_our_node_id ( ) ;
1074
+
1075
+ let offer = alice. node
1076
+ . create_offer_builder ( None ) . unwrap ( )
1077
+ . amount_msats ( 10_000_000 )
1078
+ . build ( ) . unwrap ( ) ;
1079
+ assert_ne ! ( offer. signing_pubkey( ) , Some ( alice_id) ) ;
1080
+ assert ! ( !offer. paths( ) . is_empty( ) ) ;
1081
+ for path in offer. paths ( ) {
1082
+ assert_eq ! ( path. introduction_node( ) , & IntroductionNode :: NodeId ( alice_id) ) ;
1083
+ }
1084
+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
1085
+ bob. node . pay_for_offer ( & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None ) . unwrap ( ) ;
1086
+ expect_recent_payment ! ( bob, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
1087
+
1088
+ let _lost_onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
1089
+
1090
+ // Simulate a scenario where the original onion_message is lost before reaching Alice.
1091
+ // Use handle_message_received to regenerate the message.
1092
+ bob. node . message_received ( ) ;
1093
+ let onion_message = bob. onion_messenger . next_onion_message_for_peer ( alice_id) . unwrap ( ) ;
1094
+
1095
+ alice. onion_messenger . handle_onion_message ( & bob_id, & onion_message) ;
1096
+
1097
+ let ( invoice_request, reply_path) = extract_invoice_request ( alice, & onion_message) ;
1098
+ let payment_context = PaymentContext :: Bolt12Offer ( Bolt12OfferContext {
1099
+ offer_id : offer. id ( ) ,
1100
+ invoice_request : InvoiceRequestFields {
1101
+ payer_id : invoice_request. payer_id ( ) ,
1102
+ quantity : None ,
1103
+ payer_note_truncated : None ,
1104
+ } ,
1105
+ } ) ;
1106
+ assert_eq ! ( invoice_request. amount_msats( ) , None ) ;
1107
+ assert_ne ! ( invoice_request. payer_id( ) , bob_id) ;
1108
+ assert_eq ! ( reply_path. introduction_node( ) , & IntroductionNode :: NodeId ( bob_id) ) ;
1109
+ let onion_message = alice. onion_messenger . next_onion_message_for_peer ( bob_id) . unwrap ( ) ;
1110
+ bob. onion_messenger . handle_onion_message ( & alice_id, & onion_message) ;
1111
+
1112
+ // Expect no more OffersMessage to be enqueued by this point, even after calling
1113
+ // handle_message_received.
1114
+ bob. node . message_received ( ) ;
1115
+
1116
+ assert ! ( bob. onion_messenger. next_onion_message_for_peer( alice_id) . is_none( ) ) ;
1117
+
1118
+ let ( invoice, _) = extract_invoice ( bob, & onion_message) ;
1119
+ assert_eq ! ( invoice. amount_msats( ) , 10_000_000 ) ;
1120
+ assert_ne ! ( invoice. signing_pubkey( ) , alice_id) ;
1121
+ assert ! ( !invoice. payment_paths( ) . is_empty( ) ) ;
1122
+ for path in invoice. payment_paths ( ) {
1123
+ assert_eq ! ( path. introduction_node( ) , & IntroductionNode :: NodeId ( alice_id) ) ;
1124
+ }
1125
+ route_bolt12_payment ( bob, & [ alice] , & invoice) ;
1126
+ expect_recent_payment ! ( bob, RecentPaymentDetails :: Pending , payment_id) ;
1127
+ claim_bolt12_payment ( bob, & [ alice] , payment_context) ;
1128
+ expect_recent_payment ! ( bob, RecentPaymentDetails :: Fulfilled , payment_id) ;
1129
+ }
1130
+
1059
1131
/// Checks that a deferred invoice can be paid asynchronously from an Event::InvoiceReceived.
1060
1132
#[ test]
1061
1133
fn pays_bolt12_invoice_asynchronously ( ) {
0 commit comments