@@ -1732,6 +1732,133 @@ fn do_test_intercepted_payment(test: InterceptTest) {
1732
1732
}
1733
1733
}
1734
1734
1735
+ #[ test]
1736
+ fn accept_underpaying_htlcs_config ( ) {
1737
+ do_accept_underpaying_htlcs_config ( 1 ) ;
1738
+ do_accept_underpaying_htlcs_config ( 2 ) ;
1739
+ do_accept_underpaying_htlcs_config ( 3 ) ;
1740
+ }
1741
+
1742
+ fn do_accept_underpaying_htlcs_config ( num_mpp_parts : usize ) {
1743
+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
1744
+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
1745
+ let mut intercept_forwards_config = test_default_channel_config ( ) ;
1746
+ intercept_forwards_config. accept_intercept_htlcs = true ;
1747
+ let mut underpay_config = test_default_channel_config ( ) ;
1748
+ underpay_config. channel_config . accept_underpaying_htlcs = true ;
1749
+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , Some ( intercept_forwards_config) , Some ( underpay_config) ] ) ;
1750
+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
1751
+
1752
+ let mut chan_ids = Vec :: new ( ) ;
1753
+ for _ in 0 ..num_mpp_parts {
1754
+ let _ = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000 , 0 ) ;
1755
+ let channel_id = create_unannounced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 2_000_000 , 0 ) . 0 . channel_id ;
1756
+ chan_ids. push ( channel_id) ;
1757
+ }
1758
+
1759
+ // Send the initial payment.
1760
+ let amt_msat = 900_000 ;
1761
+ let skimmed_fee_msat = 20 ;
1762
+ let mut route_hints = Vec :: new ( ) ;
1763
+ for _ in 0 ..num_mpp_parts {
1764
+ route_hints. push ( RouteHint ( vec ! [ RouteHintHop {
1765
+ src_node_id: nodes[ 1 ] . node. get_our_node_id( ) ,
1766
+ short_channel_id: nodes[ 1 ] . node. get_intercept_scid( ) ,
1767
+ fees: RoutingFees {
1768
+ base_msat: 1000 ,
1769
+ proportional_millionths: 0 ,
1770
+ } ,
1771
+ cltv_expiry_delta: MIN_CLTV_EXPIRY_DELTA ,
1772
+ htlc_minimum_msat: None ,
1773
+ htlc_maximum_msat: Some ( amt_msat / num_mpp_parts as u64 + 5 ) ,
1774
+ } ] ) ) ;
1775
+ }
1776
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 2 ] . node . get_our_node_id ( ) , TEST_FINAL_CLTV )
1777
+ . with_route_hints ( route_hints) . unwrap ( )
1778
+ . with_bolt11_features ( nodes[ 2 ] . node . invoice_features ( ) ) . unwrap ( ) ;
1779
+ let route_params = RouteParameters {
1780
+ payment_params,
1781
+ final_value_msat : amt_msat,
1782
+ } ;
1783
+ let ( payment_hash, payment_secret) = nodes[ 2 ] . node . create_inbound_payment ( Some ( amt_msat) , 60 * 60 , None ) . unwrap ( ) ;
1784
+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: secret_only ( payment_secret) ,
1785
+ PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
1786
+ check_added_monitors ! ( nodes[ 0 ] , num_mpp_parts) ; // one monitor per path
1787
+ let mut events: Vec < SendEvent > = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) . into_iter ( ) . map ( |e| SendEvent :: from_event ( e) ) . collect ( ) ;
1788
+ assert_eq ! ( events. len( ) , num_mpp_parts) ;
1789
+
1790
+ // Forward the intercepted payments.
1791
+ for ( idx, ev) in events. into_iter ( ) . enumerate ( ) {
1792
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & ev. msgs [ 0 ] ) ;
1793
+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 0 ] , & ev. commitment_msg , false , true ) ;
1794
+
1795
+ let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
1796
+ assert_eq ! ( events. len( ) , 1 ) ;
1797
+ let ( intercept_id, expected_outbound_amt_msat) = match events[ 0 ] {
1798
+ crate :: events:: Event :: HTLCIntercepted {
1799
+ intercept_id, expected_outbound_amount_msat, payment_hash : pmt_hash, ..
1800
+ } => {
1801
+ assert_eq ! ( pmt_hash, payment_hash) ;
1802
+ ( intercept_id, expected_outbound_amount_msat)
1803
+ } ,
1804
+ _ => panic ! ( )
1805
+ } ;
1806
+ nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & chan_ids[ idx] ,
1807
+ nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amt_msat - skimmed_fee_msat) . unwrap ( ) ;
1808
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
1809
+ let payment_event = {
1810
+ {
1811
+ let mut added_monitors = nodes[ 1 ] . chain_monitor . added_monitors . lock ( ) . unwrap ( ) ;
1812
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
1813
+ added_monitors. clear ( ) ;
1814
+ }
1815
+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
1816
+ assert_eq ! ( events. len( ) , 1 ) ;
1817
+ SendEvent :: from_event ( events. remove ( 0 ) )
1818
+ } ;
1819
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
1820
+ do_commitment_signed_dance ( & nodes[ 2 ] , & nodes[ 1 ] , & payment_event. commitment_msg , false , true ) ;
1821
+ if idx == num_mpp_parts - 1 {
1822
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
1823
+ }
1824
+ }
1825
+
1826
+ // Claim the payment and check that the skimmed fee is as expected.
1827
+ let payment_preimage = nodes[ 2 ] . node . get_payment_preimage ( payment_hash, payment_secret) . unwrap ( ) ;
1828
+ let events = nodes[ 2 ] . node . get_and_clear_pending_events ( ) ;
1829
+ assert_eq ! ( events. len( ) , 1 ) ;
1830
+ match events[ 0 ] {
1831
+ crate :: events:: Event :: PaymentClaimable {
1832
+ ref payment_hash, ref purpose, amount_msat, counterparty_skimmed_fee_msat, receiver_node_id, ..
1833
+ } => {
1834
+ assert_eq ! ( payment_hash, payment_hash) ;
1835
+ assert_eq ! ( amt_msat - skimmed_fee_msat * num_mpp_parts as u64 , amount_msat) ;
1836
+ assert_eq ! ( skimmed_fee_msat * num_mpp_parts as u64 , counterparty_skimmed_fee_msat) ;
1837
+ assert_eq ! ( nodes[ 2 ] . node. get_our_node_id( ) , receiver_node_id. unwrap( ) ) ;
1838
+ match purpose {
1839
+ crate :: events:: PaymentPurpose :: InvoicePayment { payment_preimage : ev_payment_preimage,
1840
+ payment_secret : ev_payment_secret, .. } =>
1841
+ {
1842
+ assert_eq ! ( payment_preimage, ev_payment_preimage. unwrap( ) ) ;
1843
+ assert_eq ! ( payment_secret, * ev_payment_secret) ;
1844
+ } ,
1845
+ _ => panic ! ( ) ,
1846
+ }
1847
+ } ,
1848
+ _ => panic ! ( "Unexpected event" ) ,
1849
+ }
1850
+ let mut expected_paths_vecs = Vec :: new ( ) ;
1851
+ let mut expected_paths = Vec :: new ( ) ;
1852
+ for _ in 0 ..num_mpp_parts { expected_paths_vecs. push ( vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) ) ; }
1853
+ for i in 0 ..num_mpp_parts { expected_paths. push ( & expected_paths_vecs[ i] [ ..] ) ; }
1854
+ let total_fee_msat = do_claim_payment_along_route_with_extra_penultimate_hop_fees (
1855
+ & nodes[ 0 ] , & expected_paths[ ..] , & vec ! [ skimmed_fee_msat as u32 ; num_mpp_parts] [ ..] , false ,
1856
+ payment_preimage) ;
1857
+ // The sender doesn't know that the penultimate hop took an extra fee.
1858
+ expect_payment_sent ( & nodes[ 0 ] , payment_preimage,
1859
+ Some ( Some ( total_fee_msat - skimmed_fee_msat * num_mpp_parts as u64 ) ) , true ) ;
1860
+ }
1861
+
1735
1862
#[ derive( PartialEq ) ]
1736
1863
enum AutoRetry {
1737
1864
Success ,
0 commit comments