Skip to content

Commit d0605ac

Browse files
committed
sendpay: do route parsing inside parameter parsing.
This makes "check" more accurate, and also simplifies the code a little. Signed-off-by: Rusty Russell <[email protected]>
1 parent 13fbce9 commit d0605ac

File tree

1 file changed

+51
-41
lines changed

1 file changed

+51
-41
lines changed

lightningd/pay.c

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,38 +1195,21 @@ static struct command_result *param_route_hop_style(struct command *cmd,
11951195
json_tok_full(buffer, tok));
11961196
}
11971197

1198-
static struct command_result *json_sendpay(struct command *cmd,
1199-
const char *buffer,
1200-
const jsmntok_t *obj UNNEEDED,
1201-
const jsmntok_t *params)
1198+
static struct command_result *param_route_hops(struct command *cmd,
1199+
const char *name,
1200+
const char *buffer,
1201+
const jsmntok_t *tok,
1202+
struct route_hop **hops)
12021203
{
1203-
const jsmntok_t *routetok;
1204-
const jsmntok_t *t;
12051204
size_t i;
1206-
struct sha256 *rhash;
1207-
struct route_hop *route;
1208-
struct amount_msat *msat;
1209-
const char *b11str, *label;
1210-
u64 *partid;
1211-
struct secret *payment_secret;
1212-
1213-
/* For generating help, give new-style. */
1214-
if (!param(cmd, buffer, params,
1215-
p_req("route", param_array, &routetok),
1216-
p_req("payment_hash", param_sha256, &rhash),
1217-
p_opt("label", param_escaped_string, &label),
1218-
p_opt("msatoshi", param_msat, &msat),
1219-
p_opt("bolt11", param_string, &b11str),
1220-
p_opt("payment_secret", param_secret, &payment_secret),
1221-
p_opt_def("partid", param_u64, &partid, 0),
1222-
NULL))
1223-
return command_param_failed();
1205+
const jsmntok_t *t;
12241206

1225-
if (routetok->size == 0)
1226-
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
1207+
if (tok->type != JSMN_ARRAY || tok->size == 0)
1208+
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
1209+
"%s must be an (non-empty) array", name);
12271210

1228-
route = tal_arr(cmd, struct route_hop, routetok->size);
1229-
json_for_each_arr(i, t, routetok) {
1211+
*hops = tal_arr(cmd, struct route_hop, tok->size);
1212+
json_for_each_arr(i, t, tok) {
12301213
struct amount_msat *msat, *amount_msat;
12311214
struct node_id *id;
12321215
struct short_channel_id *channel;
@@ -1249,16 +1232,16 @@ static struct command_result *json_sendpay(struct command *cmd,
12491232

12501233
if (!msat && !amount_msat)
12511234
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
1252-
"route[%zi]: must have msatoshi"
1253-
" or amount_msat", i);
1235+
"%s[%zi]: must have msatoshi"
1236+
" or amount_msat", name, i);
12541237
if (!id || !channel || !delay)
12551238
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
1256-
"route[%zi]: must have id, channel"
1257-
" and delay", i);
1239+
"%s[%zi]: must have id, channel"
1240+
" and delay", name, i);
12581241
if (msat && amount_msat && !amount_msat_eq(*msat, *amount_msat))
12591242
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
1260-
"route[%zi]: msatoshi %s != amount_msat %s",
1261-
i,
1243+
"%s[%zi]: msatoshi %s != amount_msat %s",
1244+
name, i,
12621245
type_to_string(tmpctx,
12631246
struct amount_msat,
12641247
msat),
@@ -1268,20 +1251,47 @@ static struct command_result *json_sendpay(struct command *cmd,
12681251
if (!msat)
12691252
msat = amount_msat;
12701253

1271-
route[i].amount = *msat;
1272-
route[i].nodeid = *id;
1273-
route[i].delay = *delay;
1274-
route[i].channel_id = *channel;
1275-
route[i].style = *style;
1254+
(*hops)[i].amount = *msat;
1255+
(*hops)[i].nodeid = *id;
1256+
(*hops)[i].delay = *delay;
1257+
(*hops)[i].channel_id = *channel;
1258+
(*hops)[i].style = *style;
12761259
/* FIXME: Actually ignored by sending code! */
1277-
route[i].direction = direction ? *direction : 0;
1260+
(*hops)[i].direction = direction ? *direction : 0;
12781261
}
12791262

1263+
return NULL;
1264+
}
1265+
1266+
static struct command_result *json_sendpay(struct command *cmd,
1267+
const char *buffer,
1268+
const jsmntok_t *obj UNNEEDED,
1269+
const jsmntok_t *params)
1270+
{
1271+
struct sha256 *rhash;
1272+
struct route_hop *route;
1273+
struct amount_msat *msat;
1274+
const char *b11str, *label;
1275+
u64 *partid;
1276+
struct secret *payment_secret;
1277+
1278+
/* For generating help, give new-style. */
1279+
if (!param(cmd, buffer, params,
1280+
p_req("route", param_route_hops, &route),
1281+
p_req("payment_hash", param_sha256, &rhash),
1282+
p_opt("label", param_escaped_string, &label),
1283+
p_opt("msatoshi", param_msat, &msat),
1284+
p_opt("bolt11", param_string, &b11str),
1285+
p_opt("payment_secret", param_secret, &payment_secret),
1286+
p_opt_def("partid", param_u64, &partid, 0),
1287+
NULL))
1288+
return command_param_failed();
1289+
12801290
if (*partid && !msat)
12811291
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
12821292
"Must specify msatoshi with partid");
12831293

1284-
const struct amount_msat final_amount = route[routetok->size-1].amount;
1294+
const struct amount_msat final_amount = route[tal_count(route)-1].amount;
12851295

12861296
if (msat && !*partid && !amount_msat_eq(*msat, final_amount))
12871297
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,

0 commit comments

Comments
 (0)