@@ -691,6 +691,55 @@ static bool payment_route_can_carry_even_disabled(const struct gossmap *map,
691
691
return payment_route_check (map , c , dir , amount , p );
692
692
}
693
693
694
+ /* Rene Pickhardt:
695
+ *
696
+ * Btw the linear term of the Taylor series of -log((c+1-x)/(c+1)) is 1/(c+1)
697
+ * meaning that another suitable Weight for Dijkstra would be amt/(c+1) +
698
+ * \mu*fee(amt) which is the linearized version which for small amounts and
699
+ * suitable value of \mu should be good enough)
700
+ */
701
+ static u64 capacity_bias (const struct gossmap * map ,
702
+ const struct gossmap_chan * c ,
703
+ int dir ,
704
+ struct amount_msat cost )
705
+ {
706
+ struct amount_msat fee ;
707
+ struct amount_sat capacity ;
708
+
709
+ /* Overflow is pretty-much impossible, so ignore. */
710
+ if (!amount_msat_fee (& fee , cost ,
711
+ c -> half [dir ].base_fee ,
712
+ c -> half [dir ].proportional_fee ))
713
+ return 0 ;
714
+
715
+ /* Can fail in theory if gossmap changed underneath. */
716
+ if (!gossmap_chan_get_capacity (map , c , & capacity ))
717
+ return 0 ;
718
+
719
+ /* Assume we want \mu = 1/2 (i.e. capacity matters twice as much
720
+ * as fees), we get: bias = 2 * fee * (amt / (c + 1)) */
721
+ return 2
722
+ * fee .millisatoshis /* Raw: complex math & laziness */
723
+ * cost .millisatoshis /* Raw: complex math & laziness */
724
+ / (capacity .satoshis * 1000 + 1 ); /* Raw: complex math & laziness */
725
+ }
726
+
727
+ /* Prioritize costs over distance, but bias to larger channels. */
728
+ static u64 route_score (u32 distance ,
729
+ struct amount_msat cost ,
730
+ struct amount_msat risk ,
731
+ int dir ,
732
+ const struct gossmap_chan * c )
733
+ {
734
+ u64 costs = cost .millisatoshis + risk .millisatoshis /* Raw: score */
735
+ /* We use global_gossmap (can't still be NULL)
736
+ * *without* which might change topology. */
737
+ + capacity_bias (global_gossmap , c , dir , cost );
738
+ if (costs > 0xFFFFFFFF )
739
+ costs = 0xFFFFFFFF ;
740
+ return costs ;
741
+ }
742
+
694
743
static struct route_hop * route (const tal_t * ctx ,
695
744
struct gossmap * gossmap ,
696
745
const struct gossmap_node * src ,
@@ -712,14 +761,14 @@ static struct route_hop *route(const tal_t *ctx,
712
761
713
762
can_carry = payment_route_can_carry ;
714
763
dij = dijkstra (tmpctx , gossmap , dst , amount , riskfactor ,
715
- can_carry , route_score_cheaper , p );
764
+ can_carry , route_score , p );
716
765
r = route_from_dijkstra (ctx , gossmap , dij , src , amount , final_delay );
717
766
if (!r ) {
718
767
/* Try using disabled channels too */
719
768
/* FIXME: is there somewhere we can annotate this for paystatus? */
720
769
can_carry = payment_route_can_carry_even_disabled ;
721
770
dij = dijkstra (ctx , gossmap , dst , amount , riskfactor ,
722
- can_carry , route_score_cheaper , p );
771
+ can_carry , route_score , p );
723
772
r = route_from_dijkstra (ctx , gossmap , dij , src ,
724
773
amount , final_delay );
725
774
if (!r ) {
0 commit comments