@@ -645,7 +645,7 @@ where L::Target: Logger {
645
645
pub ( crate ) fn get_route < L : Deref , S : Score > (
646
646
our_node_pubkey : & PublicKey , payment_params : & PaymentParameters , network_graph : & ReadOnlyNetworkGraph ,
647
647
first_hops : Option < & [ & ChannelDetails ] > , final_value_msat : u64 , final_cltv_expiry_delta : u32 ,
648
- logger : L , scorer : & S , _random_seed_bytes : & [ u8 ; 32 ]
648
+ logger : L , scorer : & S , random_seed_bytes : & [ u8 ; 32 ]
649
649
) -> Result < Route , LightningError >
650
650
where L :: Target : Logger {
651
651
let payee_node_id = NodeId :: from_pubkey ( & payment_params. payee_pubkey ) ;
@@ -830,7 +830,7 @@ where L::Target: Logger {
830
830
. entry( short_channel_id)
831
831
. or_insert_with( || $candidate. effective_capacity( ) . as_msat( ) ) ;
832
832
833
- // It is tricky to substract $next_hops_fee_msat from available liquidity here.
833
+ // It is tricky to subtract $next_hops_fee_msat from available liquidity here.
834
834
// It may be misleading because we might later choose to reduce the value transferred
835
835
// over these channels, and the channel which was insufficient might become sufficient.
836
836
// Worst case: we drop a good channel here because it can't cover the high following
@@ -1446,14 +1446,31 @@ where L::Target: Logger {
1446
1446
1447
1447
// Draw multiple sufficient routes by randomly combining the selected paths.
1448
1448
let mut drawn_routes = Vec :: new ( ) ;
1449
- for i in 0 ..payment_paths. len ( ) {
1449
+ let mut prng = ChaCha20 :: new ( random_seed_bytes, & [ 0u8 ; 12 ] ) ;
1450
+ let mut random_index_bytes = [ 0u8 ; :: core:: mem:: size_of :: < usize > ( ) ] ;
1451
+
1452
+ let num_permutations = payment_paths. len ( ) ;
1453
+ let mut seen_permutation_scids: HashSet < Vec < Vec < u64 > > > = HashSet :: new ( ) ;
1454
+ for _ in 0 ..num_permutations {
1450
1455
let mut cur_route = Vec :: < PaymentPath > :: new ( ) ;
1451
1456
let mut aggregate_route_value_msat = 0 ;
1452
1457
1453
1458
// Step (6).
1454
- // TODO: real random shuffle
1455
- // Currently just starts with i_th and goes up to i-1_th in a looped way.
1456
- let cur_payment_paths = [ & payment_paths[ i..] , & payment_paths[ ..i] ] . concat ( ) ;
1459
+ // Do a Fisher-Yates shuffle to create a unique permutation of the payment paths
1460
+ let cur_payment_paths = loop {
1461
+ let mut cur_perm = payment_paths. clone ( ) ;
1462
+ for cur_index in ( 1 ..cur_perm. len ( ) ) . rev ( ) {
1463
+ prng. process_in_place ( & mut random_index_bytes) ;
1464
+ let random_index = usize:: from_be_bytes ( random_index_bytes) . wrapping_rem ( cur_index+1 ) ;
1465
+ cur_perm. swap ( cur_index, random_index) ;
1466
+ }
1467
+ let cur_perm_scids = cur_perm. iter ( ) . map ( |path|
1468
+ path. hops . iter ( ) . map ( |( hop, _) | hop. candidate . short_channel_id ( ) ) . collect :: < Vec < u64 > > ( )
1469
+ ) . collect :: < Vec < Vec < u64 > > > ( ) ;
1470
+ if seen_permutation_scids. insert ( cur_perm_scids) {
1471
+ break cur_perm;
1472
+ }
1473
+ } ;
1457
1474
1458
1475
// Step (7).
1459
1476
for payment_path in cur_payment_paths {
@@ -1466,12 +1483,17 @@ where L::Target: Logger {
1466
1483
// also makes routing more reliable.
1467
1484
let mut overpaid_value_msat = aggregate_route_value_msat - final_value_msat;
1468
1485
1469
- // First, drop some expensive low-value paths entirely if possible.
1470
- // Sort by value so that we drop many really-low values first, since
1486
+ // First, we drop some expensive low-value paths entirely if possible.
1487
+ // In order to do so, we pre-sort by total fees paid, so that in case of equal
1488
+ // values we prefer lower cost paths.
1489
+ // (Descending order, so we drop higher-fee paths first)
1490
+ cur_route. sort_by_key ( |path| path. get_total_fee_paid_msat ( ) ) ;
1491
+ cur_route. reverse ( ) ;
1492
+
1493
+ // Then sort by value so that we drop many really-low values first, since
1471
1494
// fewer paths is better: the payment is less likely to fail.
1472
- // TODO: this could also be optimized by also sorting by feerate_per_sat_routed,
1473
- // so that the sender pays less fees overall. And also htlc_minimum_msat.
1474
1495
cur_route. sort_by_key ( |path| path. get_value_msat ( ) ) ;
1496
+
1475
1497
// We should make sure that at least 1 path left.
1476
1498
let mut paths_left = cur_route. len ( ) ;
1477
1499
cur_route. retain ( |path| {
@@ -1495,13 +1517,14 @@ where L::Target: Logger {
1495
1517
assert ! ( cur_route. len( ) > 0 ) ;
1496
1518
1497
1519
// Step (8).
1498
- // Now, substract the overpaid value from the most-expensive path.
1520
+ // Now, subtract the overpaid value from the most-expensive path.
1499
1521
// TODO: this could also be optimized by also sorting by feerate_per_sat_routed,
1500
1522
// so that the sender pays less fees overall. And also htlc_minimum_msat.
1501
1523
cur_route. sort_by_key ( |path| { path. hops . iter ( ) . map ( |hop| hop. 0 . candidate . fees ( ) . proportional_millionths as u64 ) . sum :: < u64 > ( ) } ) ;
1502
1524
let expensive_payment_path = cur_route. first_mut ( ) . unwrap ( ) ;
1503
- // We already dropped all the small channels above, meaning all the
1504
- // remaining channels are larger than remaining overpaid_value_msat.
1525
+
1526
+ // We already dropped all the small value paths above, meaning all the
1527
+ // remaining paths are larger than remaining overpaid_value_msat.
1505
1528
// Thus, this can't be negative.
1506
1529
let expensive_path_new_value_msat = expensive_payment_path. get_value_msat ( ) - overpaid_value_msat;
1507
1530
expensive_payment_path. update_value_and_recompute_fees ( expensive_path_new_value_msat) ;
0 commit comments