@@ -54,6 +54,7 @@ use crate::offers::invoice::Bolt12Invoice;
54
54
use crate :: offers:: invoice_error:: InvoiceError ;
55
55
use crate :: offers:: invoice_request:: { InvoiceRequest , InvoiceRequestFields } ;
56
56
use crate :: offers:: parse:: Bolt12SemanticError ;
57
+ use crate :: offers:: test_utils:: is_properly_padded;
57
58
use crate :: onion_message:: messenger:: PeeledOnion ;
58
59
use crate :: onion_message:: offers:: OffersMessage ;
59
60
use crate :: onion_message:: packet:: ParsedOnionMessageContents ;
@@ -1724,3 +1725,85 @@ fn fails_paying_invoice_more_than_once() {
1724
1725
let invoice_error = extract_invoice_error ( alice, & onion_message) ;
1725
1726
assert_eq ! ( invoice_error, InvoiceError :: from_string( "DuplicateInvoice" . to_string( ) ) ) ;
1726
1727
}
1728
+
1729
+ /// This test verifies that both the blinded message paths and blinded payment
1730
+ /// paths are properly padded and function as expected.
1731
+ #[ test]
1732
+ fn test_blinded_path_padding ( ) {
1733
+ let mut accept_forward_cfg = test_default_channel_config ( ) ;
1734
+ accept_forward_cfg. accept_forwards_to_priv_channels = true ;
1735
+
1736
+ let mut features = channelmanager:: provided_init_features ( & accept_forward_cfg) ;
1737
+ features. set_onion_messages_optional ( ) ;
1738
+ features. set_route_blinding_optional ( ) ;
1739
+
1740
+ let chanmon_cfgs = create_chanmon_cfgs ( 6 ) ;
1741
+ let node_cfgs = create_node_cfgs ( 6 , & chanmon_cfgs) ;
1742
+
1743
+ * node_cfgs[ 1 ] . override_init_features . borrow_mut ( ) = Some ( features) ;
1744
+
1745
+ let node_chanmgrs = create_node_chanmgrs (
1746
+ 6 , & node_cfgs, & [ None , Some ( accept_forward_cfg) , None , None , None , None ]
1747
+ ) ;
1748
+ let nodes = create_network ( 6 , & node_cfgs, & node_chanmgrs) ;
1749
+
1750
+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000_000 ) ;
1751
+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 10_000_000 , 1_000_000_000 ) ;
1752
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 1_000_000_000 ) ;
1753
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 4 , 10_000_000 , 1_000_000_000 ) ;
1754
+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 5 , 10_000_000 , 1_000_000_000 ) ;
1755
+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 4 , 10_000_000 , 1_000_000_000 ) ;
1756
+ create_announced_chan_between_nodes_with_value ( & nodes, 2 , 5 , 10_000_000 , 1_000_000_000 ) ;
1757
+
1758
+ let ( alice, bob, charlie, david) = ( & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ) ;
1759
+ let alice_id = alice. node . get_our_node_id ( ) ;
1760
+ let bob_id = bob. node . get_our_node_id ( ) ;
1761
+ let charlie_id = charlie. node . get_our_node_id ( ) ;
1762
+ let david_id = david. node . get_our_node_id ( ) ;
1763
+
1764
+ disconnect_peers ( alice, & [ charlie, david, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
1765
+ disconnect_peers ( david, & [ bob, & nodes[ 4 ] , & nodes[ 5 ] ] ) ;
1766
+
1767
+ let absolute_expiry = Duration :: from_secs ( u64:: MAX ) ;
1768
+ let payment_id = PaymentId ( [ 1 ; 32 ] ) ;
1769
+ let refund = david. node
1770
+ . create_refund_builder ( 10_000_000 , absolute_expiry, payment_id, Retry :: Attempts ( 0 ) , None )
1771
+ . unwrap ( )
1772
+ . build ( ) . unwrap ( ) ;
1773
+ assert ! ( !refund. paths( ) . is_empty( ) ) ;
1774
+ for path in refund. paths ( ) {
1775
+ assert_eq ! ( path. introduction_node, IntroductionNode :: NodeId ( charlie_id) ) ;
1776
+ // Verify that the blinded message paths are properly padded.
1777
+ is_properly_padded ( path) ;
1778
+ }
1779
+ expect_recent_payment ! ( david, RecentPaymentDetails :: AwaitingInvoice , payment_id) ;
1780
+
1781
+ let payment_context = PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ;
1782
+ let expected_invoice = alice. node . request_refund_payment ( & refund) . unwrap ( ) ;
1783
+
1784
+ connect_peers ( alice, charlie) ;
1785
+
1786
+ let onion_message = alice. onion_messenger . next_onion_message_for_peer ( charlie_id) . unwrap ( ) ;
1787
+ charlie. onion_messenger . handle_onion_message ( & alice_id, & onion_message) ;
1788
+
1789
+ let onion_message = charlie. onion_messenger . next_onion_message_for_peer ( david_id) . unwrap ( ) ;
1790
+ david. onion_messenger . handle_onion_message ( & charlie_id, & onion_message) ;
1791
+
1792
+ let ( invoice, _) = extract_invoice ( david, & onion_message) ;
1793
+ assert_eq ! ( invoice, expected_invoice) ;
1794
+
1795
+ assert_eq ! ( invoice. amount_msats( ) , 10_000_000 ) ;
1796
+ assert_ne ! ( invoice. signing_pubkey( ) , alice_id) ;
1797
+ assert ! ( !invoice. payment_paths( ) . is_empty( ) ) ;
1798
+ for ( _, path) in invoice. payment_paths ( ) {
1799
+ assert_eq ! ( path. introduction_node, IntroductionNode :: NodeId ( bob_id) ) ;
1800
+ // Verify that the blinded payment paths are properly padded.
1801
+ is_properly_padded ( path) ;
1802
+ }
1803
+
1804
+ route_bolt12_payment ( david, & [ charlie, bob, alice] , & invoice) ;
1805
+ expect_recent_payment ! ( david, RecentPaymentDetails :: Pending , payment_id) ;
1806
+
1807
+ claim_bolt12_payment ( david, & [ charlie, bob, alice] , payment_context) ;
1808
+ expect_recent_payment ! ( david, RecentPaymentDetails :: Fulfilled , payment_id) ;
1809
+ }
0 commit comments