diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 9baaa7827..a15343cdf 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -5,7 +5,6 @@ #include "bitcoind.h" #include "chaintopology.h" #include "jsonrpc.h" -#include "jsonrpc_errors.h" #include "lightningd.h" #include "log.h" #include "watch.h" @@ -20,6 +19,7 @@ #include #include #include +#include /* Mutual recursion via timer. */ static void try_extend_tip(struct chain_topology *topo); @@ -589,18 +589,9 @@ u32 get_feerate(const struct chain_topology *topo, enum feerate feerate) static void json_dev_setfees(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *ratetok[NUM_FEERATES]; struct chain_topology *topo = cmd->ld->topology; struct json_result *response; - if (!json_get_params(cmd, buffer, params, - "?immediate", &ratetok[FEERATE_IMMEDIATE], - "?normal", &ratetok[FEERATE_NORMAL], - "?slow", &ratetok[FEERATE_SLOW], - NULL)) { - return; - } - if (!topo->dev_override_fee_rate) { u32 fees[NUM_FEERATES]; for (size_t i = 0; i < ARRAY_SIZE(fees); i++) @@ -608,18 +599,20 @@ static void json_dev_setfees(struct command *cmd, topo->dev_override_fee_rate = tal_dup_arr(topo, u32, fees, ARRAY_SIZE(fees), 0); } - for (size_t i = 0; i < NUM_FEERATES; i++) { - if (!ratetok[i]) - continue; - if (!json_tok_number(buffer, ratetok[i], - &topo->dev_override_fee_rate[i])) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid feerate %.*s", - ratetok[i]->end - ratetok[i]->start, - buffer + ratetok[i]->start); - return; - } - } + + if (!param(cmd, buffer, params, + p_opt_def("immediate", json_tok_number, + &topo->dev_override_fee_rate[FEERATE_IMMEDIATE], + topo->dev_override_fee_rate[FEERATE_IMMEDIATE]), + p_opt_def("normal", json_tok_number, + &topo->dev_override_fee_rate[FEERATE_NORMAL], + topo->dev_override_fee_rate[FEERATE_NORMAL]), + p_opt_def("slow", json_tok_number, + &topo->dev_override_fee_rate[FEERATE_SLOW], + topo->dev_override_fee_rate[FEERATE_SLOW]), + NULL)) + return; + log_debug(topo->log, "dev-setfees: fees now %u/%u/%u", topo->dev_override_fee_rate[FEERATE_IMMEDIATE], diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index 63345e546..22789e467 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -9,6 +9,7 @@ #include #include #include +#include #include struct connect { @@ -80,7 +81,8 @@ void gossip_connect_result(struct lightningd *ld, const u8 *msg) static void json_connect(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *hosttok, *porttok, *idtok; + const jsmntok_t *hosttok, *porttok; + jsmntok_t *idtok; struct pubkey id; char *id_str; char *atptr; @@ -90,13 +92,12 @@ static void json_connect(struct command *cmd, u8 *msg; const char *err_msg; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "?host", &hosttok, - "?port", &porttok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("id", json_tok_tok, (const jsmntok_t **) &idtok), + p_opt_tok("host", &hosttok), + p_opt_tok("port", &porttok), + NULL)) return; - } /* Check for id@addrport form */ id_str = tal_strndup(cmd, buffer + idtok->start, diff --git a/lightningd/dev_ping.c b/lightningd/dev_ping.c index 4d71eea13..37cbc2773 100644 --- a/lightningd/dev_ping.c +++ b/lightningd/dev_ping.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -42,28 +43,16 @@ static void json_dev_ping(struct command *cmd, { struct peer *peer; u8 *msg; - jsmntok_t *idtok, *lentok, *pongbytestok; unsigned int len, pongbytes; struct pubkey id; struct subd *owner; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "len", &lentok, - "pongbytes", &pongbytestok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("id", json_tok_pubkey, &id), + p_req("len", json_tok_number, &len), + p_req("pongbytes", json_tok_number, &pongbytes), + NULL)) return; - } - - /* FIXME: These checks are horrible, use a peer flag to say it's - * ready to forward! */ - if (!json_tok_number(buffer, lentok, &len)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - lentok->end - lentok->start, - buffer + lentok->start); - return; - } /* BOLT #1: * @@ -85,14 +74,6 @@ static void json_dev_ping(struct command *cmd, return; } - if (!json_tok_number(buffer, pongbytestok, &pongbytes)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - pongbytestok->end - pongbytestok->start, - buffer + pongbytestok->start); - return; - } - /* Note that > 65531 is valid: it means "no pong reply" */ if (pongbytes > 65535) { command_fail(cmd, JSONRPC2_INVALID_PARAMS, @@ -100,14 +81,6 @@ static void json_dev_ping(struct command *cmd, return; } - if (!json_tok_pubkey(buffer, idtok, &id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid pubkey", - idtok->end - idtok->start, - buffer + idtok->start); - return; - } - /* First, see if it's in channeld. */ peer = peer_by_id(cmd->ld, &id); if (peer) { diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 8f2f91f80..fb6b365d3 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -332,22 +333,12 @@ static void json_listnodes(struct command *cmd, const char *buffer, const jsmntok_t *params) { u8 *req; - jsmntok_t *idtok = NULL; - struct pubkey *id = NULL; + struct pubkey *id; - if (!json_get_params(cmd, buffer, params, - "?id", &idtok, - NULL)) { + if (!param(cmd, buffer, params, + p_opt("id", json_tok_pubkey, &id), + NULL)) return; - } - - if (idtok) { - id = tal_arr(cmd, struct pubkey, 1); - if (!json_tok_pubkey(buffer, idtok, id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid id"); - return; - } - } req = towire_gossip_getnodes_request(cmd, id); subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd); @@ -384,72 +375,31 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con static void json_getroute(struct command *cmd, const char *buffer, const jsmntok_t *params) { struct lightningd *ld = cmd->ld; - struct pubkey source = ld->id, destination; - jsmntok_t *idtok, *msatoshitok, *riskfactortok, *cltvtok, *fromidtok; - jsmntok_t *fuzztok; + struct pubkey destination; + struct pubkey source; jsmntok_t *seedtok; u64 msatoshi; - unsigned cltv = 9; + unsigned cltv; double riskfactor; /* Higher fuzz means that some high-fee paths can be discounted * for an even larger value, increasing the scope for route * randomization (the higher-fee paths become more likely to * be selected) at the cost of increasing the probability of * selecting the higher-fee paths. */ - double fuzz = 75.0; + double fuzz; struct siphash_seed seed; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "msatoshi", &msatoshitok, - "riskfactor", &riskfactortok, - "?cltv", &cltvtok, - "?fromid", &fromidtok, - "?fuzzpercent", &fuzztok, - "?seed", &seedtok, - NULL)) { - return; - } - - if (!json_tok_pubkey(buffer, idtok, &destination)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid id"); + if (!param(cmd, buffer, params, + p_req("id", json_tok_pubkey, &destination), + p_req("msatoshi", json_tok_u64, &msatoshi), + p_req("riskfactor", json_tok_double, &riskfactor), + p_opt_def("cltv", json_tok_number, &cltv, 9), + p_opt_def("fromid", json_tok_pubkey, &source, ld->id), + p_opt_def("fuzzpercent", json_tok_double, &fuzz, 75.0), + p_opt_tok("seed", &seedtok), + NULL)) return; - } - - if (cltvtok && !json_tok_number(buffer, cltvtok, &cltv)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid cltv"); - return; - } - - if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - msatoshitok->end - msatoshitok->start, - buffer + msatoshitok->start); - return; - } - if (!json_tok_double(buffer, riskfactortok, &riskfactor)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid double", - riskfactortok->end - riskfactortok->start, - buffer + riskfactortok->start); - return; - } - - if (fromidtok && !json_tok_pubkey(buffer, fromidtok, &source)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid from id"); - return; - } - - if (fuzztok && - !json_tok_double(buffer, fuzztok, &fuzz)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid double", - fuzztok->end - fuzztok->start, - buffer + fuzztok->start); - return; - } if (!(0.0 <= fuzz && fuzz <= 100.0)) { command_fail(cmd, JSONRPC2_INVALID_PARAMS, "fuzz must be in range 0.0 <= %f <= 100.0", @@ -531,23 +481,11 @@ static void json_listchannels(struct command *cmd, const char *buffer, const jsmntok_t *params) { u8 *req; - jsmntok_t *idtok; - struct short_channel_id *id = NULL; - - if (!json_get_params(cmd, buffer, params, - "?short_channel_id", &idtok, - NULL)) { + struct short_channel_id *id; + if (!param(cmd, buffer, params, + p_opt("short_channel_id", json_tok_short_channel_id, &id), + NULL)) return; - } - - if (idtok) { - id = tal_arr(cmd, struct short_channel_id, 1); - if (!json_tok_short_channel_id(buffer, idtok, id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid short_channel_id"); - return; - } - } req = towire_gossip_getchannels_request(cmd, id); subd_req(cmd->ld->gossip, cmd->ld->gossip, @@ -591,26 +529,17 @@ static void json_dev_query_scids(struct command *cmd, const char *buffer, const jsmntok_t *params) { u8 *msg; - jsmntok_t *idtok, *scidstok; + const jsmntok_t *scidstok; const jsmntok_t *t, *end; struct pubkey id; struct short_channel_id *scids; size_t i; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "scids", &scidstok, - NULL)) { - return; - } - - if (!json_tok_pubkey(buffer, idtok, &id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid id", - idtok->end - idtok->start, - buffer + idtok->start); + if (!param(cmd, buffer, params, + p_req("id", json_tok_pubkey, &id), + p_req("scids", json_tok_tok, &scidstok), + NULL)) return; - } if (scidstok->type != JSMN_ARRAY) { command_fail(cmd, JSONRPC2_INVALID_PARAMS, @@ -651,32 +580,15 @@ static void json_dev_send_timestamp_filter(struct command *cmd, const jsmntok_t *params) { u8 *msg; - jsmntok_t *idtok, *firsttok, *rangetok; struct pubkey id; u32 first, range; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "first", &firsttok, - "range", &rangetok, - NULL)) { - return; - } - - if (!json_tok_pubkey(buffer, idtok, &id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid id", - idtok->end - idtok->start, - buffer + idtok->start); - return; - } - - if (!json_tok_number(buffer, firsttok, &first) - || !json_tok_number(buffer, rangetok, &range)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "bad first or range numbers"); + if (!param(cmd, buffer, params, + p_req("id", json_tok_pubkey, &id), + p_req("first", json_tok_number, &first), + p_req("range", json_tok_number, &range), + NULL)) return; - } log_debug(cmd->ld->log, "Setting timestamp range %u+%u", first, range); /* Tell gossipd, since this is a gossip query. */ @@ -736,32 +648,15 @@ static void json_dev_query_channel_range(struct command *cmd, const jsmntok_t *params) { u8 *msg; - jsmntok_t *idtok, *firsttok, *numtok; struct pubkey id; u32 first, num; - if (!json_get_params(cmd, buffer, params, - "id", &idtok, - "first", &firsttok, - "num", &numtok, - NULL)) { - return; - } - - if (!json_tok_pubkey(buffer, idtok, &id)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid id", - idtok->end - idtok->start, - buffer + idtok->start); + if (!param(cmd, buffer, params, + p_req("id", json_tok_pubkey, &id), + p_req("first", json_tok_number, &first), + p_req("num", json_tok_number, &num), + NULL)) return; - } - - if (!json_tok_number(buffer, firsttok, &first) - || !json_tok_number(buffer, numtok, &num)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "first and num must be numbers"); - return; - } /* Tell gossipd, since this is a gossip query. */ msg = towire_gossip_query_channel_range(cmd, &id, first, num); @@ -782,20 +677,12 @@ static void json_dev_set_max_scids_encode_size(struct command *cmd, const jsmntok_t *params) { u8 *msg; - jsmntok_t *maxtok; u32 max; - if (!json_get_params(cmd, buffer, params, - "max", &maxtok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("max", json_tok_number, &max), + NULL)) return; - } - - if (!json_tok_number(buffer, maxtok, &max)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "max must be a number"); - return; - } msg = towire_gossip_dev_set_max_scids_encode_size(NULL, max); subd_send_msg(cmd->ld->gossip, take(msg)); diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 30f63aa5e..f00889742 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -158,8 +159,8 @@ static void json_invoice(struct command *cmd, { struct invoice invoice; struct invoice_details details; - jsmntok_t *msatoshi, *label, *desctok, *exp, *fallback, *fallbacks; - jsmntok_t *preimagetok; + const jsmntok_t *msatoshi, *label, *desctok, *fallback, *fallbacks; + const jsmntok_t *preimagetok; u64 *msatoshi_val; const struct json_escaped *label_val, *desc; const char *desc_val; @@ -168,20 +169,19 @@ static void json_invoice(struct command *cmd, struct bolt11 *b11; char *b11enc; const u8 **fallback_scripts = NULL; - u64 expiry = 3600; + u64 expiry; bool result; - if (!json_get_params(cmd, buffer, params, - "msatoshi", &msatoshi, - "label", &label, - "description", &desctok, - "?expiry", &exp, - "?fallback", &fallback, - "?fallbacks", &fallbacks, - "?preimage", &preimagetok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("msatoshi", json_tok_tok, &msatoshi), + p_req("label", json_tok_tok, &label), + p_req("description", json_tok_tok, &desctok), + p_opt_def("expiry", json_tok_u64, &expiry, 3600), + p_opt_tok("fallback", &fallback), + p_opt_tok("fallbacks", &fallbacks), + p_opt_tok("preimage", &preimagetok), + NULL)) return; - } /* Get arguments. */ /* msatoshi */ @@ -244,14 +244,6 @@ static void json_invoice(struct command *cmd, strlen(desc_val)); return; } - /* expiry */ - if (exp && !json_tok_u64(buffer, exp, &expiry)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Expiry '%.*s' invalid seconds", - exp->end - exp->start, - buffer + exp->start); - return; - } /* fallback addresses */ if (fallback) { @@ -405,16 +397,15 @@ static void json_listinvoice_internal(struct command *cmd, const jsmntok_t *params, bool modern) { - jsmntok_t *labeltok = NULL; + jsmntok_t *labeltok; struct json_escaped *label; struct json_result *response = new_json_result(cmd); struct wallet *wallet = cmd->ld->wallet; - if (!json_get_params(cmd, buffer, params, - "?label", &labeltok, - NULL)) { + if (!param(cmd, buffer, params, + p_opt_tok("label", &labeltok), + NULL)) return; - } if (labeltok) { label = json_tok_label(cmd, buffer, labeltok); @@ -473,18 +464,17 @@ static void json_delinvoice(struct command *cmd, { struct invoice i; struct invoice_details details; - jsmntok_t *labeltok, *statustok; + const jsmntok_t *labeltok, *statustok; struct json_result *response = new_json_result(cmd); const char *status, *actual_status; struct json_escaped *label; struct wallet *wallet = cmd->ld->wallet; - if (!json_get_params(cmd, buffer, params, - "label", &labeltok, - "status", &statustok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("label", json_tok_tok, &labeltok), + p_req("status", json_tok_tok, &statustok), + NULL)) return; - } label = json_tok_label(cmd, buffer, labeltok); if (!label) { @@ -536,25 +526,14 @@ AUTODATA(json_command, &delinvoice_command); static void json_delexpiredinvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *maxexpirytimetok; - u64 maxexpirytime = time_now().ts.tv_sec; + u64 maxexpirytime; struct json_result *result; - if (!json_get_params(cmd, buffer, params, - "?maxexpirytime", &maxexpirytimetok, - NULL)) { + if (!param(cmd, buffer, params, + p_opt_def("maxexpirytime", json_tok_u64, &maxexpirytime, + time_now().ts.tv_sec), + NULL)) return; - } - - if (maxexpirytimetok) { - if (!json_tok_u64(buffer, maxexpirytimetok, &maxexpirytime)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - maxexpirytimetok->end - maxexpirytimetok->start, - buffer + maxexpirytimetok->start); - return; - } - } wallet_invoice_delete_expired(cmd->ld->wallet, maxexpirytime); @@ -574,37 +553,15 @@ static void json_autocleaninvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *cycletok; - jsmntok_t *exbytok; - u64 cycle = 3600; - u64 exby = 86400; + u64 cycle; + u64 exby; struct json_result *result; - if (!json_get_params(cmd, buffer, params, - "?cycle_seconds", &cycletok, - "?expired_by", &exbytok, - NULL)) { + if (!param(cmd, buffer, params, + p_opt_def("cycle_seconds", json_tok_u64, &cycle, 3600), + p_opt_def("expired_by", json_tok_u64, &exby, 86400), + NULL)) return; - } - - if (cycletok) { - if (!json_tok_u64(buffer, cycletok, &cycle)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - cycletok->end - cycletok->start, - buffer + cycletok->start); - return; - } - } - if (exbytok) { - if (!json_tok_u64(buffer, exbytok, &exby)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - exbytok->end - exbytok->start, - buffer + exbytok->start); - return; - } - } wallet_invoice_autoclean(cmd->ld->wallet, cycle, exby); @@ -625,27 +582,13 @@ AUTODATA(json_command, &autocleaninvoice_command); static void json_waitanyinvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *pay_indextok; u64 pay_index; struct wallet *wallet = cmd->ld->wallet; - if (!json_get_params(cmd, buffer, params, - "?lastpay_index", &pay_indextok, - NULL)) { + if (!param(cmd, buffer, params, + p_opt_def("lastpay_index", json_tok_u64, &pay_index, 0), + NULL)) return; - } - - if (!pay_indextok) { - pay_index = 0; - } else { - if (!json_tok_u64(buffer, pay_indextok, &pay_index)) { - command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "'%.*s' is not a valid number", - pay_indextok->end - pay_indextok->start, - buffer + pay_indextok->start); - return; - } - } /* Set command as pending. We do not know if * wallet_invoice_waitany will return immediately @@ -676,12 +619,13 @@ static void json_waitinvoice(struct command *cmd, struct invoice i; struct invoice_details details; struct wallet *wallet = cmd->ld->wallet; - jsmntok_t *labeltok; + const jsmntok_t *labeltok; struct json_escaped *label; - if (!json_get_params(cmd, buffer, params, "label", &labeltok, NULL)) { + if (!param(cmd, buffer, params, + p_req("label", json_tok_tok, &labeltok), + NULL)) return; - } /* Search for invoice */ label = json_tok_label(cmd, buffer, labeltok); @@ -756,17 +700,16 @@ static void json_add_fallback(struct json_result *response, static void json_decodepay(struct command *cmd, const char *buffer, const jsmntok_t *params) { - jsmntok_t *bolt11tok, *desctok; + const jsmntok_t *bolt11tok, *desctok; struct bolt11 *b11; struct json_result *response; char *str, *desc, *fail; - if (!json_get_params(cmd, buffer, params, - "bolt11", &bolt11tok, - "?description", &desctok, - NULL)) { + if (!param(cmd, buffer, params, + p_req("bolt11", json_tok_tok, &bolt11tok), + p_opt_tok("description", &desctok), + NULL)) return; - } str = tal_strndup(cmd, buffer + bolt11tok->start, bolt11tok->end - bolt11tok->start);