@@ -5810,7 +5810,7 @@ mod tests {
58105810 let mut scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & graph, & logger) ;
58115811 let features = super :: InvoiceFeatures :: empty ( ) ;
58125812
5813- super :: bench_utils:: generate_test_routes ( & graph, & mut scorer, & params, features, random_init_seed ( ) as usize , 2 ) ;
5813+ super :: bench_utils:: generate_test_routes ( & graph, & mut scorer, & params, features, random_init_seed ( ) , 0 , 2 ) ;
58145814 }
58155815
58165816 #[ test]
@@ -5831,7 +5831,28 @@ mod tests {
58315831 let mut scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & graph, & logger) ;
58325832 let features = channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) ;
58335833
5834- super :: bench_utils:: generate_test_routes ( & graph, & mut scorer, & params, features, random_init_seed ( ) as usize , 2 ) ;
5834+ super :: bench_utils:: generate_test_routes ( & graph, & mut scorer, & params, features, random_init_seed ( ) , 0 , 2 ) ;
5835+ }
5836+
5837+ #[ test]
5838+ #[ cfg( not( feature = "no-std" ) ) ]
5839+ fn generate_large_mpp_routes ( ) {
5840+ use crate :: routing:: scoring:: { ProbabilisticScorer , ProbabilisticScoringFeeParameters } ;
5841+
5842+ let logger = ln_test_utils:: TestLogger :: new ( ) ;
5843+ let graph = match super :: bench_utils:: read_network_graph ( & logger) {
5844+ Ok ( f) => f,
5845+ Err ( e) => {
5846+ eprintln ! ( "{}" , e) ;
5847+ return ;
5848+ } ,
5849+ } ;
5850+
5851+ let params = ProbabilisticScoringFeeParameters :: default ( ) ;
5852+ let mut scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & graph, & logger) ;
5853+ let features = channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) ;
5854+
5855+ super :: bench_utils:: generate_test_routes ( & graph, & mut scorer, & params, features, random_init_seed ( ) , 1_000_000 , 2 ) ;
58355856 }
58365857
58375858 #[ test]
@@ -6085,11 +6106,11 @@ pub(crate) mod bench_utils {
60856106 short_channel_id : Some ( 1 ) ,
60866107 inbound_scid_alias : None ,
60876108 outbound_scid_alias : None ,
6088- channel_value_satoshis : 10_000_000 ,
6109+ channel_value_satoshis : 10_000_000_000 ,
60896110 user_channel_id : 0 ,
6090- balance_msat : 10_000_000 ,
6091- outbound_capacity_msat : 10_000_000 ,
6092- next_outbound_htlc_limit_msat : 10_000_000 ,
6111+ balance_msat : 10_000_000_000 ,
6112+ outbound_capacity_msat : 10_000_000_000 ,
6113+ next_outbound_htlc_limit_msat : 10_000_000_000 ,
60936114 inbound_capacity_msat : 0 ,
60946115 unspendable_punishment_reserve : None ,
60956116 confirmations_required : None ,
@@ -6107,46 +6128,65 @@ pub(crate) mod bench_utils {
61076128 }
61086129
61096130 pub ( crate ) fn generate_test_routes < S : Score > ( graph : & NetworkGraph < & TestLogger > , scorer : & mut S ,
6110- score_params : & S :: ScoreParams , features : InvoiceFeatures , mut seed : usize , route_count : usize ,
6131+ score_params : & S :: ScoreParams , features : InvoiceFeatures , mut seed : u64 ,
6132+ starting_amount : u64 , route_count : usize ,
61116133 ) -> Vec < ( ChannelDetails , PaymentParameters , u64 ) > {
61126134 let payer = payer_pubkey ( ) ;
61136135 let keys_manager = KeysManager :: new ( & [ 0u8 ; 32 ] , 42 , 42 ) ;
61146136 let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
61156137
61166138 let nodes = graph. read_only ( ) . nodes ( ) . clone ( ) ;
61176139 let mut route_endpoints = Vec :: new ( ) ;
6118- let mut routes = Vec :: new ( ) ;
6119-
6120- ' load_endpoints : for _ in 0 ..route_count * 3 /2 {
6140+ // Fetch 1.5x more routes than we need as after we do some scorer updates we may end up
6141+ // with some routes we picked being un-routable.
6142+ for _ in 0 ..route_count * 3 / 2 {
61216143 loop {
6122- seed = seed. overflowing_mul ( 0xdeadbeef ) . 0 ;
6123- let src = PublicKey :: from_slice ( nodes. unordered_keys ( ) . skip ( seed % nodes. len ( ) ) . next ( ) . unwrap ( ) . as_slice ( ) ) . unwrap ( ) ;
6124- seed = seed. overflowing_mul ( 0xdeadbeef ) . 0 ;
6125- let dst = PublicKey :: from_slice ( nodes. unordered_keys ( ) . skip ( seed % nodes. len ( ) ) . next ( ) . unwrap ( ) . as_slice ( ) ) . unwrap ( ) ;
6126- let params = PaymentParameters :: from_node_id ( dst, 42 ) . with_bolt11_features ( features. clone ( ) ) . unwrap ( ) ;
6144+ seed = seed. overflowing_mul ( 6364136223846793005 ) . 0 . overflowing_add ( 1 ) . 0 ;
6145+ let src = PublicKey :: from_slice ( nodes. unordered_keys ( )
6146+ . skip ( ( seed as usize ) % nodes. len ( ) ) . next ( ) . unwrap ( ) . as_slice ( ) ) . unwrap ( ) ;
6147+ seed = seed. overflowing_mul ( 6364136223846793005 ) . 0 . overflowing_add ( 1 ) . 0 ;
6148+ let dst = PublicKey :: from_slice ( nodes. unordered_keys ( )
6149+ . skip ( ( seed as usize ) % nodes. len ( ) ) . next ( ) . unwrap ( ) . as_slice ( ) ) . unwrap ( ) ;
6150+ let params = PaymentParameters :: from_node_id ( dst, 42 )
6151+ . with_bolt11_features ( features. clone ( ) ) . unwrap ( ) ;
61276152 let first_hop = first_hop ( src) ;
6128- let amt = seed as u64 % 1_000_000 ;
6129- if let Ok ( route) = get_route ( & payer, & params, & graph. read_only ( ) , Some ( & [ & first_hop] ) ,
6130- amt, & TestLogger :: new ( ) , & scorer, score_params, & random_seed_bytes,
6131- ) {
6132- routes. push ( route) ;
6133- route_endpoints. push ( ( first_hop, params, amt) ) ;
6134- continue ' load_endpoints;
6135- }
6136- }
6137- }
6153+ let amt = starting_amount + seed % 1_000_000 ;
6154+ let path_exists =
6155+ get_route ( & payer, & params, & graph. read_only ( ) , Some ( & [ & first_hop] ) ,
6156+ amt, & TestLogger :: new ( ) , & scorer, score_params, & random_seed_bytes) . is_ok ( ) ;
6157+ if path_exists {
6158+ // ...and seed the scorer with success and failure data...
6159+ seed = seed. overflowing_mul ( 6364136223846793005 ) . 0 . overflowing_add ( 1 ) . 0 ;
6160+ let mut score_amt = seed % 1_000_000_000 ;
6161+ loop {
6162+ // Generate fail/success paths for a wider range of potential amounts with
6163+ // MPP enabled to give us a chance to apply penalties for more potential
6164+ // routes.
6165+ let mpp_features = channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) ;
6166+ let params = PaymentParameters :: from_node_id ( dst, 42 )
6167+ . with_bolt11_features ( mpp_features) . unwrap ( ) ;
6168+
6169+ let route_res = get_route ( & payer, & params, & graph. read_only ( ) ,
6170+ Some ( & [ & first_hop] ) , score_amt, & TestLogger :: new ( ) , & scorer,
6171+ score_params, & random_seed_bytes) ;
6172+ if let Ok ( route) = route_res {
6173+ for path in route. paths {
6174+ if seed & 0x80 == 0 {
6175+ scorer. payment_path_successful ( & path) ;
6176+ } else {
6177+ let short_channel_id = path. hops [ path. hops . len ( ) / 2 ] . short_channel_id ;
6178+ scorer. payment_path_failed ( & path, short_channel_id) ;
6179+ }
6180+ seed = seed. overflowing_mul ( 6364136223846793005 ) . 0 . overflowing_add ( 1 ) . 0 ;
6181+ }
6182+ break ;
6183+ }
6184+ // If we couldn't find a path with a higer amount, reduce and try again.
6185+ score_amt /= 100 ;
6186+ }
61386187
6139- // ...and seed the scorer with success and failure data...
6140- for route in routes {
6141- let amount = route. get_total_amount ( ) ;
6142- if amount < 250_000 {
6143- for path in route. paths {
6144- scorer. payment_path_successful ( & path) ;
6145- }
6146- } else if amount > 750_000 {
6147- for path in route. paths {
6148- let short_channel_id = path. hops [ path. hops . len ( ) / 2 ] . short_channel_id ;
6149- scorer. payment_path_failed ( & path, short_channel_id) ;
6188+ route_endpoints. push ( ( first_hop, params, amt) ) ;
6189+ break ;
61506190 }
61516191 }
61526192 }
@@ -6189,15 +6229,15 @@ mod benches {
61896229 let logger = TestLogger :: new ( ) ;
61906230 let network_graph = bench_utils:: read_network_graph ( & logger) . unwrap ( ) ;
61916231 let scorer = FixedPenaltyScorer :: with_penalty ( 0 ) ;
6192- generate_routes ( bench, & network_graph, scorer, & ( ) , InvoiceFeatures :: empty ( ) ) ;
6232+ generate_routes ( bench, & network_graph, scorer, & ( ) , InvoiceFeatures :: empty ( ) , 0 ) ;
61936233 }
61946234
61956235 #[ bench]
61966236 fn generate_mpp_routes_with_zero_penalty_scorer ( bench : & mut Bencher ) {
61976237 let logger = TestLogger :: new ( ) ;
61986238 let network_graph = bench_utils:: read_network_graph ( & logger) . unwrap ( ) ;
61996239 let scorer = FixedPenaltyScorer :: with_penalty ( 0 ) ;
6200- generate_routes ( bench, & network_graph, scorer, & ( ) , channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) ) ;
6240+ generate_routes ( bench, & network_graph, scorer, & ( ) , channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) , 0 ) ;
62016241 }
62026242
62036243 #[ bench]
@@ -6206,7 +6246,7 @@ mod benches {
62066246 let network_graph = bench_utils:: read_network_graph ( & logger) . unwrap ( ) ;
62076247 let params = ProbabilisticScoringFeeParameters :: default ( ) ;
62086248 let scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & network_graph, & logger) ;
6209- generate_routes ( bench, & network_graph, scorer, & params, InvoiceFeatures :: empty ( ) ) ;
6249+ generate_routes ( bench, & network_graph, scorer, & params, InvoiceFeatures :: empty ( ) , 0 ) ;
62106250 }
62116251
62126252 #[ bench]
@@ -6215,19 +6255,28 @@ mod benches {
62156255 let network_graph = bench_utils:: read_network_graph ( & logger) . unwrap ( ) ;
62166256 let params = ProbabilisticScoringFeeParameters :: default ( ) ;
62176257 let scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & network_graph, & logger) ;
6218- generate_routes ( bench, & network_graph, scorer, & params, channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) ) ;
6258+ generate_routes ( bench, & network_graph, scorer, & params, channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) , 0 ) ;
6259+ }
6260+
6261+ #[ bench]
6262+ fn generate_large_mpp_routes_with_probabilistic_scorer ( bench : & mut Bencher ) {
6263+ let logger = TestLogger :: new ( ) ;
6264+ let network_graph = bench_utils:: read_network_graph ( & logger) . unwrap ( ) ;
6265+ let params = ProbabilisticScoringFeeParameters :: default ( ) ;
6266+ let scorer = ProbabilisticScorer :: new ( ProbabilisticScoringDecayParameters :: default ( ) , & network_graph, & logger) ;
6267+ generate_routes ( bench, & network_graph, scorer, & params, channelmanager:: provided_invoice_features ( & UserConfig :: default ( ) ) , 100_000_000 ) ;
62196268 }
62206269
62216270 fn generate_routes < S : Score > (
62226271 bench : & mut Bencher , graph : & NetworkGraph < & TestLogger > , mut scorer : S ,
6223- score_params : & S :: ScoreParams , features : InvoiceFeatures ,
6272+ score_params : & S :: ScoreParams , features : InvoiceFeatures , starting_amount : u64 ,
62246273 ) {
62256274 let payer = bench_utils:: payer_pubkey ( ) ;
62266275 let keys_manager = KeysManager :: new ( & [ 0u8 ; 32 ] , 42 , 42 ) ;
62276276 let random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ;
62286277
62296278 // First, get 100 (source, destination) pairs for which route-getting actually succeeds...
6230- let route_endpoints = bench_utils:: generate_test_routes ( graph, & mut scorer, score_params, features, 0xdeadbeef , 100 ) ;
6279+ let route_endpoints = bench_utils:: generate_test_routes ( graph, & mut scorer, score_params, features, 0xdeadbeef , starting_amount , 50 ) ;
62316280
62326281 // ...then benchmark finding paths between the nodes we learned.
62336282 let mut idx = 0 ;
0 commit comments