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