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