@@ -691,6 +691,55 @@ static bool payment_route_can_carry_even_disabled(const struct gossmap *map,
691691 return payment_route_check (map , c , dir , amount , p );
692692}
693693
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+
694743static struct route_hop * route (const tal_t * ctx ,
695744 struct gossmap * gossmap ,
696745 const struct gossmap_node * src ,
@@ -712,14 +761,14 @@ static struct route_hop *route(const tal_t *ctx,
712761
713762 can_carry = payment_route_can_carry ;
714763 dij = dijkstra (tmpctx , gossmap , dst , amount , riskfactor ,
715- can_carry , route_score_cheaper , p );
764+ can_carry , route_score , p );
716765 r = route_from_dijkstra (ctx , gossmap , dij , src , amount , final_delay );
717766 if (!r ) {
718767 /* Try using disabled channels too */
719768 /* FIXME: is there somewhere we can annotate this for paystatus? */
720769 can_carry = payment_route_can_carry_even_disabled ;
721770 dij = dijkstra (ctx , gossmap , dst , amount , riskfactor ,
722- can_carry , route_score_cheaper , p );
771+ can_carry , route_score , p );
723772 r = route_from_dijkstra (ctx , gossmap , dij , src ,
724773 amount , final_delay );
725774 if (!r ) {
0 commit comments