mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
common/route: route_from_dijkstra returns route_hop array.
This is what (most) callers actually want, so unify it into one place. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/dijkstra.h>
|
||||
#include <common/features.h>
|
||||
#include <common/gossmap.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/pseudorand.h>
|
||||
#include <common/random_select.h>
|
||||
#include <common/route.h>
|
||||
@@ -64,31 +64,82 @@ u64 route_score_cheaper(u32 distance,
|
||||
return ((u64)costs_to_score(cost, risk) << 32) + distance;
|
||||
}
|
||||
|
||||
struct route **route_from_dijkstra(const tal_t *ctx,
|
||||
const struct gossmap *map,
|
||||
const struct dijkstra *dij,
|
||||
const struct gossmap_node *cur)
|
||||
/* 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)
|
||||
{
|
||||
struct route **path = tal_arr(ctx, struct route *, 0);
|
||||
u32 curidx = gossmap_node_idx(map, cur);
|
||||
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;
|
||||
|
||||
while (dijkstra_distance(dij, curidx) != 0) {
|
||||
struct route *r;
|
||||
if (dist == 0)
|
||||
return true;
|
||||
|
||||
if (dijkstra_distance(dij, curidx) == UINT_MAX)
|
||||
return tal_free(path);
|
||||
if (dist == UINT_MAX)
|
||||
return false;
|
||||
|
||||
r = tal(path, struct route);
|
||||
r->c = dijkstra_best_chan(dij, curidx);
|
||||
if (r->c->half[0].nodeidx == curidx) {
|
||||
r->dir = 0;
|
||||
} else {
|
||||
assert(r->c->half[1].nodeidx == curidx);
|
||||
r->dir = 1;
|
||||
}
|
||||
tal_arr_expand(&path, r);
|
||||
cur = gossmap_nth_node(map, r->c, !r->dir);
|
||||
curidx = gossmap_node_idx(map, cur);
|
||||
tal_resize(hops, num_hops + 1);
|
||||
|
||||
/* OK, populate other fields. */
|
||||
c = dijkstra_best_chan(dij, curidx);
|
||||
if (c->half[0].nodeidx == curidx) {
|
||||
(*hops)[num_hops].direction = 0;
|
||||
} else {
|
||||
assert(c->half[1].nodeidx == curidx);
|
||||
(*hops)[num_hops].direction = 1;
|
||||
}
|
||||
return path;
|
||||
(*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 (gossmap_node_get_feature(gossmap, next, OPT_VAR_ONION) != -1)
|
||||
(*hops)[num_hops].style = ROUTE_HOP_TLV;
|
||||
else
|
||||
(*hops)[num_hops].style = ROUTE_HOP_LEGACY;
|
||||
|
||||
/* These are (ab)used by others. */
|
||||
(*hops)[num_hops].blinding = NULL;
|
||||
(*hops)[num_hops].enctlv = NULL;
|
||||
|
||||
if (!dijkstra_to_hops(hops, gossmap, dij, next, amount, cltv))
|
||||
return false;
|
||||
|
||||
(*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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user