Skip to content

Commit 010a89e

Browse files
committed
askrene: refine: add a step to increase flows ...
by a small amount if the deliver amount is less than the requested amount by X. This step saves runtime by avoiding calling an extra MCF and it helps us solve a small percentage of cases where the only available routes have HTLCmin that is bigger than X. Out of 50000 simulated payment situations distributed accross payment amounts of 1e2, 1e3, 1e4, 1e5 and 1e6 sats, we find that 133 failed cases in the master branch turn to success with the current changes, while only 3 success cases in the master are not solved by the changes. master +-------+------+ | S | F | +---+-------+------+ | S | 46329 | 133 | changes +---+-------+------+ | F | 3 | 3535 | +---+-------+------+ Out of the 133 cases that flipped from failure to success the failed reasons were: 122 -> "Could not find route without excessive cost" 5 -> "We couldn't quite afford it" 5 -> "Amount *msat below minimum" 1 -> tripped an HTLC min check Changelog-None Signed-off-by: Lagrang3 <[email protected]>
1 parent 523fe3e commit 010a89e

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

plugins/askrene/refine.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,58 @@ static struct amount_msat remove_excess(struct flow **flows,
407407
return all_deliver;
408408
}
409409

410+
/* It increases the flows to meet the deliver target. It does not increase any
411+
* flow beyond the tolerance fraction. It doesn't increase any flow above its
412+
* max_deliverable value.
413+
* Returns the total delivery amount. */
414+
static struct amount_msat increase_flows(struct flow **flows,
415+
size_t **flows_index,
416+
struct amount_msat deliver,
417+
double tolerance,
418+
struct amount_msat *max_deliverable)
419+
{
420+
if (tal_count(flows) == 0)
421+
return AMOUNT_MSAT(0);
422+
423+
struct amount_msat all_deliver, defect;
424+
all_deliver = sum_all_deliver(flows, *flows_index);
425+
426+
/* early exit: target is already met */
427+
if (!amount_msat_sub(&defect, deliver, all_deliver) ||
428+
amount_msat_is_zero(defect))
429+
return all_deliver;
430+
431+
asort(*flows_index, tal_count(*flows_index), revcmp_flows, flows);
432+
433+
all_deliver = AMOUNT_MSAT(0);
434+
for (size_t i = 0;
435+
i < tal_count(*flows_index) && !amount_msat_is_zero(defect); i++) {
436+
const size_t index = (*flows_index)[i];
437+
struct flow *flow = flows[index];
438+
struct amount_msat can_add = defect, amt;
439+
440+
/* no more than tolerance */
441+
if (!amount_msat_scale(&amt, flow->delivers, tolerance))
442+
continue;
443+
else
444+
can_add = amount_msat_min(can_add, amt);
445+
446+
/* no more than max_deliverable */
447+
if (!amount_msat_sub(&amt, max_deliverable[index],
448+
flow->delivers))
449+
continue;
450+
else
451+
can_add = amount_msat_min(can_add, amt);
452+
453+
if (!amount_msat_add(&flow->delivers, flow->delivers,
454+
can_add) ||
455+
!amount_msat_sub(&defect, defect, can_add) ||
456+
!amount_msat_accumulate(&all_deliver, flow->delivers))
457+
abort();
458+
}
459+
return all_deliver;
460+
}
461+
410462
static void write_selected_flows(const tal_t *ctx, size_t *flows_index,
411463
struct flow ***flows)
412464
{
@@ -465,6 +517,10 @@ const char *refine_flows(const tal_t *ctx, struct route_query *rq,
465517
/* remove excess from MCF granularity if any */
466518
remove_excess(*flows, &flows_index, deliver);
467519

520+
/* increase flows if necessary to meet the target */
521+
increase_flows(*flows, &flows_index, deliver, /* tolerance = */ 0.02,
522+
max_deliverable);
523+
468524
/* detect htlc_min violations */
469525
for (size_t i = 0; i < tal_count(flows_index);) {
470526
size_t k = flows_index[i];

0 commit comments

Comments
 (0)