@@ -570,3 +570,71 @@ fn fails_creating_invoice_request_without_blinded_reply_path() {
570570
571571 assert ! ( nodes[ 0 ] . node. list_recent_payments( ) . is_empty( ) ) ;
572572}
573+
574+ #[ test]
575+ fn fails_creating_invoice_request_with_duplicate_payment_id ( ) {
576+ let chanmon_cfgs = create_chanmon_cfgs ( 6 ) ;
577+ let node_cfgs = create_node_cfgs ( 6 , & chanmon_cfgs) ;
578+ let node_chanmgrs = create_node_chanmgrs ( 6 , & node_cfgs, & [ None , None , None , None , None , None ] ) ;
579+ let nodes = create_network ( 6 , & node_cfgs, & node_chanmgrs) ;
580+
581+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
582+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
583+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
584+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
585+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
586+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
587+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
588+
589+ let ( alice, _bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
590+
591+ disconnect_peers ( alice, & [ charlie, david, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
592+
593+ let offer = alice. node
594+ . create_offer_builder ( "coffee" . to_string ( ) ) . unwrap ( )
595+ . amount_msats ( 10_000_000 )
596+ . build ( ) . unwrap ( ) ;
597+
598+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
599+ assert ! (
600+ david. node. pay_for_offer(
601+ & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None
602+ ) . is_ok( )
603+ ) ;
604+ expect_recent_payment ! ( david, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
605+
606+ match david. node . pay_for_offer ( & offer, None , None , None , payment_id, Retry :: Attempts ( 0 ) , None ) {
607+ Ok ( _) => panic ! ( "Expected error" ) ,
608+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: DuplicatePaymentId ) ,
609+ }
610+
611+ expect_recent_payment ! ( david, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
612+ }
613+
614+ #[ test]
615+ fn fails_creating_refund_with_duplicate_payment_id ( ) {
616+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
617+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
618+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
619+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
620+
621+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
622+
623+ let absolute_expiry = Duration :: from_secs ( u64:: MAX ) ;
624+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
625+ assert ! (
626+ nodes[ 0 ] . node. create_refund_builder(
627+ "refund" . to_string( ) , 10_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None
628+ ) . is_ok( )
629+ ) ;
630+ expect_recent_payment ! ( nodes[ 0 ] , RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
631+
632+ match nodes[ 0 ] . node . create_refund_builder (
633+ "refund" . to_string ( ) , 10_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None
634+ ) {
635+ Ok ( _) => panic ! ( "Expected error" ) ,
636+ Err ( e) => assert_eq ! ( e, Bolt12SemanticError :: DuplicatePaymentId ) ,
637+ }
638+
639+ expect_recent_payment ! ( nodes[ 0 ] , RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
640+ }
0 commit comments