refactor: move exclude parsing to json_tok

This commit is contained in:
Andrew Toth
2021-11-04 17:06:01 -04:00
committed by Rusty Russell
parent 80661f920b
commit 384c359c79
4 changed files with 90 additions and 49 deletions

View File

@@ -10,6 +10,7 @@
#include <common/json_command.h>
#include <common/json_helpers.h>
#include <common/json_tok.h>
#include <common/route.h>
struct command_result *param_array(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
@@ -649,6 +650,64 @@ param_routehint_array(struct command *cmd, const char *name, const char *buffer,
return NULL;
}
struct command_result *param_route_exclusion(struct command *cmd,
const char *name, const char *buffer, const jsmntok_t *tok,
struct route_exclusion **re)
{
*re = tal(cmd, struct route_exclusion);
struct short_channel_id_dir *chan_id =
tal(tmpctx, struct short_channel_id_dir);
if (!short_channel_id_dir_from_str(buffer + tok->start,
tok->end - tok->start,
chan_id)) {
struct node_id *node_id = tal(tmpctx, struct node_id);
if (!json_to_node_id(buffer, tok, node_id))
return command_fail_badparam(cmd, "exclude",
buffer, tok,
"should be short_channel_id_dir or node_id");
(*re)->type = EXCLUDE_NODE;
(*re)->u.node_id = *node_id;
} else {
(*re)->type = EXCLUDE_CHANNEL;
(*re)->u.chan_id = *chan_id;
}
return NULL;
}
struct command_result *
param_route_exclusion_array(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
struct route_exclusion ***res)
{
size_t i;
const jsmntok_t *curr;
char *element_name;
struct command_result *err;
if (tok->type != JSMN_ARRAY) {
return command_fail(
cmd, JSONRPC2_INVALID_PARAMS,
"Exclude array %s (\"%s\") is not an array",
name, json_strdup(tmpctx, buffer, tok));
}
*res = tal_arr(cmd, struct route_exclusion *, 0);
json_for_each_arr(i, curr, tok) {
struct route_exclusion *element;
element_name = tal_fmt(cmd, "%s[%zu]", name, i);
err = param_route_exclusion(cmd, element_name, buffer, curr, &element);
if (err != NULL) {
return err;
}
tal_arr_expand(res, element);
tal_free(element_name);
}
return NULL;
}
struct command_result *param_lease_hex(struct command *cmd,
const char *name,
const char *buffer,

View File

@@ -18,6 +18,7 @@ struct channel_id;
struct command;
struct command_result;
struct json_escape;
struct route_exclusion;
struct sha256;
struct wally_psbt;
@@ -205,6 +206,15 @@ struct command_result *
param_routehint_array(struct command *cmd, const char *name, const char *buffer,
const jsmntok_t *tok, struct route_info ***ris);
struct command_result *param_route_exclusion(struct command *cmd,
const char *name, const char *buffer, const jsmntok_t *tok,
struct route_exclusion **re);
struct command_result *
param_route_exclusion_array(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
struct route_exclusion ***res);
/**
* Parse a 'compact-lease' (serialized lease_rates) back into lease_rates
*/

View File

@@ -74,4 +74,22 @@ struct route_hop *route_from_dijkstra(const tal_t *ctx,
const struct gossmap_node *src,
struct amount_msat final_amount,
u32 final_cltv);
/*
* Manually exlude nodes or channels from a route.
* Used with `getroute` and `pay` commands
*/
enum route_exclusion_type {
EXCLUDE_CHANNEL = 1,
EXCLUDE_NODE = 2
};
struct route_exclusion {
enum route_exclusion_type type;
union {
struct short_channel_id_dir chan_id;
struct node_id node_id;
} u;
};
#endif /* LIGHTNING_COMMON_ROUTE_H */

View File

@@ -30,19 +30,6 @@ static struct gossmap *get_gossmap(void)
/* Convenience global since route_score_fuzz doesn't take args. 0 to 1. */
static double fuzz;
enum exclude_entry_type {
EXCLUDE_CHANNEL = 1,
EXCLUDE_NODE = 2
};
struct exclude_entry {
enum exclude_entry_type type;
union {
struct short_channel_id_dir chan_id;
struct node_id node_id;
} u;
};
/* Prioritize costs over distance, but with fuzz. Cost must be
* the same when the same channel queried, so we base it on that. */
static u64 route_score_fuzz(u32 distance,
@@ -68,7 +55,7 @@ static bool can_carry(const struct gossmap *map,
const struct gossmap_chan *c,
int dir,
struct amount_msat amount,
const struct exclude_entry **excludes)
struct route_exclusion **excludes)
{
struct node_id dstid;
@@ -143,12 +130,11 @@ static struct command_result *json_getroute(struct command *cmd,
{
struct node_id *destination;
struct node_id *source;
const jsmntok_t *excludetok;
struct amount_msat *msat;
u32 *cltv;
/* risk factor 12.345% -> riskfactor_millionths = 12345000 */
u64 *riskfactor_millionths, *fuzz_millionths;
const struct exclude_entry **excluded;
struct route_exclusion **excluded;
u32 *max_hops;
const struct dijkstra *dij;
struct route_hop *route;
@@ -164,7 +150,7 @@ static struct command_result *json_getroute(struct command *cmd,
p_opt_def("fromid", param_node_id, &source, local_id),
p_opt_def("fuzzpercent", param_millionths, &fuzz_millionths,
5000000),
p_opt("exclude", param_array, &excludetok),
p_opt("exclude", param_route_exclusion_array, &excluded),
p_opt_def("maxhops", param_number, &max_hops, ROUTING_MAX_HOPS),
NULL))
return command_param_failed();
@@ -176,38 +162,6 @@ static struct command_result *json_getroute(struct command *cmd,
buffer, params,
"should be <= 100");
if (excludetok) {
const jsmntok_t *t;
size_t i;
excluded = tal_arr(cmd, const struct exclude_entry *, 0);
json_for_each_arr(i, t, excludetok) {
struct exclude_entry *entry = tal(excluded, struct exclude_entry);
struct short_channel_id_dir *chan_id = tal(tmpctx, struct short_channel_id_dir);
if (!short_channel_id_dir_from_str(buffer + t->start,
t->end - t->start,
chan_id)) {
struct node_id *node_id = tal(tmpctx, struct node_id);
if (!json_to_node_id(buffer, t, node_id))
return command_fail_badparam(cmd, "exclude",
buffer, t,
"should be short_channel_id or node_id");
entry->type = EXCLUDE_NODE;
entry->u.node_id = *node_id;
} else {
entry->type = EXCLUDE_CHANNEL;
entry->u.chan_id = *chan_id;
}
tal_arr_expand(&excluded, entry);
}
} else {
excluded = NULL;
}
gossmap = get_gossmap();
src = gossmap_find_node(gossmap, source);
if (!src)