| 96 | }; |
| 97 | |
| 98 | static struct command_result *try_route(struct command *cmd, |
| 99 | struct gossmap *gossmap, |
| 100 | struct getroute_info *info) |
| 101 | { |
| 102 | const struct dijkstra *dij; |
| 103 | struct route_hop *route; |
| 104 | struct gossmap_node *src, *dst; |
| 105 | struct json_stream *js; |
| 106 | src = gossmap_find_node(gossmap, info->source); |
| 107 | if (!src) |
| 108 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 109 | "%s: unknown source node_id (no public channels?)", |
| 110 | fmt_node_id(tmpctx, info->source)); |
| 111 | |
| 112 | dst = gossmap_find_node(gossmap, info->destination); |
| 113 | if (!dst) |
| 114 | return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
| 115 | "%s: unknown destination node_id (no public channels?)", |
| 116 | fmt_node_id(tmpctx, info->destination)); |
| 117 | |
| 118 | dij = dijkstra(tmpctx, gossmap, dst, *info->msat, |
| 119 | *info->riskfactor_millionths / 1000000.0, |
| 120 | can_carry, route_score_cheaper, info->excluded); |
| 121 | route = route_from_dijkstra(dij, gossmap, dij, src, |
| 122 | *info->msat, *info->cltv); |
| 123 | if (!route) |
| 124 | return command_fail(cmd, PAY_ROUTE_NOT_FOUND, "Could not find a route"); |
| 125 | |
| 126 | /* If it's too far, fall back to using shortest path. */ |
| 127 | if (tal_count(route) > *info->max_hops) { |
| 128 | plugin_notify_message(cmd, LOG_INFORM, "Cheapest route %zu hops: seeking shorter", |
| 129 | tal_count(route)); |
| 130 | dij = dijkstra(tmpctx, gossmap, dst, *info->msat, |
| 131 | *info->riskfactor_millionths / 1000000.0, |
| 132 | can_carry, route_score_shorter, info->excluded); |
| 133 | route = route_from_dijkstra(dij, gossmap, dij, src, *info->msat, *info->cltv); |
| 134 | if (tal_count(route) > *info->max_hops) |
| 135 | return command_fail(cmd, PAY_ROUTE_NOT_FOUND, "Shortest route was %zu", |
| 136 | tal_count(route)); |
| 137 | } |
| 138 | |
| 139 | js = jsonrpc_stream_success(cmd); |
| 140 | json_array_start(js, "route"); |
| 141 | for (size_t i = 0; i < tal_count(route); i++) { |
| 142 | json_add_route_hop(js, NULL, &route[i]); |
| 143 | } |
| 144 | json_array_end(js); |
| 145 | |
| 146 | return command_finished(cmd, js); |
| 147 | } |
| 148 | |
| 149 | static struct command_result * |
| 150 | listpeerchannels_getroute_done(struct command *cmd, |
no test coverage detected