@@ -5740,187 +5740,33 @@ mod tests {
5740
5740
}
5741
5741
5742
5742
#[ 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) ;
5906
5746
{
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 ) ;
5916
5751
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
+ }
5917
5766
{
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 ( ) ;
5924
5770
assert_eq ! ( route. paths. len( ) , 3 ) ;
5925
5771
5926
5772
let mut total_amount_paid_msat = 0 ;
@@ -5930,11 +5776,11 @@ mod tests {
5930
5776
}
5931
5777
assert_eq ! ( total_amount_paid_msat, 300_000 ) ;
5932
5778
}
5933
-
5779
+ // Check that trying to pay more than our available liquidity fails.
5780
+ assert ! ( do_mpp_route_tests( 300_001 ) . is_err( ) ) ;
5934
5781
}
5935
5782
5936
- #[ test]
5937
- fn mpp_cheaper_route_test ( ) {
5783
+ fn do_mpp_route_tests ( amt : u64 ) -> Result < Route , LightningError > {
5938
5784
let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
5939
5785
let ( our_privkey, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
5940
5786
let scorer = ln_test_utils:: TestScorer :: new ( ) ;
@@ -5944,21 +5790,17 @@ mod tests {
5944
5790
. with_bolt11_features ( channelmanager:: provided_bolt11_invoice_features ( & config) )
5945
5791
. unwrap ( ) ;
5946
5792
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.
5957
5799
5958
5800
// Disable other potential paths.
5959
- update_channel ( & gossip_sync, & secp_ctx, & our_privkey , UnsignedChannelUpdate {
5801
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys [ 2 ] , UnsignedChannelUpdate {
5960
5802
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5961
- short_channel_id : 2 ,
5803
+ short_channel_id : 7 ,
5962
5804
timestamp : 2 ,
5963
5805
message_flags : 1 , // Only must_be_one
5964
5806
channel_flags : 2 ,
@@ -5969,9 +5811,9 @@ mod tests {
5969
5811
fee_proportional_millionths : 0 ,
5970
5812
excess_data : Vec :: new ( )
5971
5813
} ) ;
5972
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5814
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
5973
5815
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5974
- short_channel_id : 7 ,
5816
+ short_channel_id : 4 ,
5975
5817
timestamp : 2 ,
5976
5818
message_flags : 1 , // Only must_be_one
5977
5819
channel_flags : 2 ,
@@ -6011,31 +5853,30 @@ mod tests {
6011
5853
excess_data : Vec :: new ( )
6012
5854
} ) ;
6013
5855
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 {
6017
5858
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6018
- short_channel_id : 5 ,
5859
+ short_channel_id : 16 ,
6019
5860
timestamp : 2 ,
6020
5861
message_flags : 1 , // Only must_be_one
6021
5862
channel_flags : 0 ,
6022
5863
cltv_expiry_delta : 0 ,
6023
5864
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 ,
6026
5867
fee_proportional_millionths : 0 ,
6027
5868
excess_data : Vec :: new ( )
6028
5869
} ) ;
6029
5870
update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 3 ] , UnsignedChannelUpdate {
6030
5871
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6031
- short_channel_id : 5 ,
5872
+ short_channel_id : 16 ,
6032
5873
timestamp : 2 ,
6033
5874
message_flags : 1 , // Only must_be_one
6034
5875
channel_flags : 3 , // disable direction 1
6035
5876
cltv_expiry_delta : 0 ,
6036
5877
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 ,
6039
5880
fee_proportional_millionths : 0 ,
6040
5881
excess_data : Vec :: new ( )
6041
5882
} ) ;
@@ -6051,7 +5892,7 @@ mod tests {
6051
5892
channel_flags : 0 ,
6052
5893
cltv_expiry_delta : 0 ,
6053
5894
htlc_minimum_msat : 0 ,
6054
- htlc_maximum_msat : 200_000 ,
5895
+ htlc_maximum_msat : 100_000 ,
6055
5896
fee_base_msat : 0 ,
6056
5897
fee_proportional_millionths : 0 ,
6057
5898
excess_data : Vec :: new ( )
@@ -6064,7 +5905,7 @@ mod tests {
6064
5905
channel_flags : 0 ,
6065
5906
cltv_expiry_delta : 0 ,
6066
5907
htlc_minimum_msat : 0 ,
6067
- htlc_maximum_msat : 200_000 ,
5908
+ htlc_maximum_msat : 100_000 ,
6068
5909
fee_base_msat : 0 ,
6069
5910
fee_proportional_millionths : 0 ,
6070
5911
excess_data : Vec :: new ( )
@@ -6078,8 +5919,8 @@ mod tests {
6078
5919
channel_flags : 0 ,
6079
5920
cltv_expiry_delta : 0 ,
6080
5921
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 ,
6083
5924
fee_proportional_millionths : 0 ,
6084
5925
excess_data : Vec :: new ( )
6085
5926
} ) ;
@@ -6091,7 +5932,7 @@ mod tests {
6091
5932
channel_flags : 0 ,
6092
5933
cltv_expiry_delta : 0 ,
6093
5934
htlc_minimum_msat : 0 ,
6094
- htlc_maximum_msat : 100_000 ,
5935
+ htlc_maximum_msat : 200_000 ,
6095
5936
fee_base_msat : 0 ,
6096
5937
fee_proportional_millionths : 0 ,
6097
5938
excess_data : Vec :: new ( )
@@ -6101,29 +5942,11 @@ mod tests {
6101
5942
// We already limited them to 200 sats (they are used twice for 100 sats).
6102
5943
// Nothing to do here.
6103
5944
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
6127
5950
}
6128
5951
6129
5952
#[ test]
0 commit comments