@@ -171,6 +171,7 @@ static const s64 MU_MAX = 100;
171171
172172/* every payment under 1000sat will be routed through a single path */
173173static const struct amount_msat SINGLE_PATH_THRESHOLD = AMOUNT_MSAT (1000000 );
174+ static const double DEFAULT_BASE_PROBABILITY = 0.98 ;
174175
175176/* Let's try this encoding of arcs:
176177 * Each channel `c` has two possible directions identified by a bit
@@ -300,6 +301,13 @@ struct pay_parameters {
300301
301302 double delay_feefactor ;
302303 double base_fee_penalty ;
304+ /* base_prob is understood as global probability for channel
305+ * availability, ie. a channel chosen at random will be able to forward
306+ * 1msat with a probability given by this value. We don't know the
307+ * actual value for this quantity but we can still use it to penalize
308+ * the use of many channels per payment, ie. reducing this number we
309+ * tend to obtaine less routes and/or shorter paths. */
310+ double base_prob ;
303311};
304312
305313/* Helper function.
@@ -359,6 +367,7 @@ static void linearize_channel(const struct pay_parameters *params,
359367 const struct gossmap_chan * c , const int dir ,
360368 s64 * capacity , double * cost )
361369{
370+ const double base_prob_cost = - log (params -> base_prob );
362371 struct amount_msat mincap , maxcap ;
363372
364373 /* This takes into account any payments in progress. */
@@ -391,9 +400,23 @@ static void linearize_channel(const struct pay_parameters *params,
391400 {
392401 set_capacity (& capacity [i ], params -> cap_fraction [i ]* (b - a ), & cap_on_capacity );
393402
394- cost [i ] = params -> cost_fraction [i ] * 1000
395- * amount_msat_ratio (params -> amount , params -> accuracy )
396- / (b - a );
403+ /* It is conceptually wrong to add a base cost to every arc,
404+ * that would mean we might pay several times for the same base
405+ * cost. The linearization of the base cost is another corner
406+ * that needs improvement.
407+ * For a cost function of the form
408+ * C(x) = x*k1 + k0
409+ * we produce a linear variation of the form
410+ * C_lin(x) = x*(k1 + k0/T)
411+ * where T is the entire payment amount.
412+ * Since we also scale up the probability cost function by
413+ * 1000*T the resulting linear approximation becomes:
414+ * C_lin(x) = x*1000*(k1*T + k0)
415+ **/
416+ cost [i ] = 1000 * (params -> cost_fraction [i ] / (b - a ) *
417+ amount_msat_ratio (params -> amount ,
418+ params -> accuracy ) +
419+ base_prob_cost );
397420 }
398421}
399422
@@ -970,7 +993,8 @@ struct flow **minflow(const tal_t *ctx,
970993 const struct gossmap_node * target ,
971994 struct amount_msat amount ,
972995 u32 mu ,
973- double delay_feefactor )
996+ double delay_feefactor ,
997+ double base_prob )
974998{
975999 struct flow * * flow_paths ;
9761000 /* We allocate everything off this, and free it at the end,
@@ -991,6 +1015,7 @@ struct flow **minflow(const tal_t *ctx,
9911015 * */
9921016 params -> accuracy =
9931017 amount_msat_max (AMOUNT_MSAT (1 ), amount_msat_div_ceil (amount , 1000 ));
1018+ params -> base_prob = base_prob ;
9941019
9951020 // template the channel partition into linear arcs
9961021 params -> cap_fraction [0 ]= 0 ;
@@ -1149,7 +1174,8 @@ static void init_linear_network_single_path(
11491174 (* arc_capacity )[arc .idx ] = 1 ;
11501175 (* arc_prob_cost )[arc .idx ] =
11511176 (-1.0 ) * log (pickhardt_richter_probability (
1152- mincap , maxcap , params -> amount ));
1177+ mincap , maxcap , params -> amount ) *
1178+ params -> base_prob );
11531179
11541180 struct amount_msat fee ;
11551181 if (!amount_msat_fee (& fee , params -> amount ,
@@ -1171,7 +1197,8 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
11711197 const struct gossmap_node * source ,
11721198 const struct gossmap_node * target ,
11731199 struct amount_msat amount , u32 mu ,
1174- double delay_feefactor )
1200+ double delay_feefactor ,
1201+ double base_prob )
11751202{
11761203 struct flow * * flow_paths ;
11771204 /* We allocate everything off this, and free it at the end,
@@ -1188,6 +1215,7 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
11881215 params -> accuracy = amount ;
11891216 params -> delay_feefactor = delay_feefactor ;
11901217 params -> base_fee_penalty = base_fee_penalty_estimate (amount );
1218+ params -> base_prob = base_prob ;
11911219
11921220 struct graph * graph ;
11931221 double * arc_prob_cost ;
@@ -1352,7 +1380,7 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
13521380 struct flow * * (* solver )(const tal_t * , const struct route_query * ,
13531381 const struct gossmap_node * ,
13541382 const struct gossmap_node * ,
1355- struct amount_msat , u32 , double ))
1383+ struct amount_msat , u32 , double , double ))
13561384{
13571385 const tal_t * working_ctx = tal (ctx , tal_t );
13581386 const char * error_message ;
@@ -1373,6 +1401,7 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
13731401
13741402 /* Re-use the reservation system to make flows aware of each other. */
13751403 struct reserve_hop * reservations = new_reservations (working_ctx , rq );
1404+ double base_prob = DEFAULT_BASE_PROBABILITY ;
13761405
13771406 while (!amount_msat_is_zero (amount_to_deliver )) {
13781407 size_t num_parts , parts_slots , excess_parts ;
@@ -1409,11 +1438,13 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
14091438 parts_slots == 1 ) {
14101439 new_flows = single_path_flow (working_ctx , rq , srcnode ,
14111440 dstnode , amount_to_deliver ,
1412- mu , delay_feefactor );
1441+ mu , delay_feefactor ,
1442+ base_prob );
14131443 } else {
14141444 new_flows =
14151445 solver (working_ctx , rq , srcnode , dstnode ,
1416- amount_to_deliver , mu , delay_feefactor );
1446+ amount_to_deliver , mu , delay_feefactor ,
1447+ base_prob );
14171448 }
14181449
14191450 if (!new_flows ) {
@@ -1448,9 +1479,10 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
14481479 }
14491480
14501481 if (tal_count (new_flows ) > parts_slots ) {
1451- /* Remove the excees of parts and leave one slot for the
1452- * next round of computations. */
1453- excess_parts = 1 + tal_count (new_flows ) - parts_slots ;
1482+ /* try again but with a bigger activation cost per
1483+ * channel */
1484+ base_prob *= DEFAULT_BASE_PROBABILITY ;
1485+ continue ;
14541486 } else if (tal_count (new_flows ) == parts_slots &&
14551487 amount_msat_less (all_deliver , amount_to_deliver )) {
14561488 /* Leave exactly 1 slot for the next round of
@@ -1467,6 +1499,8 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
14671499 tal_count (new_flows ));
14681500 goto fail ;
14691501 }
1502+
1503+ // FIXME: if too many parts -> decrease the base prob
14701504
14711505 /* Is this set of flows too expensive?
14721506 * We can check if the new flows are within the fee budget,
0 commit comments