@@ -5774,187 +5774,33 @@ mod tests {
5774
5774
}
5775
5775
5776
5776
#[ test]
5777
- fn long_mpp_route_test ( ) {
5778
- let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
5779
- let ( our_privkey, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
5780
- let scorer = ln_test_utils:: TestScorer :: new ( ) ;
5781
- let random_seed_bytes = [ 42 ; 32 ] ;
5782
- let config = UserConfig :: default ( ) ;
5783
- let payment_params = PaymentParameters :: from_node_id ( nodes[ 3 ] , 42 )
5784
- . with_bolt11_features ( channelmanager:: provided_bolt11_invoice_features ( & config) )
5785
- . unwrap ( ) ;
5786
-
5787
- // We need a route consisting of 3 paths:
5788
- // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5789
- // Note that these paths overlap (channels 5, 12, 13).
5790
- // We will route 300 sats.
5791
- // Each path will have 100 sats capacity, those channels which
5792
- // are used twice will have 200 sats capacity.
5793
-
5794
- // Disable other potential paths.
5795
- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5796
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5797
- short_channel_id : 2 ,
5798
- timestamp : 2 ,
5799
- message_flags : 1 , // Only must_be_one
5800
- channel_flags : 2 ,
5801
- cltv_expiry_delta : 0 ,
5802
- htlc_minimum_msat : 0 ,
5803
- htlc_maximum_msat : 100_000 ,
5804
- fee_base_msat : 0 ,
5805
- fee_proportional_millionths : 0 ,
5806
- excess_data : Vec :: new ( )
5807
- } ) ;
5808
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5809
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5810
- short_channel_id : 7 ,
5811
- timestamp : 2 ,
5812
- message_flags : 1 , // Only must_be_one
5813
- channel_flags : 2 ,
5814
- cltv_expiry_delta : 0 ,
5815
- htlc_minimum_msat : 0 ,
5816
- htlc_maximum_msat : 100_000 ,
5817
- fee_base_msat : 0 ,
5818
- fee_proportional_millionths : 0 ,
5819
- excess_data : Vec :: new ( )
5820
- } ) ;
5821
-
5822
- // Path via {node0, node2} is channels {1, 3, 5}.
5823
- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5824
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5825
- short_channel_id : 1 ,
5826
- timestamp : 2 ,
5827
- message_flags : 1 , // Only must_be_one
5828
- channel_flags : 0 ,
5829
- cltv_expiry_delta : 0 ,
5830
- htlc_minimum_msat : 0 ,
5831
- htlc_maximum_msat : 100_000 ,
5832
- fee_base_msat : 0 ,
5833
- fee_proportional_millionths : 0 ,
5834
- excess_data : Vec :: new ( )
5835
- } ) ;
5836
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 0 ] , UnsignedChannelUpdate {
5837
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5838
- short_channel_id : 3 ,
5839
- timestamp : 2 ,
5840
- message_flags : 1 , // Only must_be_one
5841
- channel_flags : 0 ,
5842
- cltv_expiry_delta : 0 ,
5843
- htlc_minimum_msat : 0 ,
5844
- htlc_maximum_msat : 100_000 ,
5845
- fee_base_msat : 0 ,
5846
- fee_proportional_millionths : 0 ,
5847
- excess_data : Vec :: new ( )
5848
- } ) ;
5849
-
5850
- // Capacity of 200 sats because this channel will be used by 3rd path as well.
5851
- add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 5 ) ) , 5 ) ;
5852
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5853
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5854
- short_channel_id : 5 ,
5855
- timestamp : 2 ,
5856
- message_flags : 1 , // Only must_be_one
5857
- channel_flags : 0 ,
5858
- cltv_expiry_delta : 0 ,
5859
- htlc_minimum_msat : 0 ,
5860
- htlc_maximum_msat : 200_000 ,
5861
- fee_base_msat : 0 ,
5862
- fee_proportional_millionths : 0 ,
5863
- excess_data : Vec :: new ( )
5864
- } ) ;
5865
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 3 ] , UnsignedChannelUpdate {
5866
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5867
- short_channel_id : 5 ,
5868
- timestamp : 2 ,
5869
- message_flags : 1 , // Only must_be_one
5870
- channel_flags : 3 , // disable direction 1
5871
- cltv_expiry_delta : 0 ,
5872
- htlc_minimum_msat : 0 ,
5873
- htlc_maximum_msat : 200_000 ,
5874
- fee_base_msat : 0 ,
5875
- fee_proportional_millionths : 0 ,
5876
- excess_data : Vec :: new ( )
5877
- } ) ;
5878
-
5879
- // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
5880
- // Add 100 sats to the capacities of {12, 13}, because these channels
5881
- // are also used for 3rd path. 100 sats for the rest. Total capacity: 100 sats.
5882
- update_channel ( & gossip_sync, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
5883
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5884
- short_channel_id : 12 ,
5885
- timestamp : 2 ,
5886
- message_flags : 1 , // Only must_be_one
5887
- channel_flags : 0 ,
5888
- cltv_expiry_delta : 0 ,
5889
- htlc_minimum_msat : 0 ,
5890
- htlc_maximum_msat : 200_000 ,
5891
- fee_base_msat : 0 ,
5892
- fee_proportional_millionths : 0 ,
5893
- excess_data : Vec :: new ( )
5894
- } ) ;
5895
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 7 ] , UnsignedChannelUpdate {
5896
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5897
- short_channel_id : 13 ,
5898
- timestamp : 2 ,
5899
- message_flags : 1 , // Only must_be_one
5900
- channel_flags : 0 ,
5901
- cltv_expiry_delta : 0 ,
5902
- htlc_minimum_msat : 0 ,
5903
- htlc_maximum_msat : 200_000 ,
5904
- fee_base_msat : 0 ,
5905
- fee_proportional_millionths : 0 ,
5906
- excess_data : Vec :: new ( )
5907
- } ) ;
5908
-
5909
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5910
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5911
- short_channel_id : 6 ,
5912
- timestamp : 2 ,
5913
- message_flags : 1 , // Only must_be_one
5914
- channel_flags : 0 ,
5915
- cltv_expiry_delta : 0 ,
5916
- htlc_minimum_msat : 0 ,
5917
- htlc_maximum_msat : 100_000 ,
5918
- fee_base_msat : 0 ,
5919
- fee_proportional_millionths : 0 ,
5920
- excess_data : Vec :: new ( )
5921
- } ) ;
5922
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 4 ] , UnsignedChannelUpdate {
5923
- chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5924
- short_channel_id : 11 ,
5925
- timestamp : 2 ,
5926
- message_flags : 1 , // Only must_be_one
5927
- channel_flags : 0 ,
5928
- cltv_expiry_delta : 0 ,
5929
- htlc_minimum_msat : 0 ,
5930
- htlc_maximum_msat : 100_000 ,
5931
- fee_base_msat : 0 ,
5932
- fee_proportional_millionths : 0 ,
5933
- excess_data : Vec :: new ( )
5934
- } ) ;
5935
-
5936
- // Path via {node7, node2} is channels {12, 13, 5}.
5937
- // We already limited them to 200 sats (they are used twice for 100 sats).
5938
- // Nothing to do here.
5939
-
5777
+ fn mpp_tests ( ) {
5778
+ let secp_ctx = Secp256k1 :: new ( ) ;
5779
+ let ( _, _, _, nodes) = get_nodes ( & secp_ctx) ;
5940
5780
{
5941
- // Attempt to route more than available results in a failure.
5942
- let route_params = RouteParameters :: from_payment_params_and_value (
5943
- payment_params. clone ( ) , 350_000 ) ;
5944
- if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route (
5945
- & our_id, & route_params, & network_graph. read_only ( ) , None , Arc :: clone ( & logger) ,
5946
- & scorer, & Default :: default ( ) , & random_seed_bytes) {
5947
- assert_eq ! ( err, "Failed to find a sufficient route to the given destination" ) ;
5948
- } else { panic ! ( ) ; }
5949
- }
5781
+ // Check that if we have two cheaper paths and a more expensive (fewer hops) path, we
5782
+ // choose the two cheaper paths:
5783
+ let route = do_mpp_route_tests ( 180_000 ) . unwrap ( ) ;
5784
+ assert_eq ! ( route. paths. len( ) , 2 ) ;
5950
5785
5786
+ let mut total_value_transferred_msat = 0 ;
5787
+ let mut total_paid_msat = 0 ;
5788
+ for path in & route. paths {
5789
+ assert_eq ! ( path. hops. last( ) . unwrap( ) . pubkey, nodes[ 3 ] ) ;
5790
+ total_value_transferred_msat += path. final_value_msat ( ) ;
5791
+ for hop in & path. hops {
5792
+ total_paid_msat += hop. fee_msat ;
5793
+ }
5794
+ }
5795
+ // If we paid fee, this would be higher.
5796
+ assert_eq ! ( total_value_transferred_msat, 180_000 ) ;
5797
+ let total_fees_paid = total_paid_msat - total_value_transferred_msat;
5798
+ assert_eq ! ( total_fees_paid, 0 ) ;
5799
+ }
5951
5800
{
5952
- // Now, attempt to route 300 sats (exact amount we can route).
5953
- // Our algorithm should provide us with these 3 paths, 100 sats each.
5954
- let route_params = RouteParameters :: from_payment_params_and_value (
5955
- payment_params, 300_000 ) ;
5956
- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
5957
- Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
5801
+ // Check that if we use the same channels but need to send more than we could fit in
5802
+ // the cheaper paths we select all three paths:
5803
+ let route = do_mpp_route_tests ( 300_000 ) . unwrap ( ) ;
5958
5804
assert_eq ! ( route. paths. len( ) , 3 ) ;
5959
5805
5960
5806
let mut total_amount_paid_msat = 0 ;
@@ -5964,11 +5810,11 @@ mod tests {
5964
5810
}
5965
5811
assert_eq ! ( total_amount_paid_msat, 300_000 ) ;
5966
5812
}
5967
-
5813
+ // Check that trying to pay more than our available liquidity fails.
5814
+ assert ! ( do_mpp_route_tests( 300_001 ) . is_err( ) ) ;
5968
5815
}
5969
5816
5970
- #[ test]
5971
- fn mpp_cheaper_route_test ( ) {
5817
+ fn do_mpp_route_tests ( amt : u64 ) -> Result < Route , LightningError > {
5972
5818
let ( secp_ctx, network_graph, gossip_sync, _, logger) = build_graph ( ) ;
5973
5819
let ( our_privkey, our_id, privkeys, nodes) = get_nodes ( & secp_ctx) ;
5974
5820
let scorer = ln_test_utils:: TestScorer :: new ( ) ;
@@ -5978,21 +5824,17 @@ mod tests {
5978
5824
. with_bolt11_features ( channelmanager:: provided_bolt11_invoice_features ( & config) )
5979
5825
. unwrap ( ) ;
5980
5826
5981
- // This test checks that if we have two cheaper paths and one more expensive path,
5982
- // so that liquidity-wise any 2 of 3 combination is sufficient,
5983
- // two cheaper paths will be taken.
5984
- // These paths have equal available liquidity.
5985
-
5986
- // We need a combination of 3 paths:
5987
- // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}.
5988
- // Note that these paths overlap (channels 5, 12, 13).
5989
- // Each path will have 100 sats capacity, those channels which
5990
- // are used twice will have 200 sats capacity.
5827
+ // Build a setup where we have three potential paths from us to node3:
5828
+ // {node0, node2, node4} (channels 1, 3, 6, 11), fee 0 msat,
5829
+ // {node7, node2, node4} (channels 12, 13, 6, 11), fee 0 msat, and
5830
+ // {node1} (channel 2, then a new channel 16), fee 1000 msat.
5831
+ // Note that these paths overlap on channels 6 and 11.
5832
+ // Each channel will have 100 sats capacity except for 6 and 11, which have 200.
5991
5833
5992
5834
// Disable other potential paths.
5993
- update_channel ( & gossip_sync, & secp_ctx, & our_privkey , UnsignedChannelUpdate {
5835
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys [ 2 ] , UnsignedChannelUpdate {
5994
5836
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
5995
- short_channel_id : 2 ,
5837
+ short_channel_id : 7 ,
5996
5838
timestamp : 2 ,
5997
5839
message_flags : 1 , // Only must_be_one
5998
5840
channel_flags : 2 ,
@@ -6003,9 +5845,9 @@ mod tests {
6003
5845
fee_proportional_millionths : 0 ,
6004
5846
excess_data : Vec :: new ( )
6005
5847
} ) ;
6006
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5848
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
6007
5849
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6008
- short_channel_id : 7 ,
5850
+ short_channel_id : 4 ,
6009
5851
timestamp : 2 ,
6010
5852
message_flags : 1 , // Only must_be_one
6011
5853
channel_flags : 2 ,
@@ -6045,31 +5887,30 @@ mod tests {
6045
5887
excess_data : Vec :: new ( )
6046
5888
} ) ;
6047
5889
6048
- // Capacity of 200 sats because this channel will be used by 3rd path as well.
6049
- add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 5 ) ) , 5 ) ;
6050
- update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 2 ] , UnsignedChannelUpdate {
5890
+ add_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , & privkeys[ 3 ] , ChannelFeatures :: from_le_bytes ( id_to_feature_flags ( 16 ) ) , 16 ) ;
5891
+ update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 1 ] , UnsignedChannelUpdate {
6051
5892
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6052
- short_channel_id : 5 ,
5893
+ short_channel_id : 16 ,
6053
5894
timestamp : 2 ,
6054
5895
message_flags : 1 , // Only must_be_one
6055
5896
channel_flags : 0 ,
6056
5897
cltv_expiry_delta : 0 ,
6057
5898
htlc_minimum_msat : 0 ,
6058
- htlc_maximum_msat : 200_000 ,
6059
- fee_base_msat : 0 ,
5899
+ htlc_maximum_msat : 100_000 ,
5900
+ fee_base_msat : 1_000 ,
6060
5901
fee_proportional_millionths : 0 ,
6061
5902
excess_data : Vec :: new ( )
6062
5903
} ) ;
6063
5904
update_channel ( & gossip_sync, & secp_ctx, & privkeys[ 3 ] , UnsignedChannelUpdate {
6064
5905
chain_hash : ChainHash :: using_genesis_block ( Network :: Testnet ) ,
6065
- short_channel_id : 5 ,
5906
+ short_channel_id : 16 ,
6066
5907
timestamp : 2 ,
6067
5908
message_flags : 1 , // Only must_be_one
6068
5909
channel_flags : 3 , // disable direction 1
6069
5910
cltv_expiry_delta : 0 ,
6070
5911
htlc_minimum_msat : 0 ,
6071
- htlc_maximum_msat : 200_000 ,
6072
- fee_base_msat : 0 ,
5912
+ htlc_maximum_msat : 100_000 ,
5913
+ fee_base_msat : 1_000 ,
6073
5914
fee_proportional_millionths : 0 ,
6074
5915
excess_data : Vec :: new ( )
6075
5916
} ) ;
@@ -6085,7 +5926,7 @@ mod tests {
6085
5926
channel_flags : 0 ,
6086
5927
cltv_expiry_delta : 0 ,
6087
5928
htlc_minimum_msat : 0 ,
6088
- htlc_maximum_msat : 200_000 ,
5929
+ htlc_maximum_msat : 100_000 ,
6089
5930
fee_base_msat : 0 ,
6090
5931
fee_proportional_millionths : 0 ,
6091
5932
excess_data : Vec :: new ( )
@@ -6098,7 +5939,7 @@ mod tests {
6098
5939
channel_flags : 0 ,
6099
5940
cltv_expiry_delta : 0 ,
6100
5941
htlc_minimum_msat : 0 ,
6101
- htlc_maximum_msat : 200_000 ,
5942
+ htlc_maximum_msat : 100_000 ,
6102
5943
fee_base_msat : 0 ,
6103
5944
fee_proportional_millionths : 0 ,
6104
5945
excess_data : Vec :: new ( )
@@ -6112,8 +5953,8 @@ mod tests {
6112
5953
channel_flags : 0 ,
6113
5954
cltv_expiry_delta : 0 ,
6114
5955
htlc_minimum_msat : 0 ,
6115
- htlc_maximum_msat : 100_000 ,
6116
- fee_base_msat : 1_000 ,
5956
+ htlc_maximum_msat : 200_000 ,
5957
+ fee_base_msat : 0 ,
6117
5958
fee_proportional_millionths : 0 ,
6118
5959
excess_data : Vec :: new ( )
6119
5960
} ) ;
@@ -6125,7 +5966,7 @@ mod tests {
6125
5966
channel_flags : 0 ,
6126
5967
cltv_expiry_delta : 0 ,
6127
5968
htlc_minimum_msat : 0 ,
6128
- htlc_maximum_msat : 100_000 ,
5969
+ htlc_maximum_msat : 200_000 ,
6129
5970
fee_base_msat : 0 ,
6130
5971
fee_proportional_millionths : 0 ,
6131
5972
excess_data : Vec :: new ( )
@@ -6135,29 +5976,11 @@ mod tests {
6135
5976
// We already limited them to 200 sats (they are used twice for 100 sats).
6136
5977
// Nothing to do here.
6137
5978
6138
- {
6139
- // Now, attempt to route 180 sats.
6140
- // Our algorithm should provide us with these 2 paths.
6141
- let route_params = RouteParameters :: from_payment_params_and_value (
6142
- payment_params, 180_000 ) ;
6143
- let route = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
6144
- Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) . unwrap ( ) ;
6145
- assert_eq ! ( route. paths. len( ) , 2 ) ;
6146
-
6147
- let mut total_value_transferred_msat = 0 ;
6148
- let mut total_paid_msat = 0 ;
6149
- for path in & route. paths {
6150
- assert_eq ! ( path. hops. last( ) . unwrap( ) . pubkey, nodes[ 3 ] ) ;
6151
- total_value_transferred_msat += path. final_value_msat ( ) ;
6152
- for hop in & path. hops {
6153
- total_paid_msat += hop. fee_msat ;
6154
- }
6155
- }
6156
- // If we paid fee, this would be higher.
6157
- assert_eq ! ( total_value_transferred_msat, 180_000 ) ;
6158
- let total_fees_paid = total_paid_msat - total_value_transferred_msat;
6159
- assert_eq ! ( total_fees_paid, 0 ) ;
6160
- }
5979
+ let route_params = RouteParameters :: from_payment_params_and_value (
5980
+ payment_params, amt) ;
5981
+ let res = get_route ( & our_id, & route_params, & network_graph. read_only ( ) , None ,
5982
+ Arc :: clone ( & logger) , & scorer, & Default :: default ( ) , & random_seed_bytes) ;
5983
+ res
6161
5984
}
6162
5985
6163
5986
#[ test]
0 commit comments