From bab8ff991ae79191487ded945d9ac83e75f0f356 Mon Sep 17 00:00:00 2001 From: Mark Beckwith Date: Mon, 13 Aug 2018 11:16:41 -0500 Subject: [PATCH] param: upgraded json_tok_u64 Also renamed old version to json_to_u64 for use as a utility funciton. Signed-off-by: Mark Beckwith --- common/json.c | 4 +- common/json.h | 4 +- lightningd/gossip_control.c | 6 +-- lightningd/invoice.c | 34 ++++++------- lightningd/json.c | 14 ++++++ lightningd/json.h | 6 +++ lightningd/jsonrpc.c | 2 +- lightningd/param.c | 1 - lightningd/pay.c | 5 +- lightningd/payalgo.c | 2 +- lightningd/test/run-param.c | 99 ++++++++++++++++++------------------- wallet/walletrpc.c | 10 ++-- 12 files changed, 103 insertions(+), 84 deletions(-) diff --git a/common/json.c b/common/json.c index 48fee838d..2db012c2d 100644 --- a/common/json.c +++ b/common/json.c @@ -43,7 +43,7 @@ bool json_tok_streq(const char *buffer, const jsmntok_t *tok, const char *str) return strncmp(buffer + tok->start, str, tok->end - tok->start) == 0; } -bool json_tok_u64(const char *buffer, const jsmntok_t *tok, +bool json_to_u64(const char *buffer, const jsmntok_t *tok, uint64_t *num) { char *end; @@ -96,7 +96,7 @@ bool json_to_number(const char *buffer, const jsmntok_t *tok, { uint64_t u64; - if (!json_tok_u64(buffer, tok, &u64)) + if (!json_to_u64(buffer, tok, &u64)) return false; *num = u64; diff --git a/common/json.h b/common/json.h index 2f003e70a..1cf45d0ba 100644 --- a/common/json.h +++ b/common/json.h @@ -29,8 +29,8 @@ bool json_to_number(const char *buffer, const jsmntok_t *tok, unsigned int *num); /* Extract number from this (may be a string, or a number literal) */ -bool json_tok_u64(const char *buffer, const jsmntok_t *tok, - uint64_t *num); +bool json_to_u64(const char *buffer, const jsmntok_t *tok, + uint64_t *num); /* Extract double from this (must be a number literal) */ bool json_tok_double(const char *buffer, const jsmntok_t *tok, double *num); diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 9e8d5db79..becf3bece 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -275,7 +275,7 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok struct pubkey destination; struct pubkey source; const jsmntok_t *seedtok; - u64 msatoshi; + u64 *msatoshi; unsigned *cltv; double riskfactor; /* Higher fuzz means that some high-fee paths can be discounted @@ -288,7 +288,7 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok if (!param(cmd, buffer, params, p_req("id", json_tok_pubkey, &destination), - p_req("msatoshi", json_tok_u64, &msatoshi), + p_req_tal("msatoshi", json_tok_u64, &msatoshi), p_req("riskfactor", json_tok_double, &riskfactor), p_opt_def_tal("cltv", json_tok_number, &cltv, 9), p_opt_def("fromid", json_tok_pubkey, &source, ld->id), @@ -317,7 +317,7 @@ static void json_getroute(struct command *cmd, const char *buffer, const jsmntok } else randombytes_buf(&seed, sizeof(seed)); - u8 *req = towire_gossip_getroute_request(cmd, &source, &destination, msatoshi, riskfactor*1000, *cltv, &fuzz, &seed); + u8 *req = towire_gossip_getroute_request(cmd, &source, &destination, *msatoshi, riskfactor*1000, *cltv, &fuzz, &seed); subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd); command_still_pending(cmd); } diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 375acc241..ace192e58 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -164,14 +164,14 @@ static void json_invoice(struct command *cmd, struct bolt11 *b11; char *b11enc; const u8 **fallback_scripts = NULL; - u64 expiry; + u64 *expiry; bool result; if (!param(cmd, buffer, params, p_req_tal("msatoshi", json_tok_tok, &msatoshi), p_req_tal("label", json_tok_tok, &label), p_req_tal("description", json_tok_tok, &desctok), - p_opt_def("expiry", json_tok_u64, &expiry, 3600), + p_opt_def_tal("expiry", json_tok_u64, &expiry, 3600), p_opt_tal("fallbacks", json_tok_tok, &fallbacks), p_opt_tal("preimage", json_tok_tok, &preimagetok), NULL)) @@ -183,7 +183,7 @@ static void json_invoice(struct command *cmd, msatoshi_val = NULL; else { msatoshi_val = tal(cmd, u64); - if (!json_tok_u64(buffer, msatoshi, msatoshi_val) + if (!json_to_u64(buffer, msatoshi, msatoshi_val) || *msatoshi_val == 0) { command_fail(cmd, JSONRPC2_INVALID_PARAMS, "'%.*s' is not a valid positive number", @@ -294,7 +294,7 @@ static void json_invoice(struct command *cmd, b11->payment_hash = rhash; b11->receiver_id = cmd->ld->id; b11->min_final_cltv_expiry = cmd->ld->config.cltv_final; - b11->expiry = expiry; + b11->expiry = *expiry; b11->description = tal_steal(b11, desc_val); b11->description_hash = NULL; if (fallback_scripts) @@ -307,7 +307,7 @@ static void json_invoice(struct command *cmd, &invoice, take(msatoshi_val), take(label_val), - expiry, + *expiry, b11enc, b11->description, &r, @@ -471,16 +471,16 @@ AUTODATA(json_command, &delinvoice_command); static void json_delexpiredinvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - u64 maxexpirytime; + u64 *maxexpirytime; struct json_result *result; if (!param(cmd, buffer, params, - p_opt_def("maxexpirytime", json_tok_u64, &maxexpirytime, - time_now().ts.tv_sec), + p_opt_def_tal("maxexpirytime", json_tok_u64, &maxexpirytime, + time_now().ts.tv_sec), NULL)) return; - wallet_invoice_delete_expired(cmd->ld->wallet, maxexpirytime); + wallet_invoice_delete_expired(cmd->ld->wallet, *maxexpirytime); result = new_json_result(cmd); json_object_start(result, NULL); @@ -498,17 +498,17 @@ static void json_autocleaninvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - u64 cycle; - u64 exby; + u64 *cycle; + u64 *exby; struct json_result *result; 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), + p_opt_def_tal("cycle_seconds", json_tok_u64, &cycle, 3600), + p_opt_def_tal("expired_by", json_tok_u64, &exby, 86400), NULL)) return; - wallet_invoice_autoclean(cmd->ld->wallet, cycle, exby); + wallet_invoice_autoclean(cmd->ld->wallet, *cycle, *exby); result = new_json_result(cmd); json_object_start(result, NULL); @@ -527,11 +527,11 @@ AUTODATA(json_command, &autocleaninvoice_command); static void json_waitanyinvoice(struct command *cmd, const char *buffer, const jsmntok_t *params) { - u64 pay_index; + u64 *pay_index; struct wallet *wallet = cmd->ld->wallet; if (!param(cmd, buffer, params, - p_opt_def("lastpay_index", json_tok_u64, &pay_index, 0), + p_opt_def_tal("lastpay_index", json_tok_u64, &pay_index, 0), NULL)) return; @@ -541,7 +541,7 @@ static void json_waitanyinvoice(struct command *cmd, command_still_pending(cmd); /* Find next paid invoice. */ - wallet_invoice_waitany(cmd, wallet, pay_index, + wallet_invoice_waitany(cmd, wallet, *pay_index, &wait_on_invoice, (void*) cmd); } diff --git a/lightningd/json.c b/lightningd/json.c index 909faefaf..b3792a431 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -105,6 +105,20 @@ bool json_tok_number(struct command *cmd, const char *name, return true; } +bool json_tok_u64(struct command *cmd, const char *name, + const char *buffer, const jsmntok_t *tok, + uint64_t **num) +{ + *num = tal(cmd, uint64_t); + if (!json_to_u64(buffer, tok, *num)) { + command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "'%s' should be an unsigned 64 bit integer, not '%.*s'", + name, tok->end - tok->start, buffer + tok->start); + return false; + } + return true; +} + bool json_tok_pubkey(const char *buffer, const jsmntok_t *tok, struct pubkey *pubkey) { diff --git a/lightningd/json.h b/lightningd/json.h index fa5cca01c..7dc26f199 100644 --- a/lightningd/json.h +++ b/lightningd/json.h @@ -7,6 +7,7 @@ #include "config.h" #include #include +#include #define JSMN_STRICT 1 # include @@ -53,6 +54,11 @@ bool json_tok_pubkey(const char *buffer, const jsmntok_t *tok, bool json_tok_short_channel_id(const char *buffer, const jsmntok_t *tok, struct short_channel_id *scid); +/* Extract number from this (may be a string, or a number literal) */ +bool json_tok_u64(struct command *cmd, const char *name, + const char *buffer, const jsmntok_t *tok, + uint64_t **num); + /* '"fieldname" : "1234:5:6"' */ void json_add_short_channel_id(struct json_result *response, const char *fieldname, diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 05e2c509e..ab3d8f698 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -769,7 +769,7 @@ bool json_tok_wtx(struct wallet_tx * tx, const char * buffer, if (json_tok_streq(buffer, sattok, "all")) { tx->all_funds = true; tx->amount = max; - } else if (!json_tok_u64(buffer, sattok, &tx->amount)) { + } else if (!json_to_u64(buffer, sattok, &tx->amount)) { command_fail(tx->cmd, JSONRPC2_INVALID_PARAMS, "Invalid satoshis"); return false; diff --git a/lightningd/param.c b/lightningd/param.c index 6c2efb401..7f7aa1e7e 100644 --- a/lightningd/param.c +++ b/lightningd/param.c @@ -54,7 +54,6 @@ static struct fail_format fail_formats[] = { {json_tok_double, "'%s' should be a double, not '%.*s'"}, {json_tok_percent, "'%s' should be a double in range [0.0, 100.0], not '%.*s'"}, - {json_tok_u64, "'%s' should be an unsigned 64 bit integer, not '%.*s'"}, {json_tok_newaddr, "'%s' should be 'bech32' or 'p2sh-segwit', not '%.*s'"}, {json_tok_wtx, "'%s' should be 'all' or a positive integer greater than " diff --git a/lightningd/pay.c b/lightningd/pay.c index ec4f1e875..57e3fc0c3 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -957,8 +957,8 @@ static void json_sendpay(struct command *cmd, if (!param(cmd, buffer, params, p_req_tal("route", json_tok_tok, &routetok), p_req("payment_hash", json_tok_sha256, &rhash), - p_opt("msatoshi", json_tok_u64, &msatoshi), p_opt_tal("description", json_tok_tok, &desctok), + p_opt_tal("msatoshi", json_tok_u64, &msatoshi), NULL)) return; @@ -975,6 +975,7 @@ static void json_sendpay(struct command *cmd, route = tal_arr(cmd, struct route_hop, n_hops); for (t = routetok + 1; t < end; t = json_next(t)) { + /* FIXME: Use param() to handle parsing each route? -- @wythe */ const jsmntok_t *amttok, *idtok, *delaytok, *chantok; if (t->type != JSMN_OBJECT) { @@ -999,7 +1000,7 @@ static void json_sendpay(struct command *cmd, tal_resize(&route, n_hops + 1); /* What that hop will forward */ - if (!json_tok_u64(buffer, amttok, &route[n_hops].amount)) { + if (!json_to_u64(buffer, amttok, &route[n_hops].amount)) { command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Route %zu invalid msatoshi", n_hops); diff --git a/lightningd/payalgo.c b/lightningd/payalgo.c index 7ad578cb7..f9809cd74 100644 --- a/lightningd/payalgo.c +++ b/lightningd/payalgo.c @@ -612,8 +612,8 @@ static void json_pay(struct command *cmd, if (!param(cmd, buffer, params, p_req_tal("bolt11", json_tok_tok, &bolt11tok), - p_opt("msatoshi", json_tok_u64, &msatoshi), p_opt_tal("description", json_tok_tok, &desctok), + p_opt_tal("msatoshi", json_tok_u64, &msatoshi), p_opt_def("riskfactor", json_tok_double, &riskfactor, 1.0), p_opt_def("maxfeepercent", json_tok_percent, &maxfeepercent, 0.5), p_opt_def_tal("retry_for", json_tok_number, &retryfor, 60), diff --git a/lightningd/test/run-param.c b/lightningd/test/run-param.c index f57b096ad..c7b1c8ca5 100644 --- a/lightningd/test/run-param.c +++ b/lightningd/test/run-param.c @@ -130,24 +130,27 @@ struct sanity buffers[] = { {"['42']", true, 0, 0, "missing required"}, // fail wrong type - {"{'u64':'hello', 'double':'3.15'}", true, 0, 0, "\"u64\": \"hello\""}, + {"{'u64':'hello', 'double':'3.15'}", true, 0, 0, "be an unsigned 64"}, {"['3.15', '3.15', 'stuff']", true, 0, 0, "integer"}, }; static void stest(const struct json *j, struct sanity *b) { - u64 ival; + u64 *ival; double dval; if (!param(cmd, j->buffer, j->toks, - p_req("u64", json_tok_u64, &ival), + p_req_tal("u64", json_tok_u64, &ival), p_req("double", json_tok_double, &dval), NULL)) { assert(check_fail()); assert(b->failed == true); - assert(strstr(fail_msg, b->fail_str)); + if (!strstr(fail_msg, b->fail_str)) { + printf("%s != %s\n", fail_msg, b->fail_str); + assert(false); + } } else { assert(!check_fail()); assert(b->failed == false); - assert(ival == 42); + assert(*ival == 42); assert(dval > 3.1499 && b->dval < 3.1501); } } @@ -200,56 +203,52 @@ static void dup_names(void) json_parse(cmd, "{ 'u64' : '42', 'u64' : '43', 'double' : '3.15' }"); - u64 i; + u64 *i; double d; assert(!param(cmd, j->buffer, j->toks, - p_req("u64", json_tok_u64, &i), + p_req_tal("u64", json_tok_u64, &i), p_req("double", json_tok_double, &d), NULL)); } static void null_params(void) { - uint64_t *ints = tal_arr(cmd, uint64_t, 5); - uint64_t **intptrs = tal_arr(cmd, uint64_t *, 2); + uint64_t **intptrs = tal_arr(cmd, uint64_t *, 7); /* no null params */ struct json *j = json_parse(cmd, "[ '10', '11', '12', '13', '14', '15', '16']"); - for (int i = 0; i < tal_count(ints) - 1; ++i) - ints[i] = i; assert(param(cmd, j->buffer, j->toks, - p_req("0", json_tok_u64, &ints[0]), - p_req("1", json_tok_u64, &ints[1]), - p_req("2", json_tok_u64, &ints[2]), - p_req("3", json_tok_u64, &ints[3]), - p_opt_def("4", json_tok_u64, &ints[4], 999), - p_opt("5", json_tok_u64, &intptrs[0]), - p_opt("6", json_tok_u64, &intptrs[1]), + p_req_tal("0", json_tok_u64, &intptrs[0]), + p_req_tal("1", json_tok_u64, &intptrs[1]), + p_req_tal("2", json_tok_u64, &intptrs[2]), + p_req_tal("3", json_tok_u64, &intptrs[3]), + p_opt_def_tal("4", json_tok_u64, &intptrs[4], 999), + p_opt_tal("5", json_tok_u64, &intptrs[5]), + p_opt_tal("6", json_tok_u64, &intptrs[6]), NULL)); - for (int i = 0; i < tal_count(ints); ++i) - assert(ints[i] == i + 10); - for (int i = 0; i < tal_count(intptrs); ++i) - assert(*intptrs[i] == i + 10 + tal_count(ints)); + for (int i = 0; i < tal_count(intptrs); ++i) { + assert(intptrs[i]); + assert(*intptrs[i] == i + 10); + } /* missing at end */ - for (int i = 0; i < tal_count(ints); ++i) - ints[i] = 42; - for (int i = 0; i < tal_count(intptrs); ++i) - intptrs[i] = (void *)42; - j = json_parse(cmd, "[ '10', '11', '12', '13', '14']"); assert(param(cmd, j->buffer, j->toks, - p_req("0", json_tok_u64, &ints[0]), - p_req("1", json_tok_u64, &ints[1]), - p_req("2", json_tok_u64, &ints[2]), - p_req("3", json_tok_u64, &ints[3]), - p_opt("4", json_tok_u64, &intptrs[0]), - p_opt("5", json_tok_u64, &intptrs[1]), - p_opt_def("6", json_tok_u64, &ints[4], 888), + p_req_tal("0", json_tok_u64, &intptrs[0]), + p_req_tal("1", json_tok_u64, &intptrs[1]), + p_req_tal("2", json_tok_u64, &intptrs[2]), + p_req_tal("3", json_tok_u64, &intptrs[3]), + p_opt_tal("4", json_tok_u64, &intptrs[4]), + p_opt_tal("5", json_tok_u64, &intptrs[5]), + p_opt_def_tal("6", json_tok_u64, &intptrs[6], 888), NULL)); - assert(*intptrs[0] == 14); - assert(intptrs[1] == NULL); - assert(ints[4] == 888); + assert(*intptrs[0] == 10); + assert(*intptrs[1] == 11); + assert(*intptrs[2] == 12); + assert(*intptrs[3] == 13); + assert(*intptrs[4] == 14); + assert(!intptrs[5]); + assert(*intptrs[6] == 888); } #if DEVELOPER @@ -258,28 +257,28 @@ static void null_params(void) */ static void bad_programmer(void) { - u64 ival; - u64 ival2; + u64 *ival; + u64 *ival2; double dval; struct json *j = json_parse(cmd, "[ '25', '546', '26' ]"); /* check for repeated names */ assert(!param(cmd, j->buffer, j->toks, - p_req("repeat", json_tok_u64, &ival), + p_req_tal("repeat", json_tok_u64, &ival), p_req("double", json_tok_double, &dval), - p_req("repeat", json_tok_u64, &ival2), NULL)); + p_req_tal("repeat", json_tok_u64, &ival2), NULL)); assert(check_fail()); assert(strstr(fail_msg, "developer error")); assert(!param(cmd, j->buffer, j->toks, - p_req("repeat", json_tok_u64, &ival), + p_req_tal("repeat", json_tok_u64, &ival), p_req("double", json_tok_double, &dval), - p_req("repeat", json_tok_u64, &ival), NULL)); + p_req_tal("repeat", json_tok_u64, &ival), NULL)); assert(check_fail()); assert(strstr(fail_msg, "developer error")); assert(!param(cmd, j->buffer, j->toks, - p_req("u64", json_tok_u64, &ival), + p_req_tal("u64", json_tok_u64, &ival), p_req("repeat", json_tok_double, &dval), p_req("repeat", json_tok_double, &dval), NULL)); assert(check_fail()); @@ -287,8 +286,8 @@ static void bad_programmer(void) /* check for repeated arguments */ assert(!param(cmd, j->buffer, j->toks, - p_req("u64", json_tok_u64, &ival), - p_req("repeated-arg", json_tok_u64, &ival), NULL)); + p_req_tal("u64", json_tok_u64, &ival), + p_req_tal("repeated-arg", json_tok_u64, &ival), NULL)); assert(check_fail()); assert(strstr(fail_msg, "developer error")); @@ -302,7 +301,7 @@ static void bad_programmer(void) unsigned int *msatoshi; double riskfactor; assert(!param(cmd, j->buffer, j->toks, - p_req("u64", json_tok_u64, &ival), + p_req_tal("u64", json_tok_u64, &ival), p_req("double", json_tok_double, &dval), p_opt_def_tal("msatoshi", json_tok_number, &msatoshi, 100), p_req("riskfactor", json_tok_double, &riskfactor), NULL)); @@ -382,7 +381,7 @@ static void sendpay(void) p_req_tal("route", json_tok_tok, &routetok), p_req_tal("cltv", json_tok_number, &cltv), p_opt_tal("note", json_tok_tok, ¬e), - p_opt("msatoshi", json_tok_u64, &msatoshi), + p_opt_tal("msatoshi", json_tok_u64, &msatoshi), NULL)) assert(false); @@ -405,7 +404,7 @@ static void sendpay_nulltok(void) p_req_tal("route", json_tok_tok, &routetok), p_req_tal("cltv", json_tok_number, &cltv), p_opt_tal("note", json_tok_tok, ¬e), - p_opt("msatoshi", json_tok_u64, &msatoshi), + p_opt_tal("msatoshi", json_tok_u64, &msatoshi), NULL)) assert(false); @@ -425,7 +424,7 @@ static bool json_tok_msat(struct command *cmd, } *msatoshi_val = tal(cmd, u64); - if (json_tok_u64(buffer, tok, *msatoshi_val) && *msatoshi_val != 0) + if (json_to_u64(buffer, tok, *msatoshi_val) && *msatoshi_val != 0) return true; command_fail(cmd, JSONRPC2_INVALID_PARAMS, diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index ced6ecada..6ea56bc5c 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -279,19 +279,19 @@ static void json_listaddrs(struct command *cmd, struct json_result *response = new_json_result(cmd); struct ext_key ext; struct pubkey pubkey; - u64 bip32_max_index; + u64 *bip32_max_index; if (!param(cmd, buffer, params, - p_opt_def("bip32_max_index", json_tok_u64, &bip32_max_index, - db_get_intvar(cmd->ld->wallet->db, - "bip32_max_index", 0)), + p_opt_def_tal("bip32_max_index", json_tok_u64, &bip32_max_index, + db_get_intvar(cmd->ld->wallet->db, + "bip32_max_index", 0)), NULL)) return; json_object_start(response, NULL); json_array_start(response, "addresses"); - for (s64 keyidx = 0; keyidx <= bip32_max_index; keyidx++) { + for (s64 keyidx = 0; keyidx <= *bip32_max_index; keyidx++) { if(keyidx == BIP32_INITIAL_HARDENED_CHILD){ break;