@@ -383,54 +383,94 @@ static struct amount_msat remove_excess(struct flow ***flows,
383383 return all_deliver ;
384384}
385385
386+ /* Return true (and set shortage) if flow doesn't deliver this much */
387+ static bool flows_short (struct flow * * flows ,
388+ struct amount_msat deliver ,
389+ struct amount_msat * shortage )
390+ {
391+ return amount_msat_sub (shortage , deliver , sum_all_deliver (flows ))
392+ && !amount_msat_is_zero (* shortage );
393+ }
394+
386395/* It increases the flows to meet the deliver target. It does not increase any
387- * flow beyond the tolerance fraction. It doesn't increase any flow above its
388- * max_deliverable value.
389- * Returns the total delivery amount. */
390- static struct amount_msat increase_flows (const struct route_query * rq ,
391- struct flow * * flows ,
392- struct amount_msat deliver ,
393- double tolerance )
396+ * flow beyond the tolerance fraction (unless negative).
397+ * Returns true if it managed to increase total amount to "deliver". */
398+ static bool increase_flows (const struct route_query * rq ,
399+ struct flow * * flows ,
400+ struct amount_msat deliver ,
401+ double tolerance )
394402{
395- if ( tal_count ( flows ) == 0 )
396- return AMOUNT_MSAT ( 0 ) ;
403+ const tal_t * working_ctx = tal ( NULL , tal_t );
404+ struct amount_msat shortage , * ceiling ;
397405
398- struct amount_msat all_deliver , defect ;
399- all_deliver = sum_all_deliver (flows );
406+ /* Record max we can deliver for each flow, so we don't exceed it */
407+ ceiling = tal_arr (working_ctx , struct amount_msat , tal_count (flows ));
408+ for (size_t i = 0 ; i < tal_count (flows ); i ++ ) {
409+ if (tolerance < 0 )
410+ ceiling [i ] = deliver ;
411+ else if (!amount_msat_scale (& ceiling [i ], flows [i ]-> delivers , 1.0 + tolerance ))
412+ abort ();
413+ }
400414
401- /* early exit: target is already met */
402- if (!amount_msat_sub (& defect , deliver , all_deliver ) ||
403- amount_msat_is_zero (defect ))
404- return all_deliver ;
415+ /* This is naive, but since flows can overlap, increasing one
416+ * can alter the remaining capacity of the others! */
417+ while (flows_short (flows , deliver , & shortage )) {
418+ size_t best_flownum = 0 ;
419+ struct amount_msat best_remaining = AMOUNT_MSAT (0 );
420+ struct reserve_hop * * reservations ;
421+ struct amount_msat addition ;
422+
423+ /* Because flows can interact, we reserve them all, removing one at a time. */
424+ reservations = tal_arr (NULL , struct reserve_hop * , tal_count (flows ));
425+ for (size_t i = 0 ; i < tal_count (flows ); i ++ ) {
426+ reservations [i ] = new_reservations (reservations , rq );
427+ create_flow_reservations (rq , & reservations [i ], flows [i ]);
428+ }
405429
406- asort (flows , tal_count (flows ), revcmp_flows , NULL );
430+ /* Find flow with most excess capacity. */
431+ for (size_t i = 0 ; i < tal_count (flows ); i ++ ) {
432+ struct amount_msat capacity , remaining ;
407433
408- all_deliver = AMOUNT_MSAT (0 );
409- for (size_t i = 0 ;
410- i < tal_count (flows ) && !amount_msat_is_zero (defect ); i ++ ) {
411- struct flow * flow = flows [i ];
412- struct amount_msat can_add = defect , amt ;
434+ /* flow_max_deliverable considers reservations *and*
435+ * htlc_max. So remove this reservation, to get the
436+ * real maximum for one flow, then replace it. */
437+ tal_free (reservations [i ]);
438+ capacity = flow_max_deliverable (rq , flows [i ], NULL );
439+ reservations [i ] = new_reservations (reservations , rq );
440+ create_flow_reservations (rq , & reservations [i ], flows [i ]);
413441
414- /* no more than tolerance */
415- if (!amount_msat_scale (& amt , flow -> delivers , tolerance ))
416- continue ;
417- else
418- can_add = amount_msat_min (can_add , amt );
442+ /* Don't go above our tolerance */
443+ if (amount_msat_greater (capacity , ceiling [i ]))
444+ capacity = ceiling [i ];
419445
420- /* no more than max_deliverable */
421- if (!amount_msat_sub (& amt , flow_max_deliverable (rq , flow , NULL ),
422- flow -> delivers ))
423- continue ;
446+ if (!amount_msat_sub (& remaining , capacity , flows [i ]-> delivers ))
447+ abort ();
448+ if (amount_msat_greater (remaining , best_remaining )) {
449+ best_flownum = i ;
450+ best_remaining = remaining ;
451+ }
452+ }
453+ tal_free (reservations );
454+
455+ /* Add 1/n of the remainder, or all we can if that's less than 10 sats. */
456+ if (amount_msat_less_sat (shortage , AMOUNT_SAT (10 )))
457+ addition = shortage ;
424458 else
425- can_add = amount_msat_min ( can_add , amt );
459+ addition = amount_msat_div_ceil ( shortage , tal_count ( flows ) );
426460
427- if (!amount_msat_add (& flow -> delivers , flow -> delivers ,
428- can_add ) ||
429- !amount_msat_sub (& defect , defect , can_add ) ||
430- !amount_msat_accumulate (& all_deliver , flow -> delivers ))
461+ /* Can't add it? */
462+ if (amount_msat_less (best_remaining , addition )) {
463+ tal_free (working_ctx );
464+ return false;
465+ }
466+
467+ if (!amount_msat_accumulate (& flows [best_flownum ]-> delivers , addition ))
468+ abort ();
469+ if (!amount_msat_deduct (& shortage , addition ))
431470 abort ();
432471 }
433- return all_deliver ;
472+ tal_free (working_ctx );
473+ return true;
434474}
435475
436476const char * refine_flows (const tal_t * ctx , struct route_query * rq ,
0 commit comments