mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
routing: Refactor get_route into its own method
The JSON-RPC call `getroute` and the functionality to compute the actual route have been split so that we can reuse it independently of the JSON-interface. Since this is now a routing-only method I also moved it into `routing.[ch]` instead of `pay.c`.
This commit is contained in:
parent
9273b615ab
commit
73e65cac4d
44
daemon/pay.c
44
daemon/pay.c
@ -201,17 +201,11 @@ static void json_getroute(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
struct pubkey id;
|
||||
struct pubkey *first;
|
||||
jsmntok_t *idtok, *msatoshitok, *riskfactortok;
|
||||
struct json_result *response;
|
||||
int i;
|
||||
size_t i;
|
||||
u64 msatoshi;
|
||||
s64 fee;
|
||||
double riskfactor;
|
||||
struct node_connection **route;
|
||||
struct peer *peer;
|
||||
u64 *amounts, total_amount;
|
||||
unsigned int total_delay, *delays;
|
||||
|
||||
if (!json_get_params(buffer, params,
|
||||
"id", &idtok,
|
||||
@ -242,45 +236,19 @@ static void json_getroute(struct command *cmd,
|
||||
return;
|
||||
}
|
||||
|
||||
first = find_route(cmd, cmd->dstate->rstate, &cmd->dstate->id, &id, msatoshi,
|
||||
riskfactor, &fee, &route);
|
||||
if (first)
|
||||
peer = find_peer(cmd->dstate, first);
|
||||
if (!first || !peer) {
|
||||
struct route_hop *hops = get_route(cmd, cmd->dstate->rstate, &cmd->dstate->id, &id, msatoshi, riskfactor);
|
||||
|
||||
if (!hops) {
|
||||
command_fail(cmd, "no route found");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fees, delays need to be calculated backwards along route. */
|
||||
amounts = tal_arr(cmd, u64, tal_count(route)+1);
|
||||
delays = tal_arr(cmd, unsigned int, tal_count(route)+1);
|
||||
total_amount = msatoshi;
|
||||
|
||||
total_delay = 0;
|
||||
for (i = tal_count(route) - 1; i >= 0; i--) {
|
||||
amounts[i+1] = total_amount;
|
||||
total_amount += connection_fee(route[i], total_amount);
|
||||
|
||||
total_delay += route[i]->delay;
|
||||
if (total_delay < route[i]->min_blocks)
|
||||
total_delay = route[i]->min_blocks;
|
||||
delays[i+1] = total_delay;
|
||||
}
|
||||
/* We don't charge ourselves any fees. */
|
||||
amounts[0] = total_amount;
|
||||
/* We do require delay though. */
|
||||
total_delay += peer->nc->delay;
|
||||
if (total_delay < peer->nc->min_blocks)
|
||||
total_delay = peer->nc->min_blocks;
|
||||
delays[0] = total_delay;
|
||||
|
||||
response = new_json_result(cmd);
|
||||
json_object_start(response, NULL);
|
||||
json_array_start(response, "route");
|
||||
json_add_route(response, peer->id, amounts[0], delays[0]);
|
||||
for (i = 0; i < tal_count(route); i++)
|
||||
for (i = 0; i < tal_count(hops); i++)
|
||||
json_add_route(response,
|
||||
&route[i]->dst->id, amounts[i+1], delays[i+1]);
|
||||
&hops[i].nodeid, hops[i].amount, hops[i].delay);
|
||||
json_array_end(response);
|
||||
json_object_end(response);
|
||||
command_success(cmd, response);
|
||||
|
@ -356,18 +356,14 @@ static void bfg_one_edge(struct node *node, size_t edgenum, double riskfactor)
|
||||
}
|
||||
}
|
||||
|
||||
struct pubkey *find_route(const tal_t *ctx,
|
||||
struct routing_state *rstate,
|
||||
const struct pubkey *from,
|
||||
const struct pubkey *to,
|
||||
u64 msatoshi,
|
||||
double riskfactor,
|
||||
s64 *fee,
|
||||
struct node_connection ***route)
|
||||
struct node_connection *
|
||||
find_route(const tal_t *ctx, struct routing_state *rstate,
|
||||
const struct pubkey *from, const struct pubkey *to, u64 msatoshi,
|
||||
double riskfactor, s64 *fee, struct node_connection ***route)
|
||||
{
|
||||
struct node *n, *src, *dst;
|
||||
struct node_map_iter it;
|
||||
struct pubkey *first;
|
||||
struct node_connection *first_conn;
|
||||
int runs, i, best;
|
||||
|
||||
/* Note: we map backwards, since we know the amount of satoshi we want
|
||||
@ -434,11 +430,10 @@ struct pubkey *find_route(const tal_t *ctx,
|
||||
/* Save route from *next* hop (we return first hop as peer).
|
||||
* Note that we take our own fees into account for routing, even
|
||||
* though we don't pay them: it presumably effects preference. */
|
||||
first_conn = dst->bfg[best].prev;
|
||||
dst = dst->bfg[best].prev->dst;
|
||||
best--;
|
||||
|
||||
first = &dst->id;
|
||||
|
||||
*fee = dst->bfg[best].total - msatoshi;
|
||||
*route = tal_arr(ctx, struct node_connection *, best);
|
||||
for (i = 0, n = dst;
|
||||
@ -450,7 +445,7 @@ struct pubkey *find_route(const tal_t *ctx,
|
||||
|
||||
msatoshi += *fee;
|
||||
log_info(rstate->base_log, "find_route:");
|
||||
log_add_struct(rstate->base_log, "via %s", struct pubkey, first);
|
||||
log_add_struct(rstate->base_log, "via %s", struct pubkey, &first_conn->dst->id);
|
||||
/* If there are intermidiaries, dump them, and total fees. */
|
||||
if (best != 0) {
|
||||
for (i = 0; i < best; i++) {
|
||||
@ -465,7 +460,7 @@ struct pubkey *find_route(const tal_t *ctx,
|
||||
log_add(rstate->base_log, "=%"PRIi64"(%+"PRIi64")",
|
||||
(*route)[best-1]->dst->bfg[best-1].total, *fee);
|
||||
}
|
||||
return first;
|
||||
return first_conn;
|
||||
}
|
||||
|
||||
static bool get_slash_u32(const char **arg, u32 *v)
|
||||
@ -843,3 +838,48 @@ void handle_node_announcement(
|
||||
node->node_announcement = tal_steal(node, serialized);
|
||||
tal_free(tmpctx);
|
||||
}
|
||||
|
||||
struct route_hop *get_route(tal_t *ctx, struct routing_state *rstate,
|
||||
const struct pubkey *source,
|
||||
const struct pubkey *destination,
|
||||
const u32 msatoshi, double riskfactor)
|
||||
{
|
||||
struct node_connection **route;
|
||||
u64 total_amount;
|
||||
unsigned int total_delay;
|
||||
s64 fee;
|
||||
struct route_hop *hops;
|
||||
int i;
|
||||
struct node_connection *first_conn;
|
||||
|
||||
first_conn = find_route(ctx, rstate, source, destination, msatoshi,
|
||||
riskfactor, &fee, &route);
|
||||
|
||||
if (!first_conn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fees, delays need to be calculated backwards along route. */
|
||||
hops = tal_arr(ctx, struct route_hop, tal_count(route) + 1);
|
||||
total_amount = msatoshi;
|
||||
total_delay = 0;
|
||||
|
||||
for (i = tal_count(route) - 1; i >= 0; i--) {
|
||||
hops[i + 1].nodeid = route[i]->dst->id;
|
||||
hops[i + 1].amount = total_amount;
|
||||
total_amount += connection_fee(route[i], total_amount);
|
||||
|
||||
total_delay += route[i]->delay;
|
||||
if (total_delay < route[i]->min_blocks)
|
||||
total_delay = route[i]->min_blocks;
|
||||
hops[i + 1].delay = total_delay;
|
||||
}
|
||||
/* Backfill the first hop manually */
|
||||
hops[0].nodeid = first_conn->dst->id;
|
||||
/* We don't charge ourselves any fees. */
|
||||
hops[0].amount = total_amount;
|
||||
/* We do require delay though. */
|
||||
total_delay += first_conn->delay;
|
||||
hops[0].delay = total_delay;
|
||||
return hops;
|
||||
}
|
||||
|
@ -88,6 +88,12 @@ struct routing_state {
|
||||
struct broadcast_state *broadcasts;
|
||||
};
|
||||
|
||||
struct route_hop {
|
||||
struct pubkey nodeid;
|
||||
u32 amount;
|
||||
u32 delay;
|
||||
};
|
||||
|
||||
//FIXME(cdecker) The log will have to be replaced for the new subdaemon, keeping for now to keep changes small.
|
||||
struct routing_state *new_routing_state(const tal_t *ctx, struct log *base_log);
|
||||
|
||||
@ -139,14 +145,10 @@ struct node_connection *get_connection_by_scid(const struct routing_state *rstat
|
||||
void remove_connection(struct routing_state *rstate,
|
||||
const struct pubkey *src, const struct pubkey *dst);
|
||||
|
||||
struct pubkey *find_route(const tal_t *ctx,
|
||||
struct routing_state *rstate,
|
||||
const struct pubkey *from,
|
||||
const struct pubkey *to,
|
||||
u64 msatoshi,
|
||||
double riskfactor,
|
||||
s64 *fee,
|
||||
struct node_connection ***route);
|
||||
struct node_connection *
|
||||
find_route(const tal_t *ctx, struct routing_state *rstate,
|
||||
const struct pubkey *from, const struct pubkey *to, u64 msatoshi,
|
||||
double riskfactor, s64 *fee, struct node_connection ***route);
|
||||
|
||||
struct node_map *empty_node_map(const tal_t *ctx);
|
||||
|
||||
@ -167,4 +169,10 @@ void handle_channel_announcement(struct routing_state *rstate, const u8 *announc
|
||||
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len);
|
||||
void handle_node_announcement(struct routing_state *rstate, const u8 *node, size_t len);
|
||||
|
||||
/* Compute a route to a destination, for a given amount and riskfactor. */
|
||||
struct route_hop *get_route(tal_t *ctx, struct routing_state *rstate,
|
||||
const struct pubkey *source,
|
||||
const struct pubkey *destination,
|
||||
const u32 msatoshi, double riskfactor);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_ROUTING_H */
|
||||
|
Loading…
Reference in New Issue
Block a user