mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-23 15:00:34 +01:00
111 lines
3.2 KiB
C
111 lines
3.2 KiB
C
#include "config.h"
|
|
#include <plugins/renepay/route.h>
|
|
|
|
struct route *new_route(const tal_t *ctx, u32 groupid,
|
|
u32 partid, struct sha256 payment_hash,
|
|
struct amount_msat amount,
|
|
struct amount_msat amount_sent)
|
|
{
|
|
struct route *route = tal(ctx, struct route);
|
|
route->key.partid = partid;
|
|
route->key.groupid = groupid;
|
|
route->key.payment_hash = payment_hash;
|
|
|
|
route->final_error = LIGHTNINGD;
|
|
route->final_msg = NULL;
|
|
route->hops = NULL;
|
|
route->success_prob = 0.0;
|
|
route->result = NULL;
|
|
|
|
route->amount = amount;
|
|
route->amount_sent = amount_sent;
|
|
return route;
|
|
}
|
|
|
|
/* Construct a route from a flow.
|
|
*
|
|
* @ctx: allocator
|
|
* @groupid, @partid, @payment_hash: unique identification keys for this route
|
|
* @final_cltv: final delay required by the payment
|
|
* @gossmap: global gossmap
|
|
* @flow: the flow to convert to route */
|
|
struct route *flow_to_route(const tal_t *ctx,
|
|
u32 groupid, u32 partid, struct sha256 payment_hash,
|
|
u32 final_cltv, struct gossmap *gossmap,
|
|
struct flow *flow)
|
|
{
|
|
struct route *route =
|
|
new_route(ctx, groupid, partid, payment_hash,
|
|
AMOUNT_MSAT(0), AMOUNT_MSAT(0));
|
|
|
|
size_t pathlen = tal_count(flow->path);
|
|
route->hops = tal_arr(route, struct route_hop, pathlen);
|
|
|
|
for (size_t i = 0; i < pathlen; i++) {
|
|
struct route_hop *hop = &route->hops[i];
|
|
struct gossmap_node *n;
|
|
n = gossmap_nth_node(gossmap, flow->path[i], !flow->dirs[i]);
|
|
gossmap_node_get_id(gossmap, n, &hop->node_id);
|
|
|
|
hop->scid = gossmap_chan_scid(gossmap, flow->path[i]);
|
|
hop->direction = flow->dirs[i];
|
|
}
|
|
|
|
/* Calculate cumulative delays (backwards) */
|
|
route->hops[pathlen - 1].delay = final_cltv;
|
|
route->hops[pathlen - 1].amount = flow->amount;
|
|
|
|
for (int i = (int)pathlen - 2; i >= 0; i--) {
|
|
const struct half_chan *h = flow_edge(flow, i + 1);
|
|
|
|
route->hops[i].delay = route->hops[i + 1].delay + h->delay;
|
|
route->hops[i].amount = route->hops[i + 1].amount;
|
|
if (!amount_msat_add_fee(&route->hops[i].amount, h->base_fee,
|
|
h->proportional_fee))
|
|
goto function_fail;
|
|
}
|
|
route->success_prob = flow->success_prob;
|
|
route->amount = route->hops[pathlen - 1].amount;
|
|
route->amount_sent = route->hops[0].amount;
|
|
return route;
|
|
|
|
function_fail:
|
|
return tal_free(route);
|
|
}
|
|
|
|
struct route **flows_to_routes(const tal_t *ctx,
|
|
u32 groupid, u32 partid,
|
|
struct sha256 payment_hash, u32 final_cltv,
|
|
struct gossmap *gossmap, struct flow **flows)
|
|
{
|
|
assert(gossmap);
|
|
assert(flows);
|
|
const size_t N = tal_count(flows);
|
|
struct route **routes = tal_arr(ctx, struct route *, N);
|
|
for (size_t i = 0; i < N; i++) {
|
|
routes[i] =
|
|
flow_to_route(routes, groupid, partid++,
|
|
payment_hash, final_cltv, gossmap, flows[i]);
|
|
if (!routes[i])
|
|
goto function_fail;
|
|
}
|
|
return routes;
|
|
|
|
function_fail:
|
|
return tal_free(routes);
|
|
}
|
|
|
|
const char *fmt_route_path(const tal_t *ctx, const struct route *route)
|
|
{
|
|
tal_t *this_ctx = tal(ctx, tal_t);
|
|
char *s = tal_strdup(ctx, "");
|
|
const size_t pathlen = tal_count(route->hops);
|
|
for (size_t i = 0; i < pathlen; i++) {
|
|
const struct short_channel_id_dir scidd =
|
|
hop_to_scidd(&route->hops[i]);
|
|
tal_append_fmt(&s, "%s%s", i ? "->" : "",
|
|
fmt_short_channel_id(this_ctx, scidd.scid));
|
|
}
|
|
tal_free(this_ctx);
|
|
return s;
|
|
}
|