Files
palladum-lightning/common/route.c
Rusty Russell 6e5cb299dd global: remove unnecessary includes from C files.
Basically, `devtools/reduce-includes.sh */*.c`.

Build time from make clean (RUST=0) (includes building external libs):

Before:
	real    0m38.944000-40.416000(40.1131+/-0.4)s
	user    3m6.790000-17.159000(15.0571+/-2.8)s
	sys     0m35.304000-37.336000(36.8942+/-0.57)s
After:
	real    0m37.872000-39.974000(39.5466+/-0.59)s
	user    3m1.211000-14.968000(12.4556+/-3.9)s
	sys     0m35.008000-36.830000(36.4143+/-0.5)s

Build time after touch config.vars (RUST=0):

Before:
	real    0m19.831000-21.862000(21.5528+/-0.58)s
	user    2m15.361000-30.731000(28.4798+/-4.4)s
	sys     0m21.056000-22.339000(22.0346+/-0.35)s

After:
	real    0m18.384000-21.307000(20.8605+/-0.92)s
	user    2m5.585000-26.843000(23.6017+/-6.7)s
	sys     0m19.650000-22.003000(21.4943+/-0.69)s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30

135 lines
3.7 KiB
C

#include "config.h"
#include <assert.h>
#include <common/dijkstra.h>
#include <common/gossmap.h>
#include <common/route.h>
bool route_can_carry_even_disabled(const struct gossmap *map,
const struct gossmap_chan *c,
int dir,
struct amount_msat amount,
void *unused)
{
if (!gossmap_chan_set(c, dir))
return false;
/* Amount 0 is a special "ignore min" probe case */
if (!amount_msat_is_zero(amount)
&& !gossmap_chan_has_capacity(c, dir, amount))
return false;
return true;
}
/* Generally only one side gets marked disabled, but it's disabled. */
bool route_can_carry(const struct gossmap *map,
const struct gossmap_chan *c,
int dir,
struct amount_msat amount,
void *arg)
{
if (!c->half[dir].enabled)
return false;
return route_can_carry_even_disabled(map, c, dir, amount, arg);
}
/* Squeeze total costs into a u32 */
static u32 costs_to_score(struct amount_msat fee,
struct amount_msat risk)
{
u64 costs = fee.millisatoshis + risk.millisatoshis; /* Raw: score */
if (costs > 0xFFFFFFFF)
costs = 0xFFFFFFFF;
return costs;
}
/* Prioritize distance over costs */
u64 route_score_shorter(struct amount_msat fee,
struct amount_msat risk,
struct amount_msat total UNUSED,
int dir UNUSED,
const struct gossmap_chan *c UNUSED)
{
return costs_to_score(fee, risk) + ((u64)1 << 32);
}
/* Prioritize costs over distance */
u64 route_score_cheaper(struct amount_msat fee,
struct amount_msat risk,
struct amount_msat total UNUSED,
int dir UNUSED,
const struct gossmap_chan *c UNUSED)
{
return ((u64)costs_to_score(fee, risk) << 32) + 1;
}
/* Recursive version: return false if we can't get there.
*
* amount and cltv are updated, and reflect the amount we
* and delay would have to put into the first channel (usually
* ignored, since we don't pay for our own channels!).
*/
static bool dijkstra_to_hops(struct route_hop **hops,
const struct gossmap *gossmap,
const struct dijkstra *dij,
const struct gossmap_node *cur,
struct amount_msat *amount,
u32 *cltv)
{
u32 curidx = gossmap_node_idx(gossmap, cur);
u32 dist = dijkstra_distance(dij, curidx);
struct gossmap_chan *c;
const struct gossmap_node *next;
size_t num_hops = tal_count(*hops);
const struct half_chan *h;
struct amount_msat total_msat;
if (dist == 0)
return true;
if (dist == UINT_MAX)
return false;
tal_resize(hops, num_hops + 1);
/* OK, populate other fields. */
c = dijkstra_best_chan(dij, curidx);
assert(c->half[0].nodeidx == curidx || c->half[1].nodeidx == curidx);
(*hops)[num_hops].direction = c->half[0].nodeidx == curidx ? 0 : 1;
(*hops)[num_hops].scid = gossmap_chan_scid(gossmap, c);
/* Find other end of channel. */
next = gossmap_nth_node(gossmap, c, !(*hops)[num_hops].direction);
gossmap_node_get_id(gossmap, next, &(*hops)[num_hops].node_id);
if (!dijkstra_to_hops(hops, gossmap, dij, next, amount, cltv))
return false;
total_msat = gossmap_chan_get_capacity(gossmap, c);
(*hops)[num_hops].capacity = total_msat;
(*hops)[num_hops].amount = *amount;
(*hops)[num_hops].delay = *cltv;
h = &c->half[(*hops)[num_hops].direction];
if (!amount_msat_add_fee(amount, h->base_fee, h->proportional_fee))
/* Shouldn't happen, since we said it would route,
* amounts must be sane. */
abort();
*cltv += h->delay;
return true;
}
struct route_hop *route_from_dijkstra(const tal_t *ctx,
const struct gossmap *map,
const struct dijkstra *dij,
const struct gossmap_node *src,
struct amount_msat final_amount,
u32 final_cltv)
{
struct route_hop *hops = tal_arr(ctx, struct route_hop, 0);
if (!dijkstra_to_hops(&hops, map, dij, src, &final_amount, &final_cltv))
return tal_free(hops);
return hops;
}