diff --git a/daemon/pay.c b/daemon/pay.c index a270d08c9..dd6924be6 100644 --- a/daemon/pay.c +++ b/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); diff --git a/daemon/routing.c b/daemon/routing.c index fefdd8fab..e8bd7f89f 100644 --- a/daemon/routing.c +++ b/daemon/routing.c @@ -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; +} diff --git a/daemon/routing.h b/daemon/routing.h index 1e192bb04..38484fb57 100644 --- a/daemon/routing.h +++ b/daemon/routing.h @@ -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 */