88#include <common/random_select.h>
99#include <common/type_to_string.h>
1010#include <errno.h>
11+ #include <math.h>
1112#include <plugins/libplugin-pay.h>
1213#include <sys/types.h>
1314#include <wire/peer_wire.h>
@@ -707,22 +708,15 @@ static u64 capacity_bias(const struct gossmap *map,
707708 int dir ,
708709 struct amount_msat amount )
709710{
710- struct amount_msat fee ;
711711 struct amount_sat capacity ;
712-
713- /* Median fees are 1000 base, 10 ppm, so scale capacity bias to that */
714- /* Overflow is pretty-much impossible, so ignore. */
715- if (!amount_msat_fee (& fee , amount , 1000 , 10 ))
716- return 0 ;
712+ u64 capmsat , amtmsat = amount .millisatoshis ; /* Raw: lengthy math */
717713
718714 /* Can fail in theory if gossmap changed underneath. */
719715 if (!gossmap_chan_get_capacity (map , c , & capacity ))
720716 return 0 ;
721717
722- /* bias = fee * (amt / (c + 1)) */
723- return fee .millisatoshis /* Raw: complex math & laziness */
724- * amount .millisatoshis /* Raw: complex math & laziness */
725- / (capacity .satoshis * 1000 + 1 ); /* Raw: complex math & laziness */
718+ capmsat = capacity .satoshis * 1000 ; /* Raw: lengthy math */
719+ return - log ((capmsat + 1 - amtmsat ) / (capmsat + 1 ));
726720}
727721
728722/* Prioritize costs over distance, but bias to larger channels. */
@@ -732,10 +726,13 @@ static u64 route_score(u32 distance,
732726 int dir ,
733727 const struct gossmap_chan * c )
734728{
735- u64 costs = cost .millisatoshis + risk .millisatoshis /* Raw: score */
736- /* We use global_gossmap (can't still be NULL)
737- * *without* get_gossmap() which might change topology. */
738- + capacity_bias (global_gossmap , c , dir , cost );
729+ u64 cmsat = cost .millisatoshis ; /* Raw: lengthy math */
730+ u64 rmsat = risk .millisatoshis ; /* Raw: lengthy math */
731+ u64 bias = capacity_bias (global_gossmap , c , dir , cost );
732+
733+ /* Smoothed harmonic mean to avoid division by 0 */
734+ u64 costs = (cmsat * rmsat * bias ) / (cmsat + rmsat + bias + 1 );
735+
739736 if (costs > 0xFFFFFFFF )
740737 costs = 0xFFFFFFFF ;
741738 return costs ;
0 commit comments