Loop over the channels in the path and disable the one with the least * permiting amount based on htlc_max and known max liquidity. */
| 314 | /* Loop over the channels in the path and disable the one with the least |
| 315 | * permiting amount based on htlc_max and known max liquidity. */ |
| 316 | static const char *remove_bottleneck(const tal_t *ctx, struct route_query *rq, |
| 317 | const struct flow *flow) |
| 318 | { |
| 319 | const char *error_message = NULL; |
| 320 | struct amount_msat min = AMOUNT_MSAT(-1); |
| 321 | u32 min_pos = UINT32_MAX; |
| 322 | struct amount_msat htlc_max, known_max, unused; |
| 323 | struct short_channel_id_dir scidd; |
| 324 | size_t idx; |
| 325 | for (u32 i = 0; i < tal_count(flow->path); i++) { |
| 326 | htlc_max = get_chan_htlc_max(rq, flow->path[i], flow->dirs[i]); |
| 327 | get_constraints(rq, flow->path[i], flow->dirs[i], &unused, |
| 328 | &known_max); |
| 329 | known_max = amount_msat_min(known_max, htlc_max); |
| 330 | if (amount_msat_less(known_max, min)) { |
| 331 | min = known_max; |
| 332 | min_pos = i; |
| 333 | } |
| 334 | } |
| 335 | if (min_pos >= tal_count(flow->path)) { |
| 336 | error_message = child_log( |
| 337 | ctx, LOG_BROKEN, |
| 338 | "%s: failed to find any bottleneck, flow has no hops? %s", |
| 339 | __func__, fmt_flow_full(tmpctx, rq, flow)); |
| 340 | } else { |
| 341 | get_scidd(rq->gossmap, flow, min_pos, &scidd); |
| 342 | child_log(tmpctx, LOG_INFORM, |
| 343 | "Disabling bottleneck channel %s with " |
| 344 | "htlc_max/known_max at %s", |
| 345 | fmt_short_channel_id_dir(ctx, &scidd), |
| 346 | fmt_amount_msat(ctx, min)); |
| 347 | idx = flow->dirs[min_pos] + |
| 348 | 2 * gossmap_chan_idx(rq->gossmap, flow->path[min_pos]); |
| 349 | bitmap_set_bit(rq->disabled_chans, idx); |
| 350 | } |
| 351 | return error_message; |
| 352 | } |
| 353 | |
| 354 | static struct amount_msat sum_all_deliver(struct flow **flows) |
| 355 | { |
no test coverage detected