@@ -286,6 +286,9 @@ struct pay_parameters {
286286 // how much we pay
287287 struct amount_msat amount ;
288288
289+ /* base unit for computation, ie. accuracy */
290+ struct amount_msat accuracy ;
291+
289292 // channel linearization parameters
290293 double cap_fraction [CHANNEL_PARTS ],
291294 cost_fraction [CHANNEL_PARTS ];
@@ -360,22 +363,23 @@ static void linearize_channel(const struct pay_parameters *params,
360363 if (amount_msat_greater (mincap , maxcap ))
361364 mincap = maxcap ;
362365
363- u64 a = mincap . millisatoshis / 1000 , /* Raw: linearize_channel */
364- b = 1 + maxcap . millisatoshis / 1000 ; /* Raw: linearize_channel */
366+ u64 a = amount_msat_ratio_floor ( mincap , params -> accuracy ),
367+ b = 1 + amount_msat_ratio_floor ( maxcap , params -> accuracy );
365368
366369 /* An extra bound on capacity, here we use it to reduce the flow such
367370 * that it does not exceed htlcmax. */
368- u64 cap_on_capacity = fp16_to_u64 (c -> half [dir ].htlc_max ) / 1000 ;
371+ u64 cap_on_capacity =
372+ amount_msat_ratio_floor (gossmap_chan_htlc_max (c , dir ), params -> accuracy );
369373
370374 set_capacity (& capacity [0 ], a , & cap_on_capacity );
371375 cost [0 ]= 0 ;
372376 for (size_t i = 1 ;i < CHANNEL_PARTS ;++ i )
373377 {
374378 set_capacity (& capacity [i ], params -> cap_fraction [i ]* (b - a ), & cap_on_capacity );
375379
376- cost [i ] = params -> cost_fraction [i ]
377- * params -> amount . millisatoshis /* Raw: linearize_channel */
378- /( b - a );
380+ cost [i ] = params -> cost_fraction [i ] * 1000
381+ * amount_msat_ratio ( params -> amount , params -> accuracy )
382+ / ( b - a );
379383 }
380384}
381385
@@ -509,7 +513,7 @@ static void combine_cost_function(
509513 *
510514 * into
511515 *
512- * fee_microsat = c_fee * x_sat
516+ * fee = c_fee/10^6 * x
513517 *
514518 * use `base_fee_penalty` to weight the base fee and `delay_feefactor` to
515519 * weight the CLTV delay.
@@ -538,21 +542,24 @@ struct amount_msat linear_flow_cost(const struct flow *flow,
538542 double delay_feefactor )
539543{
540544 struct amount_msat msat_cost ;
541- s64 cost = 0 ;
545+ s64 cost_ppm = 0 ;
542546 double base_fee_penalty = base_fee_penalty_estimate (total_amount );
543547
544548 for (size_t i = 0 ; i < tal_count (flow -> path ); i ++ ) {
545549 const struct half_chan * h = & flow -> path [i ]-> half [flow -> dirs [i ]];
546550
547- cost += linear_fee_cost (h -> base_fee , h -> proportional_fee , h -> delay ,
548- base_fee_penalty , delay_feefactor );
551+ cost_ppm +=
552+ linear_fee_cost (h -> base_fee , h -> proportional_fee , h -> delay ,
553+ base_fee_penalty , delay_feefactor );
549554 }
550-
551- if (!amount_msat_mul (& msat_cost , flow -> delivers , cost ))
555+ if (!amount_msat_fee (& msat_cost , flow -> delivers , 0 , cost_ppm ))
552556 abort ();
553557 return msat_cost ;
554558}
555559
560+ /* FIXME: Instead of mapping one-to-one the indexes in the gossmap, try to
561+ * reduce the number of nodes and arcs used by taking only those that are
562+ * enabled. We might save some cpu if the work with a pruned network. */
556563static struct linear_network *
557564init_linear_network (const tal_t * ctx , const struct pay_parameters * params )
558565{
@@ -610,6 +617,7 @@ init_linear_network(const tal_t *ctx, const struct pay_parameters *params)
610617 // that are outgoing to `node`
611618 linearize_channel (params , c , half , capacity , prob_cost );
612619
620+ /* linear fee_cost per unit of flow */
613621 const s64 fee_cost = linear_fee_cost (
614622 c -> half [half ].base_fee ,
615623 c -> half [half ].proportional_fee ,
@@ -732,13 +740,14 @@ struct list_data
732740 * balance, compute the bigest flow and substract it from the nodes balance and
733741 * the channels allocation. */
734742static struct flow * substract_flow (const tal_t * ctx ,
735- const struct gossmap * gossmap ,
743+ const struct pay_parameters * params ,
736744 const struct node source ,
737745 const struct node sink ,
738746 s64 * balance , struct chan_flow * chan_flow ,
739747 const u32 * prev_idx , const int * prev_dir ,
740748 const struct gossmap_chan * const * prev_chan )
741749{
750+ const struct gossmap * gossmap = params -> rq -> gossmap ;
742751 assert (balance [source .idx ] < 0 );
743752 assert (balance [sink .idx ] > 0 );
744753 s64 delta = - balance [source .idx ];
@@ -784,7 +793,8 @@ static struct flow *substract_flow(const tal_t *ctx,
784793
785794 chan_flow [chan_idx ].half [dir ] -= delta ;
786795 }
787- f -> delivers = amount_msat (delta * 1000 );
796+ if (!amount_msat_mul (& f -> delivers , params -> accuracy , delta ))
797+ abort ();
788798 return f ;
789799}
790800
@@ -837,16 +847,16 @@ static void substract_cycle(const struct gossmap *gossmap,
837847static struct flow * *
838848get_flow_paths (const tal_t * ctx ,
839849 const tal_t * working_ctx ,
840- const struct route_query * rq ,
850+ const struct pay_parameters * params ,
841851 const struct linear_network * linear_network ,
842852 const struct residual_network * residual_network )
843853{
844854 struct flow * * flows = tal_arr (ctx ,struct flow * ,0 );
845855
846- const size_t max_num_chans = gossmap_max_chan_idx (rq -> gossmap );
856+ const size_t max_num_chans = gossmap_max_chan_idx (params -> rq -> gossmap );
847857 struct chan_flow * chan_flow = tal_arrz (working_ctx ,struct chan_flow ,max_num_chans );
848858
849- const size_t max_num_nodes = gossmap_max_node_idx (rq -> gossmap );
859+ const size_t max_num_nodes = gossmap_max_node_idx (params -> rq -> gossmap );
850860 s64 * balance = tal_arrz (working_ctx ,s64 ,max_num_nodes );
851861
852862 const struct gossmap_chan * * prev_chan
@@ -892,21 +902,21 @@ get_flow_paths(const tal_t *ctx,
892902 while (balance [source .idx ] < 0 ) {
893903 prev_chan [source .idx ] = NULL ;
894904 struct node sink = find_path_or_cycle (
895- working_ctx , rq -> gossmap , chan_flow , source ,
905+ working_ctx , params -> rq -> gossmap , chan_flow , source ,
896906 balance , prev_chan , prev_dir , prev_idx );
897907
898908 if (balance [sink .idx ] > 0 )
899909 /* case 1. found a path */
900910 {
901911 struct flow * fp = substract_flow (
902- flows , rq -> gossmap , source , sink , balance ,
912+ flows , params , source , sink , balance ,
903913 chan_flow , prev_idx , prev_dir , prev_chan );
904914
905915 tal_arr_expand (& flows , fp );
906916 } else
907917 /* case 2. found a cycle */
908918 {
909- substract_cycle (rq -> gossmap , sink , chan_flow ,
919+ substract_cycle (params -> rq -> gossmap , sink , chan_flow ,
910920 prev_idx , prev_dir , prev_chan );
911921 }
912922 }
@@ -944,6 +954,10 @@ struct flow **minflow(const tal_t *ctx,
944954 params -> source = source ;
945955 params -> target = target ;
946956 params -> amount = amount ;
957+ params -> accuracy = AMOUNT_MSAT (1000 );
958+ /* FIXME: params->accuracy = amount_msat_max(amount_msat_div(amount,
959+ * 1000), AMOUNT_MSAT(1));
960+ * */
947961
948962 // template the channel partition into linear arcs
949963 params -> cap_fraction [0 ]= 0 ;
@@ -972,24 +986,14 @@ struct flow **minflow(const tal_t *ctx,
972986
973987 init_residual_network (linear_network ,residual_network );
974988
975- /* TODO(eduardo):
976- * Some MCF algorithms' performance depend on the size of maxflow. If we
977- * were to work in units of msats we 1. risking overflow when computing
978- * costs and 2. we risk a performance overhead for no good reason.
979- *
980- * Working in units of sats was my first choice, but maybe working in
981- * units of 10, or 100 sats could be even better.
982- *
983- * IDEA: define the size of our precision as some parameter got at
984- * runtime that depends on the size of the payment and adjust the MCF
985- * accordingly.
986- * For example if we are trying to pay 1M sats our precision could be
987- * set to 1000sat, then channels that had capacity for 3M sats become 3k
988- * flow units. */
989- const u64 pay_amount_sats = (params -> amount .millisatoshis + 999 )/1000 ; /* Raw: minflow */
989+ /* Since we have constraint accuracy, ask to find a payment solution
990+ * that can pay a bit more than the actual value rathen than undershoot it.
991+ * That's why we use the ceil function here. */
992+ const u64 pay_amount =
993+ amount_msat_ratio_ceil (params -> amount , params -> accuracy );
990994
991995 if (!simple_feasibleflow (working_ctx , linear_network -> graph , src , dst ,
992- residual_network -> cap , pay_amount_sats )) {
996+ residual_network -> cap , pay_amount )) {
993997 rq_log (tmpctx , rq , LOG_INFORM ,
994998 "%s failed: unable to find a feasible flow." , __func__ );
995999 goto fail ;
@@ -1012,7 +1016,7 @@ struct flow **minflow(const tal_t *ctx,
10121016 /* We dissect the solution of the MCF into payment routes.
10131017 * Actual amounts considering fees are computed for every
10141018 * channel in the routes. */
1015- flow_paths = get_flow_paths (ctx , working_ctx , rq ,
1019+ flow_paths = get_flow_paths (ctx , working_ctx , params ,
10161020 linear_network , residual_network );
10171021 if (!flow_paths ){
10181022 rq_log (tmpctx , rq , LOG_BROKEN ,
0 commit comments