@@ -509,21 +509,17 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
509
509
510
510
let value_contribution_msat = cmp:: min( available_value_contribution_msat, $next_hops_value_contribution) ;
511
511
// Includes paying fees for the use of the following channels.
512
- let amount_to_transfer_over_msat: u64 = match value_contribution_msat. checked_add( $next_hops_fee_msat) {
512
+ let mut amount_to_transfer_over_msat: u64 = match value_contribution_msat. checked_add( $next_hops_fee_msat) {
513
513
Some ( result) => result,
514
514
// Can't overflow due to how the values were computed right above.
515
515
None => unreachable!( ) ,
516
516
} ;
517
517
518
- // If HTLC minimum is larger than the amount we're going to transfer, we shouldn't
519
- // bother considering this channel.
520
- // Since we're choosing amount_to_transfer_over_msat as maximum possible, it can
521
- // be only reduced later (not increased), so this channel should just be skipped
522
- // as not sufficient.
523
- // TODO: Explore simply adding fee to hit htlc_minimum_msat
518
+ // If HTLC minimum is larger than the amount we're going to transfer, we shouldn
519
+ // transfer that value instead, thus overpaying fees.
524
520
let effective_htlc_minimum_msat = cmp:: max( $directional_info. htlc_minimum_msat, $incl_fee_next_hops_htlc_minimum_msat) ;
525
- let over_path_minimum_msat = amount_to_transfer_over_msat >= effective_htlc_minimum_msat;
526
- if contributes_sufficient_value && over_path_minimum_msat {
521
+ amount_to_transfer_over_msat = cmp :: max ( amount_to_transfer_over_msat, effective_htlc_minimum_msat) ;
522
+ if contributes_sufficient_value {
527
523
let hm_entry = dist. entry( & $src_node_id) ;
528
524
let old_entry = hm_entry. or_insert_with( || {
529
525
// If there was previously no known way to access
@@ -602,34 +598,12 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
602
598
} ,
603
599
} ;
604
600
605
- // Update the way of reaching $src_node_id with the given $chan_id (from $dest_node_id),
606
- // if this way is cheaper than the already known
601
+ // Update the way of reaching $src_node_id with the given $chan_id (from
602
+ // $dest_node_id), if this way is cheaper than the already known
607
603
// (considering the cost to "reach" this channel from the route destination,
608
- // the cost of using this channel,
604
+ // the cost of using this channel (with possible overpayment for htlc min)
609
605
// and the cost of routing to the source node of this channel).
610
- // Also, consider that htlc_minimum_msat_difference, because we might end up
611
- // paying it. Consider the following exploit:
612
- // we use 2 paths to transfer 1.5 BTC. One of them is 0-fee normal 1 BTC path,
613
- // and for the other one we picked a 1sat-fee path with htlc_minimum_msat of
614
- // 1 BTC. Now, since the latter is more expensive, we gonna try to cut it
615
- // by 0.5 BTC, but then match htlc_minimum_msat by paying a fee of 0.5 BTC
616
- // to this channel.
617
- // TODO: this scoring could be smarter (e.g. 0.5*htlc_minimum_msat here).
618
- let mut old_cost = old_entry. total_fee_msat;
619
- if let Some ( increased_old_cost) = old_cost. checked_add( old_entry. htlc_minimum_msat) {
620
- old_cost = increased_old_cost;
621
- } else {
622
- old_cost = u64 :: max_value( ) ;
623
- }
624
-
625
- let mut new_cost = total_fee_msat;
626
- if let Some ( increased_new_cost) = new_cost. checked_add( $directional_info. htlc_minimum_msat) {
627
- new_cost = increased_new_cost;
628
- } else {
629
- new_cost = u64 :: max_value( ) ;
630
- }
631
-
632
- if new_cost < old_cost {
606
+ if total_fee_msat < old_entry. total_fee_msat {
633
607
targets. push( new_graph_node) ;
634
608
old_entry. next_hops_fee_msat = $next_hops_fee_msat;
635
609
old_entry. hop_use_fee_msat = hop_use_fee_msat;
@@ -820,35 +794,7 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
820
794
}
821
795
822
796
new_entry = match dist. remove ( & ordered_hops. last ( ) . unwrap ( ) . route_hop . pubkey ) {
823
- Some ( payment_hop) => {
824
- if new_entry. hop_use_fee_msat + value_contribution_msat <
825
- ordered_hops. last_mut ( ) . unwrap ( ) . effective_htlc_minimum_msat {
826
- // This could happen if a mismatch happened in add_entry! when
827
- // there is a path fork: e.g. source-A-B-payee and source-A-C-payee.
828
- // The mismatch of htlc_min could happen if B is the cheapest path,
829
- // but while adding A-for-B, A can't hit htlc_minimum_msat.
830
- // Then, we add A-for-C because it does hit htlc_minimum msat.
831
- //
832
- // This block would trigger if after this we choose A-for-C
833
- // as a way to reach B, and we break from the loop because this
834
- // path would be invalid otherwise.
835
- //
836
- // The actual problem would happen when we propagate fees one hop
837
- // backward (see below), the A-for-C is not sufficient to hit
838
- // htlc_minimum_msat anymore.
839
- //
840
- // This check here attempts to check the compatibility:
841
- // (fine if A-for-C just matches following C or overpays for D).
842
- //
843
- // TODO. this is a safe approach. It indeed avoids invalid paths,
844
- // but it also could drop valid ones. Ideally, we should prevent
845
- // the latter too. Although dropping is rare, because in the example
846
- // above, C would be dropped from candidates, and then we just have
847
- // to implement hitting htlc_minimum_msat for B in add_entry.
848
- break ' paths_collection;
849
- }
850
- payment_hop
851
- }
797
+ Some ( payment_hop) => payment_hop,
852
798
None => {
853
799
// If we can't reach a given node, something went wrong
854
800
// during path traverse.
@@ -1578,7 +1524,6 @@ mod tests {
1578
1524
} ) ;
1579
1525
1580
1526
// Check against amount_to_transfer_over_msat.
1581
- // We will be transferring 300_000_000 msat.
1582
1527
// Set minimal HTLC of 200_000_000 msat.
1583
1528
update_channel ( & net_graph_msg_handler, & secp_ctx, & our_privkey, UnsignedChannelUpdate {
1584
1529
chain_hash : genesis_block ( Network :: Testnet ) . header . block_hash ( ) ,
@@ -1608,10 +1553,9 @@ mod tests {
1608
1553
excess_data : Vec :: new ( )
1609
1554
} ) ;
1610
1555
1611
- // Not possible to send 299_999_999: we first allocate 200_000_000 for the channel#12,
1612
- // and then the amount_to_transfer_over_msat over channel#2 is less than our limit.
1613
- if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route ( & our_id, & net_graph_msg_handler. network_graph . read ( ) . unwrap ( ) , & nodes[ 2 ] , None , & Vec :: new ( ) , 199_999_999 , 42 , Arc :: clone ( & logger) ) {
1614
- assert_eq ! ( err, "Failed to find a path to the given destination" ) ;
1556
+ // Not possible to send 299_999_999.
1557
+ if let Err ( LightningError { err, action : ErrorAction :: IgnoreError } ) = get_route ( & our_id, & net_graph_msg_handler. network_graph . read ( ) . unwrap ( ) , & nodes[ 2 ] , None , & Vec :: new ( ) , 299_999_999 , 42 , Arc :: clone ( & logger) ) {
1558
+ assert_eq ! ( err, "Failed to find a sufficient route to the given destination" ) ;
1615
1559
} else { panic ! ( ) ; }
1616
1560
1617
1561
// Lift the restriction on the first hop.
0 commit comments