@@ -5740,187 +5740,33 @@ mod tests {
57405740 }
57415741
57425742 #[ test]
5743- fn long_mpp_route_test ( ) {
5744- let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
5745- let ( our_privkey, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
5746- let scorer = ln_test_utils:: TestScorer :: new ( ) ;
5747- let random_seed_bytes = [ 42 ; 32 ] ;
5748- let config = UserConfig :: default ( ) ;
5749- let payment_params = PaymentParameters :: from_node_id ( nodes[ 3 ] , 42 )
5750- . with_bolt11_features ( channelmanager:: provided_bolt11_invoice_features ( & config) )
5751- . unwrap ( ) ;
5752-
5753- // We need a route consisting of 3 paths:
5754- // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5755- // Note that these paths overlap (channels 5, 12, 13).
5756- // We will route 300 sats.
5757- // Each path will have 100 sats capacity, those channels which
5758- // are used twice will have 200 sats capacity.
5759-
5760- // Disable other potential paths.
5761- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5762- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5763- short_channel_id : 2 ,
5764- timestamp : 2 ,
5765- message_flags : 1 , // Only must_be_one
5766- channel_flags : 2 ,
5767- cltv_expiry_delta : 0 ,
5768- htlc_minimum_msat : 0 ,
5769- htlc_maximum_msat : 100_000 ,
5770- fee_base_msat : 0 ,
5771- fee_proportional_millionths : 0 ,
5772- excess_data : Vec :: new ( )
5773- } ) ;
5774- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5775- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5776- short_channel_id : 7 ,
5777- timestamp : 2 ,
5778- message_flags : 1 , // Only must_be_one
5779- channel_flags : 2 ,
5780- cltv_expiry_delta : 0 ,
5781- htlc_minimum_msat : 0 ,
5782- htlc_maximum_msat : 100_000 ,
5783- fee_base_msat : 0 ,
5784- fee_proportional_millionths : 0 ,
5785- excess_data : Vec :: new ( )
5786- } ) ;
5787-
5788- // Path via {node0, node2} is channels {1, 3, 5}.
5789- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5790- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5791- short_channel_id : 1 ,
5792- timestamp : 2 ,
5793- message_flags : 1 , // Only must_be_one
5794- channel_flags : 0 ,
5795- cltv_expiry_delta : 0 ,
5796- htlc_minimum_msat : 0 ,
5797- htlc_maximum_msat : 100_000 ,
5798- fee_base_msat : 0 ,
5799- fee_proportional_millionths : 0 ,
5800- excess_data : Vec :: new ( )
5801- } ) ;
5802- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 0 ] , UnsignedChannelUpdate {
5803- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5804- short_channel_id : 3 ,
5805- timestamp : 2 ,
5806- message_flags : 1 , // Only must_be_one
5807- channel_flags : 0 ,
5808- cltv_expiry_delta : 0 ,
5809- htlc_minimum_msat : 0 ,
5810- htlc_maximum_msat : 100_000 ,
5811- fee_base_msat : 0 ,
5812- fee_proportional_millionths : 0 ,
5813- excess_data : Vec :: new ( )
5814- } ) ;
5815-
5816- // Capacity of 200 sats because this channel will be used by 3rd path as well.
5817- add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 5 ) ) , 5 ) ;
5818- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5819- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5820- short_channel_id : 5 ,
5821- timestamp : 2 ,
5822- message_flags : 1 , // Only must_be_one
5823- channel_flags : 0 ,
5824- cltv_expiry_delta : 0 ,
5825- htlc_minimum_msat : 0 ,
5826- htlc_maximum_msat : 200_000 ,
5827- fee_base_msat : 0 ,
5828- fee_proportional_millionths : 0 ,
5829- excess_data : Vec :: new ( )
5830- } ) ;
5831- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 3 ] , UnsignedChannelUpdate {
5832- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5833- short_channel_id : 5 ,
5834- timestamp : 2 ,
5835- message_flags : 1 , // Only must_be_one
5836- channel_flags : 3 , // disable direction 1
5837- cltv_expiry_delta : 0 ,
5838- htlc_minimum_msat : 0 ,
5839- htlc_maximum_msat : 200_000 ,
5840- fee_base_msat : 0 ,
5841- fee_proportional_millionths : 0 ,
5842- excess_data : Vec :: new ( )
5843- } ) ;
5844-
5845- // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
5846- // Add 100 sats to the capacities of {12, 13}, because these channels
5847- // are also used for 3rd path. 100 sats for the rest. Total capacity: 100 sats.
5848- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5849- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5850- short_channel_id : 12 ,
5851- timestamp : 2 ,
5852- message_flags : 1 , // Only must_be_one
5853- channel_flags : 0 ,
5854- cltv_expiry_delta : 0 ,
5855- htlc_minimum_msat : 0 ,
5856- htlc_maximum_msat : 200_000 ,
5857- fee_base_msat : 0 ,
5858- fee_proportional_millionths : 0 ,
5859- excess_data : Vec :: new ( )
5860- } ) ;
5861- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 7 ] , UnsignedChannelUpdate {
5862- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5863- short_channel_id : 13 ,
5864- timestamp : 2 ,
5865- message_flags : 1 , // Only must_be_one
5866- channel_flags : 0 ,
5867- cltv_expiry_delta : 0 ,
5868- htlc_minimum_msat : 0 ,
5869- htlc_maximum_msat : 200_000 ,
5870- fee_base_msat : 0 ,
5871- fee_proportional_millionths : 0 ,
5872- excess_data : Vec :: new ( )
5873- } ) ;
5874-
5875- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5876- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5877- short_channel_id : 6 ,
5878- timestamp : 2 ,
5879- message_flags : 1 , // Only must_be_one
5880- channel_flags : 0 ,
5881- cltv_expiry_delta : 0 ,
5882- htlc_minimum_msat : 0 ,
5883- htlc_maximum_msat : 100_000 ,
5884- fee_base_msat : 0 ,
5885- fee_proportional_millionths : 0 ,
5886- excess_data : Vec :: new ( )
5887- } ) ;
5888- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 4 ] , UnsignedChannelUpdate {
5889- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5890- short_channel_id : 11 ,
5891- timestamp : 2 ,
5892- message_flags : 1 , // Only must_be_one
5893- channel_flags : 0 ,
5894- cltv_expiry_delta : 0 ,
5895- htlc_minimum_msat : 0 ,
5896- htlc_maximum_msat : 100_000 ,
5897- fee_base_msat : 0 ,
5898- fee_proportional_millionths : 0 ,
5899- excess_data : Vec :: new ( )
5900- } ) ;
5901-
5902- // Path via {node7, node2} is channels {12, 13, 5}.
5903- // We already limited them to 200 sats (they are used twice for 100 sats).
5904- // Nothing to do here.
5905-
5743+ fn mpp_tests ( ) {
5744+ let secp_ctx = Secp256k1 :: new ( ) ;
5745+ let ( _, _, _, nodes) = get_nodes ( & secp_ctx) ;
59065746 {
5907- // Attempt to route more than available results in a failure.
5908- let route_params = RouteParameters :: from_payment_params_and_value (
5909- payment_params. clone ( ) , 350_000 ) ;
5910- if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route (
5911- & our_id, & route_params, & network_graph. read_only ( ) , None , Arc :: clone ( & logger) ,
5912- & scorer, & Default :: default ( ) , & random_seed_bytes) {
5913- assert_eq ! ( err, "Failed to find a sufficient route to the given destination" ) ;
5914- } else { panic ! ( ) ; }
5915- }
5747+ // Check that if we have two cheaper paths and a more expensive (fewer hops) path, we
5748+ // choose the two cheaper paths:
5749+ let route = do_mpp_route_tests ( 180_000 ) . unwrap ( ) ;
5750+ assert_eq ! ( route. paths. len( ) , 2 ) ;
59165751
5752+ let mut total_value_transferred_msat = 0 ;
5753+ let mut total_paid_msat = 0 ;
5754+ for path in & route. paths {
5755+ assert_eq ! ( path. hops. last( ) . unwrap( ) . pubkey, nodes[ 3 ] ) ;
5756+ total_value_transferred_msat += path. final_value_msat ( ) ;
5757+ for hop in & path. hops {
5758+ total_paid_msat += hop. fee_msat ;
5759+ }
5760+ }
5761+ // If we paid fee, this would be higher.
5762+ assert_eq ! ( total_value_transferred_msat, 180_000 ) ;
5763+ let total_fees_paid = total_paid_msat - total_value_transferred_msat;
5764+ assert_eq ! ( total_fees_paid, 0 ) ;
5765+ }
59175766 {
5918- // Now, attempt to route 300 sats (exact amount we can route).
5919- // Our algorithm should provide us with these 3 paths, 100 sats each.
5920- let route_params = RouteParameters :: from_payment_params_and_value (
5921- payment_params, 300_000 ) ;
5922- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
5923- Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
5767+ // Check that if we use the same channels but need to send more than we could fit in
5768+ // the cheaper paths we select all three paths:
5769+ let route = do_mpp_route_tests ( 300_000 ) . unwrap ( ) ;
59245770 assert_eq ! ( route. paths. len( ) , 3 ) ;
59255771
59265772 let mut total_amount_paid_msat = 0 ;
@@ -5930,11 +5776,11 @@ mod tests {
59305776 }
59315777 assert_eq ! ( total_amount_paid_msat, 300_000 ) ;
59325778 }
5933-
5779+ // Check that trying to pay more than our available liquidity fails.
5780+ assert ! ( do_mpp_route_tests( 300_001 ) . is_err( ) ) ;
59345781 }
59355782
5936- #[ test]
5937- fn mpp_cheaper_route_test ( ) {
5783+ fn do_mpp_route_tests ( amt : u64 ) -> Result < Route , LightningError > {
59385784 let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
59395785 let ( our_privkey, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
59405786 let scorer = ln_test_utils:: TestScorer :: new ( ) ;
@@ -5944,21 +5790,17 @@ mod tests {
59445790 . with_bolt11_features ( channelmanager:: provided_bolt11_invoice_features ( & config) )
59455791 . unwrap ( ) ;
59465792
5947- // This test checks that if we have two cheaper paths and one more expensive path,
5948- // so that liquidity-wise any 2 of 3 combination is sufficient,
5949- // two cheaper paths will be taken.
5950- // These paths have equal available liquidity.
5951-
5952- // We need a combination of 3 paths:
5953- // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5954- // Note that these paths overlap (channels 5, 12, 13).
5955- // Each path will have 100 sats capacity, those channels which
5956- // are used twice will have 200 sats capacity.
5793+ // Build a setup where we have three potential paths from us to node3:
5794+ // {node0, node2, node4} (channels 1, 3, 6, 11), fee 0 msat,
5795+ // {node7, node2, node4} (channels 12, 13, 6, 11), fee 0 msat, and
5796+ // {node1} (channel 2, then a new channel 16), fee 1000 msat.
5797+ // Note that these paths overlap on channels 6 and 11.
5798+ // Each channel will have 100 sats capacity except for 6 and 11, which have 200.
59575799
59585800 // Disable other potential paths.
5959- update_channel ( & gossip_sync, & secp_ctx, & our_privkey , UnsignedChannelUpdate {
5801+ update_channel ( & gossip_sync, & secp_ctx, & privkeys [ 2 ] , UnsignedChannelUpdate {
59605802 chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5961- short_channel_id : 2 ,
5803+ short_channel_id : 7 ,
59625804 timestamp : 2 ,
59635805 message_flags : 1 , // Only must_be_one
59645806 channel_flags : 2 ,
@@ -5969,9 +5811,9 @@ mod tests {
59695811 fee_proportional_millionths : 0 ,
59705812 excess_data : Vec :: new ( )
59715813 } ) ;
5972- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5814+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
59735815 chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5974- short_channel_id : 7 ,
5816+ short_channel_id : 4 ,
59755817 timestamp : 2 ,
59765818 message_flags : 1 , // Only must_be_one
59775819 channel_flags : 2 ,
@@ -6011,31 +5853,30 @@ mod tests {
60115853 excess_data : Vec :: new ( )
60125854 } ) ;
60135855
6014- // Capacity of 200 sats because this channel will be used by 3rd path as well.
6015- add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 5 ) ) , 5 ) ;
6016- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5856+ add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 16 ) ) , 16 ) ;
5857+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
60175858 chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6018- short_channel_id : 5 ,
5859+ short_channel_id : 16 ,
60195860 timestamp : 2 ,
60205861 message_flags : 1 , // Only must_be_one
60215862 channel_flags : 0 ,
60225863 cltv_expiry_delta : 0 ,
60235864 htlc_minimum_msat : 0 ,
6024- htlc_maximum_msat : 200_000 ,
6025- fee_base_msat : 0 ,
5865+ htlc_maximum_msat : 100_000 ,
5866+ fee_base_msat : 1_000 ,
60265867 fee_proportional_millionths : 0 ,
60275868 excess_data : Vec :: new ( )
60285869 } ) ;
60295870 update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 3 ] , UnsignedChannelUpdate {
60305871 chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6031- short_channel_id : 5 ,
5872+ short_channel_id : 16 ,
60325873 timestamp : 2 ,
60335874 message_flags : 1 , // Only must_be_one
60345875 channel_flags : 3 , // disable direction 1
60355876 cltv_expiry_delta : 0 ,
60365877 htlc_minimum_msat : 0 ,
6037- htlc_maximum_msat : 200_000 ,
6038- fee_base_msat : 0 ,
5878+ htlc_maximum_msat : 100_000 ,
5879+ fee_base_msat : 1_000 ,
60395880 fee_proportional_millionths : 0 ,
60405881 excess_data : Vec :: new ( )
60415882 } ) ;
@@ -6051,7 +5892,7 @@ mod tests {
60515892 channel_flags : 0 ,
60525893 cltv_expiry_delta : 0 ,
60535894 htlc_minimum_msat : 0 ,
6054- htlc_maximum_msat : 200_000 ,
5895+ htlc_maximum_msat : 100_000 ,
60555896 fee_base_msat : 0 ,
60565897 fee_proportional_millionths : 0 ,
60575898 excess_data : Vec :: new ( )
@@ -6064,7 +5905,7 @@ mod tests {
60645905 channel_flags : 0 ,
60655906 cltv_expiry_delta : 0 ,
60665907 htlc_minimum_msat : 0 ,
6067- htlc_maximum_msat : 200_000 ,
5908+ htlc_maximum_msat : 100_000 ,
60685909 fee_base_msat : 0 ,
60695910 fee_proportional_millionths : 0 ,
60705911 excess_data : Vec :: new ( )
@@ -6078,8 +5919,8 @@ mod tests {
60785919 channel_flags : 0 ,
60795920 cltv_expiry_delta : 0 ,
60805921 htlc_minimum_msat : 0 ,
6081- htlc_maximum_msat : 100_000 ,
6082- fee_base_msat : 1_000 ,
5922+ htlc_maximum_msat : 200_000 ,
5923+ fee_base_msat : 0 ,
60835924 fee_proportional_millionths : 0 ,
60845925 excess_data : Vec :: new ( )
60855926 } ) ;
@@ -6091,7 +5932,7 @@ mod tests {
60915932 channel_flags : 0 ,
60925933 cltv_expiry_delta : 0 ,
60935934 htlc_minimum_msat : 0 ,
6094- htlc_maximum_msat : 100_000 ,
5935+ htlc_maximum_msat : 200_000 ,
60955936 fee_base_msat : 0 ,
60965937 fee_proportional_millionths : 0 ,
60975938 excess_data : Vec :: new ( )
@@ -6101,29 +5942,11 @@ mod tests {
61015942 // We already limited them to 200 sats (they are used twice for 100 sats).
61025943 // Nothing to do here.
61035944
6104- {
6105- // Now, attempt to route 180 sats.
6106- // Our algorithm should provide us with these 2 paths.
6107- let route_params = RouteParameters :: from_payment_params_and_value (
6108- payment_params, 180_000 ) ;
6109- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
6110- Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
6111- assert_eq ! ( route. paths. len( ) , 2 ) ;
6112-
6113- let mut total_value_transferred_msat = 0 ;
6114- let mut total_paid_msat = 0 ;
6115- for path in & route. paths {
6116- assert_eq ! ( path. hops. last( ) . unwrap( ) . pubkey, nodes[ 3 ] ) ;
6117- total_value_transferred_msat += path. final_value_msat ( ) ;
6118- for hop in & path. hops {
6119- total_paid_msat += hop. fee_msat ;
6120- }
6121- }
6122- // If we paid fee, this would be higher.
6123- assert_eq ! ( total_value_transferred_msat, 180_000 ) ;
6124- let total_fees_paid = total_paid_msat - total_value_transferred_msat;
6125- assert_eq ! ( total_fees_paid, 0 ) ;
6126- }
5945+ let route_params = RouteParameters :: from_payment_params_and_value (
5946+ payment_params, amt) ;
5947+ let res = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
5948+ Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) ;
5949+ res
61275950 }
61285951
61295952 #[ test]
0 commit comments