MCPcopy Create free account
hub / github.com/ElementsProject/lightning / increase_flows

Function increase_flows

plugins/askrene/child/refine.c:447–533  ·  view source on GitHub ↗

It increases the flows to meet the deliver target. It does not increase any * flow beyond the tolerance fraction (unless negative). * Returns true if it managed to increase total amount to "deliver". */

Source from the content-addressed store, hash-verified

445 * flow beyond the tolerance fraction (unless negative).
446 * Returns true if it managed to increase total amount to "deliver". */
447static bool increase_flows(const struct route_query *rq,
448 struct flow **flows,
449 struct amount_msat deliver,
450 double tolerance)
451{
452 const tal_t *working_ctx = tal(NULL, tal_t);
453 struct amount_msat shortage, *ceiling;
454
455 /* Record max we can deliver for each flow, so we don't exceed it */
456 ceiling = tal_arr(working_ctx, struct amount_msat, tal_count(flows));
457 for (size_t i = 0; i < tal_count(flows); i++) {
458 if (tolerance < 0)
459 ceiling[i] = deliver;
460 else if (!amount_msat_scale(&ceiling[i], flows[i]->delivers, 1.0 + tolerance))
461 abort();
462 }
463
464 /* This is naive, but since flows can overlap, increasing one
465 * can alter the remaining capacity of the others! */
466 while (flows_short(flows, deliver, &shortage)) {
467 size_t best_flownum = 0;
468 struct amount_msat best_remaining = AMOUNT_MSAT(0);
469 struct reserve_hop **reservations;
470 struct amount_msat addition;
471
472 /* Because flows can interact, we reserve them all, removing one at a time. */
473 reservations = tal_arr(NULL, struct reserve_hop *, tal_count(flows));
474 for (size_t i = 0; i < tal_count(flows); i++) {
475 reservations[i] = new_reservations(reservations, rq);
476 create_flow_reservations(rq, &reservations[i], flows[i]);
477 }
478
479 /* Find flow with most excess capacity. */
480 for (size_t i = 0; i < tal_count(flows); i++) {
481 struct amount_msat capacity, remaining;
482
483 /* flow_max_deliverable considers reservations *and*
484 * htlc_max. So remove this reservation, to get the
485 * real maximum for one flow, then replace it. */
486 tal_free(reservations[i]);
487 capacity = flow_max_deliverable(rq, flows[i]);
488 reservations[i] = new_reservations(reservations, rq);
489 create_flow_reservations(rq, &reservations[i], flows[i]);
490
491 /* Don't go above our tolerance */
492 if (amount_msat_greater(capacity, ceiling[i]))
493 capacity = ceiling[i];
494
495 /* We've had a report that this subtract can fail:
496 * that implies we've pushed a flow past its estimated
497 * capacity. That shouldn't happen, but if it does,
498 * we don't crash */
499 if (!amount_msat_sub(&remaining, capacity, flows[i]->delivers)) {
500 child_log(rq, LOG_BROKEN,
501 "%s: flow %s delivers %s which is more than the path's capacity %s", __func__,
502 fmt_flow_full(tmpctx, rq, flows[i]),
503 fmt_amount_msat(tmpctx, flows[i]->delivers),
504 fmt_amount_msat(tmpctx, capacity));

Callers 2

refine_flowsFunction · 0.85
reduce_num_flowsFunction · 0.85

Calls 15

amount_msat_scaleFunction · 0.85
abortFunction · 0.85
flows_shortFunction · 0.85
new_reservationsFunction · 0.85
create_flow_reservationsFunction · 0.85
tal_freeFunction · 0.85
flow_max_deliverableFunction · 0.85
amount_msat_greaterFunction · 0.85
amount_msat_subFunction · 0.85
child_logFunction · 0.85
fmt_flow_fullFunction · 0.85
amount_msat_less_satFunction · 0.85

Tested by

no test coverage detected