askrene: don't crash if refining flow which has capacity greaater than max it should have.

```
1767724611265   2026-01-06T18:36:51.265Z                plugins/libplugin.c:1073
1767724611265   2026-01-06T18:36:51.265Z        0x55fc0c1428ac handle_rpc_reply
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/askrene.c:801
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c13174c listpeerchannels_done
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/askrene.c:669
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c130f55 do_getroutes
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/mcf.c:1636
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c138bd7 default_routes
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/mcf.c:1415
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c1382ec linear_routes
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/refine.c:510
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c13b110 refine_flows
1767724611264   2026-01-06T18:36:51.264Z                plugins/askrene/refine.c:449
1767724611264   2026-01-06T18:36:51.264Z        0x55fc0c13ac9f increase_flows
1767724611264   2026-01-06T18:36:51.264Z                abort+0xde:0
```

Fixes: #8823
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: plugins: `askrene` can crash on a corner case in increase_flows.
This commit is contained in:
Rusty Russell
2026-01-14 13:51:54 +10:30
parent b0f8077e32
commit 35e703bfe1

View File

@@ -445,8 +445,18 @@ static bool increase_flows(const struct route_query *rq,
if (amount_msat_greater(capacity, ceiling[i]))
capacity = ceiling[i];
if (!amount_msat_sub(&remaining, capacity, flows[i]->delivers))
abort();
/* We've had a report that this subtract can fail:
* that implies we've pushed a flow past its estimated
* capacity. That shouldn't happen, but if it does,
* we don't crash */
if (!amount_msat_sub(&remaining, capacity, flows[i]->delivers)) {
rq_log(rq, rq, LOG_BROKEN,
"%s: flow %s delivers %s which is more than the path's capacity %s", __func__,
fmt_flow_full(tmpctx, rq, flows[i]),
fmt_amount_msat(tmpctx, flows[i]->delivers),
fmt_amount_msat(tmpctx, capacity));
continue;
}
if (amount_msat_greater(remaining, best_remaining)) {
best_flownum = i;
best_remaining = remaining;