Browse Source

Modern param style for all remaining files

Removed `json_get_params`.

Also added json_tok_percent and json_tok_newaddr. Probably should
have been a separate PR but it was so easy.

[ Squashed comment update for gcc workaround --RR ]
Signed-off-by: Mark Beckwith <wythe@intrig.com>
ppa-0.6.1
Mark Beckwith 7 years ago
committed by Rusty Russell
parent
commit
f850849486
  1. 15
      common/json.c
  2. 3
      common/json.h
  3. 126
      lightningd/jsonrpc.c
  4. 12
      lightningd/jsonrpc.h
  5. 14
      lightningd/log.c
  6. 11
      lightningd/opening_control.c
  7. 8
      lightningd/options.c
  8. 3
      lightningd/param.c
  9. 86
      lightningd/pay.c
  10. 99
      lightningd/payalgo.c
  11. 158
      lightningd/peer_control.c
  12. 2
      lightningd/peer_control.h
  13. 24
      lightningd/peer_htlcs.c
  14. 10
      lightningd/test/run-param.c
  15. 12
      wallet/test/run-wallet.c
  16. 43
      wallet/walletrpc.c

15
common/json.c

@ -76,6 +76,21 @@ bool json_tok_double(const char *buffer, const jsmntok_t *tok, double *num)
return true;
}
bool json_tok_percent(const char *buffer, const jsmntok_t *tok, double *num)
{
if (!json_tok_double(buffer, tok, num))
return false;
/* Ensure it is in the range [0.0, 100.0] */
if (!(0.0 <= *num))
return false;
if (!(*num <= 100.0))
return false;
return true;
}
bool json_tok_number(const char *buffer, const jsmntok_t *tok,
unsigned int *num)
{

3
common/json.h

@ -39,6 +39,9 @@ bool json_tok_double(const char *buffer, const jsmntok_t *tok, double *num);
bool json_tok_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
uint64_t *satoshi);
/* Extract double in range [0.0, 100.0] */
bool json_tok_percent(const char *buffer, const jsmntok_t *tok, double *num);
/* Extract boolean this (must be a true or false) */
bool json_tok_bool(const char *buffer, const jsmntok_t *tok, bool *b);

126
lightningd/jsonrpc.c

@ -24,6 +24,7 @@
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/options.h>
#include <lightningd/param.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
@ -95,14 +96,13 @@ static void json_rhash(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct json_result *response = new_json_result(cmd);
jsmntok_t *secrettok;
const jsmntok_t *secrettok;
struct sha256 secret;
if (!json_get_params(cmd, buffer, params,
"secret", &secrettok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("secret", json_tok_tok, &secrettok),
NULL))
return;
}
if (!hex_decode(buffer + secrettok->start,
secrettok->end - secrettok->start,
@ -200,11 +200,12 @@ static void json_help(struct command *cmd,
unsigned int i;
struct json_result *response = new_json_result(cmd);
struct json_command **cmdlist = get_cmdlist();
jsmntok_t *cmdtok;
const jsmntok_t *cmdtok;
if (!json_get_params(cmd, buffer, params, "?command", &cmdtok, NULL)) {
if (!param(cmd, buffer, params,
p_opt_tok("command", &cmdtok),
NULL))
return;
}
json_object_start(response, NULL);
if (cmdtok) {
@ -493,104 +494,6 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
assert(c->pending);
}
bool json_get_params(struct command *cmd,
const char *buffer, const jsmntok_t param[], ...)
{
va_list ap;
const char **names;
size_t num_names;
/* Uninitialized warnings on p and end */
const jsmntok_t *p = NULL, *end = NULL;
if (param->type == JSMN_ARRAY) {
if (param->size == 0)
p = NULL;
else
p = param + 1;
end = json_next(param);
} else if (param->type != JSMN_OBJECT) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Expected array or object for params");
return false;
}
num_names = 0;
names = tal_arr(cmd, const char *, num_names + 1);
va_start(ap, param);
while ((names[num_names] = va_arg(ap, const char *)) != NULL) {
const jsmntok_t **tokptr = va_arg(ap, const jsmntok_t **);
bool compulsory = true;
if (names[num_names][0] == '?') {
names[num_names]++;
compulsory = false;
}
if (param->type == JSMN_ARRAY) {
*tokptr = p;
if (p) {
p = json_next(p);
if (p == end)
p = NULL;
}
} else {
*tokptr = json_get_member(buffer, param,
names[num_names]);
}
/* Convert 'null' to NULL */
if (*tokptr
&& (*tokptr)->type == JSMN_PRIMITIVE
&& buffer[(*tokptr)->start] == 'n') {
*tokptr = NULL;
}
if (compulsory && !*tokptr) {
va_end(ap);
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Missing '%s' parameter",
names[num_names]);
return false;
}
num_names++;
tal_resize(&names, num_names + 1);
}
va_end(ap);
/* Now make sure there aren't any params which aren't valid */
if (param->type == JSMN_ARRAY) {
if (param->size > num_names) {
tal_free(names);
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Too many parameters:"
" got %u, expected %zu",
param->size, num_names);
return false;
}
} else {
const jsmntok_t *t;
end = json_next(param);
/* Find each parameter among the valid names */
for (t = param + 1; t < end; t = json_next(t+1)) {
bool found = false;
for (size_t i = 0; i < num_names; i++) {
if (json_tok_streq(buffer, t, names[i]))
found = true;
}
if (!found) {
tal_free(names);
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Unknown parameter '%.*s'",
t->end - t->start,
buffer + t->start);
return false;
}
}
}
tal_free(names);
return true;
}
static struct io_plan *write_json(struct io_conn *conn,
struct json_connection *jcon)
{
@ -864,6 +767,17 @@ json_tok_address_scriptpubkey(const tal_t *cxt,
return ADDRESS_PARSE_UNRECOGNIZED;
}
bool json_tok_newaddr(const char *buffer, const jsmntok_t *tok, bool *is_p2wpkh)
{
if (json_tok_streq(buffer, tok, "p2sh-segwit"))
*is_p2wpkh = false;
else if (json_tok_streq(buffer, tok, "bech32"))
*is_p2wpkh = true;
else
return false;
return true;
}
bool json_tok_wtx(struct wallet_tx * tx, const char * buffer,
const jsmntok_t *sattok)
{

12
lightningd/jsonrpc.h

@ -60,16 +60,6 @@ struct json_command {
const char *verbose;
};
/* Get the parameters (by position or name). Followed by triples of
* of const char *name, const jsmntok_t **ret_ptr, then NULL.
*
* If name starts with '?' it is optional (and will be set to NULL
* if it's a literal 'null' or not present).
* Otherwise false is returned, and command_fail already called.
*/
bool json_get_params(struct command *cmd,
const char *buffer, const jsmntok_t param[], ...);
struct json_result *null_response(const tal_t *ctx);
void command_success(struct command *cmd, struct json_result *response);
void PRINTF_FMT(3, 4) command_fail(struct command *cmd, int code,
@ -103,6 +93,8 @@ json_tok_address_scriptpubkey(const tal_t *ctx,
const char *buffer,
const jsmntok_t *tok, const u8 **scriptpubkey);
bool json_tok_newaddr(const char *buffer, const jsmntok_t *tok, bool *is_p2wpkh);
/* Parse the satoshi token in wallet_tx. */
bool json_tok_wtx(struct wallet_tx * tx, const char * buffer,
const jsmntok_t * sattok);

14
lightningd/log.c

@ -18,6 +18,7 @@
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/lightningd.h>
#include <lightningd/options.h>
#include <lightningd/param.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
@ -656,18 +657,11 @@ static void json_getlog(struct command *cmd,
struct json_result *response = new_json_result(cmd);
enum log_level minlevel;
struct log_book *lr = cmd->ld->log_book;
jsmntok_t *level;
if (!json_get_params(cmd, buffer, params, "?level", &level, NULL)) {
if (!param(cmd, buffer, params,
p_opt_def("level", json_tok_loglevel, &minlevel, LOG_INFORM),
NULL))
return;
}
if (!level)
minlevel = LOG_INFORM;
else if (!json_tok_loglevel(buffer, level, &minlevel)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid level param");
return;
}
json_object_start(response, NULL);
if (deprecated_apis)

11
lightningd/opening_control.c

@ -19,6 +19,7 @@
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/opening_control.h>
#include <lightningd/param.h>
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <openingd/gen_opening_wire.h>
@ -892,7 +893,7 @@ bool handle_opening_channel(struct lightningd *ld,
static void json_fund_channel(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *desttok, *sattok;
const jsmntok_t *desttok, *sattok;
struct funding_channel * fc = tal(cmd, struct funding_channel);
u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL);
u8 *msg;
@ -900,10 +901,12 @@ static void json_fund_channel(struct command *cmd,
fc->cmd = cmd;
fc->uc = NULL;
wtx_init(cmd, &fc->wtx);
if (!json_get_params(fc->cmd, buffer, params,
"id", &desttok,
"satoshi", &sattok, NULL))
if (!param(fc->cmd, buffer, params,
p_req("id", json_tok_tok, &desttok),
p_req("satoshi", json_tok_tok, &sattok),
NULL))
return;
if (!json_tok_wtx(&fc->wtx, buffer, sattok))
return;
if (!pubkey_from_hexstr(buffer + desttok->start,

8
lightningd/options.c

@ -24,6 +24,7 @@
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/options.h>
#include <lightningd/param.h>
#include <lightningd/subd.h>
#include <stdio.h>
#include <string.h>
@ -1059,12 +1060,13 @@ static void json_listconfigs(struct command *cmd,
{
size_t i;
struct json_result *response = new_json_result(cmd);
jsmntok_t *configtok;
const jsmntok_t *configtok;
bool found = false;
if (!json_get_params(cmd, buffer, params, "?config", &configtok, NULL)) {
if (!param(cmd, buffer, params,
p_opt_tok("config", &configtok),
NULL))
return;
}
json_object_start(response, NULL);
if (!configtok)

3
lightningd/param.c

@ -49,7 +49,10 @@ struct fail_format {
static struct fail_format fail_formats[] = {
{json_tok_bool, "'%s' should be 'true' or 'false', not '%.*s'"},
{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_number, "'%s' should be an integer, not '%.*s'"},
{json_tok_wtx,
"'%s' should be 'all' or a positive integer greater than "

86
lightningd/pay.c

@ -11,6 +11,7 @@
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/options.h>
#include <lightningd/param.h>
#include <lightningd/peer_control.h>
#include <lightningd/peer_htlcs.h>
#include <lightningd/subd.h>
@ -912,21 +913,19 @@ static void json_sendpay_on_resolve(const struct sendpay_result* r,
static void json_sendpay(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *routetok, *rhashtok;
jsmntok_t *msatoshitok;
const jsmntok_t *routetok, *rhashtok;
const jsmntok_t *t, *end;
size_t n_hops;
struct sha256 rhash;
struct route_hop *route;
u64 msatoshi;
u64 *msatoshi;
if (!json_get_params(cmd, buffer, params,
"route", &routetok,
"payment_hash", &rhashtok,
"?msatoshi", &msatoshitok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("route", json_tok_tok, &routetok),
p_req("payment_hash", json_tok_tok, &rhashtok),
p_opt("msatoshi", json_tok_u64, &msatoshi),
NULL))
return;
}
if (!hex_decode(buffer + rhashtok->start,
rhashtok->end - rhashtok->start,
@ -1006,32 +1005,24 @@ static void json_sendpay(struct command *cmd,
return;
}
if (msatoshitok) {
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%.*s' is not a number",
msatoshitok->end - msatoshitok->start,
buffer + msatoshitok->start);
return;
}
/* The given msatoshi is the actual payment that
* the payee is requesting. The final hop amount, is
* what we actually give, which can be from the
* msatoshi to twice msatoshi. */
/* if not: msatoshi <= finalhop.amount <= 2 * msatoshi,
* fail. */
if (!(msatoshi <= route[n_hops-1].amount &&
route[n_hops-1].amount <= 2 * msatoshi)) {
/* The given msatoshi is the actual payment that the payee is
* requesting. The final hop amount is what we actually give, which can
* be from the msatoshi to twice msatoshi. */
/* if not: msatoshi <= finalhop.amount <= 2 * msatoshi, fail. */
if (msatoshi) {
if (!(*msatoshi <= route[n_hops-1].amount &&
route[n_hops-1].amount <= 2 * *msatoshi)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi %"PRIu64" out of range",
msatoshi);
*msatoshi);
return;
}
} else
msatoshi = route[n_hops-1].amount;
}
if (send_payment(cmd, cmd->ld, &rhash, route, msatoshi,
&json_sendpay_on_resolve, cmd))
if (send_payment(cmd, cmd->ld, &rhash, route,
msatoshi ? *msatoshi : route[n_hops-1].amount,
&json_sendpay_on_resolve, cmd))
command_still_pending(cmd);
}
@ -1050,15 +1041,14 @@ static void waitsendpay_timeout(struct command *cmd)
static void json_waitsendpay(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
jsmntok_t *rhashtok;
jsmntok_t *timeouttok;
const jsmntok_t *rhashtok;
struct sha256 rhash;
unsigned int timeout;
unsigned int *timeout;
if (!json_get_params(cmd, buffer, params,
"payment_hash", &rhashtok,
"?timeout", &timeouttok,
NULL))
if (!param(cmd, buffer, params,
p_req("payment_hash", json_tok_tok, &rhashtok),
p_opt("timeout", json_tok_number, &timeout),
NULL))
return;
if (!hex_decode(buffer + rhashtok->start,
@ -1071,21 +1061,12 @@ static void json_waitsendpay(struct command *cmd, const char *buffer,
return;
}
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%.*s' is not a valid number",
timeouttok->end - timeouttok->start,
buffer + timeouttok->start);
return;
}
if (!wait_payment(cmd, cmd->ld, &rhash, &json_waitsendpay_on_resolve, cmd))
return;
if (timeouttok)
new_reltimer(&cmd->ld->timers, cmd, time_from_sec(timeout),
if (timeout)
new_reltimer(&cmd->ld->timers, cmd, time_from_sec(*timeout),
&waitsendpay_timeout, cmd);
command_still_pending(cmd);
}
@ -1105,12 +1086,11 @@ static void json_listpayments(struct command *cmd, const char *buffer,
jsmntok_t *bolt11tok, *rhashtok;
struct sha256 *rhash = NULL;
if (!json_get_params(cmd, buffer, params,
"?bolt11", &bolt11tok,
"?payment_hash", &rhashtok,
NULL)) {
if (!param(cmd, buffer, params,
p_opt_tok("bolt11", &bolt11tok),
p_opt_tok("payment_hash", &rhashtok),
NULL))
return;
}
if (bolt11tok) {
struct bolt11 *b11;

99
lightningd/payalgo.c

@ -15,6 +15,7 @@
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/param.h>
#include <lightningd/subd.h>
#include <sodium/randombytes.h>
#include <wallet/wallet.h>
@ -592,29 +593,27 @@ static void json_pay_stop_retrying(struct pay *pay)
static void json_pay(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok, *maxfeetok;
jsmntok_t *retryfortok;
jsmntok_t *maxdelaytok;
double riskfactor = 1.0;
double maxfeepercent = 0.5;
u64 msatoshi;
const jsmntok_t *bolt11tok, *desctok;
double riskfactor;
double maxfeepercent;
u64 *msatoshi;
struct pay *pay = tal(cmd, struct pay);
struct bolt11 *b11;
char *fail, *b11str, *desc;
unsigned int retryfor = 60;
unsigned int maxdelay = cmd->ld->config.locktime_max;
if (!json_get_params(cmd, buffer, params,
"bolt11", &bolt11tok,
"?msatoshi", &msatoshitok,
"?description", &desctok,
"?riskfactor", &riskfactortok,
"?maxfeepercent", &maxfeetok,
"?retry_for", &retryfortok,
"?maxdelay", &maxdelaytok,
NULL)) {
unsigned int retryfor;
unsigned int maxdelay;
if (!param(cmd, buffer, params,
p_req("bolt11", json_tok_tok, &bolt11tok),
p_opt("msatoshi", json_tok_u64, &msatoshi),
p_opt_tok("description", &desctok),
p_opt_def("riskfactor", json_tok_double, &riskfactor, 1.0),
p_opt_def("maxfeepercent", json_tok_percent, &maxfeepercent, 0.5),
p_opt_def("retry_for", json_tok_number, &retryfor, 60),
p_opt_def("maxdelay", json_tok_number, &maxdelay,
cmd->ld->config.locktime_max),
NULL))
return;
}
b11str = tal_strndup(cmd, buffer + bolt11tok->start,
bolt11tok->end - bolt11tok->start);
@ -638,78 +637,24 @@ static void json_pay(struct command *cmd,
pay->expiry.ts.tv_sec = b11->timestamp + b11->expiry;
pay->min_final_cltv_expiry = b11->min_final_cltv_expiry;
if (retryfortok && !json_tok_number(buffer, retryfortok, &retryfor)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%.*s' is not an integer",
retryfortok->end - retryfortok->start,
buffer + retryfortok->start);
return;
}
if (b11->msatoshi) {
msatoshi = *b11->msatoshi;
if (msatoshitok) {
if (msatoshi) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter unnecessary");
return;
}
msatoshi = b11->msatoshi;
} else {
if (!msatoshitok) {
if (!msatoshi) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter required");
return;
}
if (!json_tok_u64(buffer, msatoshitok, &msatoshi)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi '%.*s' is not a valid number",
msatoshitok->end-msatoshitok->start,
buffer + msatoshitok->start);
return;
}
}
pay->msatoshi = msatoshi;
if (riskfactortok
&& !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;
}
pay->msatoshi = *msatoshi;
pay->riskfactor = riskfactor * 1000;
if (maxfeetok
&& !json_tok_double(buffer, maxfeetok, &maxfeepercent)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%.*s' is not a valid double",
maxfeetok->end - maxfeetok->start,
buffer + maxfeetok->start);
return;
}
/* Ensure it is in range 0.0 <= maxfeepercent <= 100.0 */
if (!(0.0 <= maxfeepercent)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%f maxfeepercent must be non-negative",
maxfeepercent);
return;
}
if (!(maxfeepercent <= 100.0)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%f maxfeepercent must be <= 100.0",
maxfeepercent);
return;
}
pay->maxfeepercent = maxfeepercent;
if (maxdelaytok
&& !json_tok_number(buffer, maxdelaytok, &maxdelay)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%.*s' is not a valid integer",
maxdelaytok->end - maxdelaytok->start,
buffer + maxdelaytok->start);
return;
}
if (maxdelay < pay->min_final_cltv_expiry) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"maxdelay (%u) must be greater than "

158
lightningd/peer_control.c

@ -39,6 +39,7 @@
#include <lightningd/onchain_control.h>
#include <lightningd/opening_control.h>
#include <lightningd/options.h>
#include <lightningd/param.h>
#include <lightningd/peer_htlcs.h>
#include <unistd.h>
#include <wally_bip32.h>
@ -143,7 +144,7 @@ struct peer *peer_by_id(struct lightningd *ld, const struct pubkey *id)
struct peer *peer_from_json(struct lightningd *ld,
const char *buffer,
jsmntok_t *peeridtok)
const jsmntok_t *peeridtok)
{
struct pubkey peerid;
@ -940,38 +941,14 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
static void json_listpeers(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *leveltok;
struct getpeers_args *gpa = tal(cmd, struct getpeers_args);
jsmntok_t *idtok;
gpa->cmd = cmd;
gpa->specific_id = NULL;
if (!json_get_params(cmd, buffer, params,
"?id", &idtok,
"?level", &leveltok,
NULL)) {
if (!param(cmd, buffer, params,
p_opt("id", json_tok_pubkey, &gpa->specific_id),
p_opt("level", json_tok_loglevel, &gpa->ll),
NULL))
return;
}
if (idtok) {
gpa->specific_id = tal_arr(cmd, struct pubkey, 1);
if (!json_tok_pubkey(buffer, idtok, gpa->specific_id)) {
command_fail(cmd, LIGHTNINGD,
"id %.*s not valid",
idtok->end - idtok->start,
buffer + idtok->start);
return;
}
}
if (leveltok) {
gpa->ll = tal(gpa, enum log_level);
if (!json_tok_loglevel(buffer, leveltok, gpa->ll)) {
command_fail(cmd, LIGHTNINGD,
"Invalid level param");
return;
}
} else
gpa->ll = NULL;
/* Get peers from gossipd. */
subd_req(cmd, cmd->ld->gossip,
@ -1040,36 +1017,18 @@ command_find_channel(struct command *cmd,
static void json_close(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *idtok;
jsmntok_t *timeouttok;
jsmntok_t *forcetok;
const jsmntok_t *idtok;
struct peer *peer;
struct channel *channel;
unsigned int timeout = 30;
bool force = false;
if (!json_get_params(cmd, buffer, params,
"id", &idtok,
"?force", &forcetok,
"?timeout", &timeouttok,
NULL)) {
return;
}
unsigned int timeout;
bool force;
if (forcetok && !json_tok_bool(buffer, forcetok, &force)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Force '%.*s' must be true or false",
forcetok->end - forcetok->start,
buffer + forcetok->start);
if (!param(cmd, buffer, params,
p_req("id", json_tok_tok, &idtok),
p_opt_def("force", json_tok_bool, &force, false),
p_opt_def("timeout", json_tok_number, &timeout, 30),
NULL))
return;
}
if (timeouttok && !json_tok_number(buffer, timeouttok, &timeout)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Timeout '%.*s' is not a number",
timeouttok->end - timeouttok->start,
buffer + timeouttok->start);
return;
}
peer = peer_from_json(cmd->ld, buffer, idtok);
if (peer)
@ -1194,22 +1153,13 @@ static void gossip_peer_disconnected (struct subd *gossip,
static void json_disconnect(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *idtok;
struct pubkey id;
u8 *msg;
if (!json_get_params(cmd, buffer, params,
"id", &idtok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &id),
NULL))
return;
}
if (!json_tok_pubkey(buffer, idtok, &id)) {
command_fail(cmd, LIGHTNINGD, "id %.*s not valid",
idtok->end - idtok->start,
buffer + idtok->start);
return;
}
msg = towire_gossipctl_peer_disconnect(cmd, &id);
subd_req(cmd, cmd->ld->gossip, msg, -1, 0, gossip_peer_disconnected, cmd);
@ -1227,19 +1177,18 @@ AUTODATA(json_command, &disconnect_command);
static void json_sign_last_tx(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *peertok;
struct pubkey peerid;
struct peer *peer;
struct json_result *response = new_json_result(cmd);
u8 *linear;
struct channel *channel;
if (!json_get_params(cmd, buffer, params,
"id", &peertok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &peerid),
NULL))
return;
}
peer = peer_from_json(cmd->ld, buffer, peertok);
peer = peer_by_id(cmd->ld, &peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
@ -1274,17 +1223,16 @@ AUTODATA(json_command, &dev_sign_last_tx);
static void json_dev_fail(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *peertok;
struct pubkey peerid;
struct peer *peer;
struct channel *channel;
if (!json_get_params(cmd, buffer, params,
"id", &peertok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &peerid),
NULL))
return;
}
peer = peer_from_json(cmd->ld, buffer, peertok);
peer = peer_by_id(cmd->ld, &peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
@ -1320,18 +1268,17 @@ static void dev_reenable_commit_finished(struct subd *channeld UNUSED,
static void json_dev_reenable_commit(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *peertok;
struct pubkey peerid;
struct peer *peer;
u8 *msg;
struct channel *channel;
if (!json_get_params(cmd, buffer, params,
"id", &peertok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &peerid),
NULL))
return;
}
peer = peer_from_json(cmd->ld, buffer, peertok);
peer = peer_by_id(cmd->ld, &peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
@ -1408,33 +1355,30 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
static void json_dev_forget_channel(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
jsmntok_t *nodeidtok, *forcetok, *scidtok;
struct pubkey peerid;
struct peer *peer;
struct channel *channel;
struct short_channel_id scid;
struct short_channel_id *scid;
struct dev_forget_channel_cmd *forget = tal(cmd, struct dev_forget_channel_cmd);
forget->cmd = cmd;
if (!json_get_params(cmd, buffer, params,
"id", &nodeidtok,
"?short_channel_id", &scidtok,
"?force", &forcetok,
NULL)) {
return;
}
if (scidtok && !json_tok_short_channel_id(buffer, scidtok, &scid)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid short_channel_id '%.*s'",
scidtok->end - scidtok->start,
buffer + scidtok->start);
/* If &forget->force is used directly in p_opt_def() below then
* gcc 7.3.0 fails with:
* 'operation on forget->force may be undefined [-Werror=sequence-point]'
*
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86584
*
* Hence this indirection.
*/
bool *force = &forget->force;
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &peerid),
p_opt("short_channel_id", json_tok_short_channel_id, &scid),
p_opt_def("force", json_tok_bool, force, false),
NULL))
return;
}
forget->force = false;
if (forcetok)
json_tok_bool(buffer, forcetok, &forget->force);
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
peer = peer_by_id(cmd->ld, &peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
"Could not find channel with that peer");
@ -1443,10 +1387,10 @@ static void json_dev_forget_channel(struct command *cmd, const char *buffer,
forget->channel = NULL;
list_for_each(&peer->channels, channel, list) {
if (scidtok) {
if (scid) {
if (!channel->scid)
continue;
if (!short_channel_id_eq(channel->scid, &scid))
if (!short_channel_id_eq(channel->scid, scid))
continue;
}
if (forget->channel) {

2
lightningd/peer_control.h

@ -62,7 +62,7 @@ void delete_peer(struct peer *peer);
struct peer *peer_by_id(struct lightningd *ld, const struct pubkey *id);
struct peer *peer_from_json(struct lightningd *ld,
const char *buffer,
jsmntok_t *peeridtok);
const jsmntok_t *peeridtok);
/* The three ways peers enter from the network:
*

24
lightningd/peer_htlcs.c

@ -10,10 +10,12 @@
#include <gossipd/gen_gossip_wire.h>
#include <lightningd/chaintopology.h>
#include <lightningd/htlc_end.h>
#include <lightningd/json.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/param.h>
#include <lightningd/pay.h>
#include <lightningd/peer_control.h>
#include <lightningd/peer_htlcs.h>
@ -1651,30 +1653,24 @@ void notify_feerate_change(struct lightningd *ld)
static void json_dev_ignore_htlcs(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
jsmntok_t *nodeidtok, *ignoretok;
struct pubkey peerid;
struct peer *peer;
bool ignore;
if (!json_get_params(cmd, buffer, params,
"id", &nodeidtok,
"ignore", &ignoretok,
NULL)) {
if (!param(cmd, buffer, params,
p_req("id", json_tok_pubkey, &peerid),
p_req("ignore", json_tok_bool, &ignore),
NULL))
return;
}
peer = peer_from_json(cmd->ld, buffer, nodeidtok);
peer = peer_by_id(cmd->ld, &peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
"Could not find channel with that peer");
return;
}
peer->ignore_htlcs = ignore;
if (!json_tok_bool(buffer, ignoretok, &peer->ignore_htlcs)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid boolean '%.*s'",
ignoretok->end - ignoretok->start,
buffer + ignoretok->start);
return;
}
command_success(cmd, null_response(cmd));
}

10
lightningd/test/run-param.c

@ -37,13 +37,13 @@ void command_fail_detailed(struct command *cmd, int code,
}
/* AUTOGENERATED MOCKS START */
/* Generated stub for json_tok_newaddr */
bool json_tok_newaddr(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool *is_p2wpkh UNNEEDED)
{ fprintf(stderr, "json_tok_newaddr called!\n"); abort(); }
/* Generated stub for json_tok_wtx */
bool json_tok_wtx(struct wallet_tx *tx UNNEEDED, const char *buffer UNNEEDED,
bool json_tok_wtx(struct wallet_tx * tx UNNEEDED, const char * buffer UNNEEDED,
const jsmntok_t * sattok UNNEEDED)
{
abort();
}
{ fprintf(stderr, "json_tok_wtx called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
struct json {

12
wallet/test/run-wallet.c

@ -242,10 +242,6 @@ struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKE
struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED,
const void *bytes UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "json_escaped_string_ called!\n"); abort(); }
/* Generated stub for json_get_params */
bool json_get_params(struct command *cmd UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t param[] UNNEEDED, ...)
{ fprintf(stderr, "json_get_params called!\n"); abort(); }
/* Generated stub for json_object_end */
void json_object_end(struct json_result *ptr UNNEEDED)
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
@ -275,6 +271,10 @@ bool json_tok_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
bool json_tok_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "json_tok_short_channel_id called!\n"); abort(); }
/* Generated stub for json_tok_tok */
bool json_tok_tok(const char *buffer UNNEEDED, const jsmntok_t * tok UNNEEDED,
const jsmntok_t **out UNNEEDED)
{ fprintf(stderr, "json_tok_tok called!\n"); abort(); }
/* Generated stub for kill_uncommitted_channel */
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
const char *why UNNEEDED)
@ -312,6 +312,10 @@ struct outpointfilter *outpointfilter_new(tal_t *ctx UNNEEDED)
void outpointfilter_remove(struct outpointfilter *of UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED)
{ fprintf(stderr, "outpointfilter_remove called!\n"); abort(); }
/* Generated stub for param */
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
const jsmntok_t params[] UNNEEDED, ...)
{ fprintf(stderr, "param called!\n"); abort(); }
/* Generated stub for peer_accept_channel */
u8 *peer_accept_channel(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED,

43
wallet/walletrpc.c

@ -19,6 +19,7 @@
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/param.h>
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <wally_bip32.h>
@ -86,7 +87,7 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
static void json_withdraw(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *desttok, *sattok;
const jsmntok_t *desttok, *sattok;
struct withdrawal *withdraw = tal(cmd, struct withdrawal);
u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL);
@ -96,10 +97,13 @@ static void json_withdraw(struct command *cmd,
withdraw->cmd = cmd;
wtx_init(cmd, &withdraw->wtx);
if (!json_get_params(withdraw->cmd, buffer, params,
"destination", &desttok,
"satoshi", &sattok, NULL))
if (!param(cmd, buffer, params,
p_req("destination", json_tok_tok, &desttok),
p_req("satoshi", json_tok_tok, &sattok),
NULL))
return;
if (!json_tok_wtx(&withdraw->wtx, buffer, sattok))
return;
@ -217,26 +221,14 @@ static void json_newaddr(struct command *cmd, const char *buffer UNUSED,
struct json_result *response = new_json_result(cmd);
struct ext_key ext;
struct pubkey pubkey;
jsmntok_t *addrtype;
bool is_p2wpkh;
s64 keyidx;
char *out;
if (!json_get_params(cmd, buffer, params,
"?addresstype", &addrtype, NULL)) {
return;
}
if (!addrtype || json_tok_streq(buffer, addrtype, "p2sh-segwit"))
is_p2wpkh = false;
else if (json_tok_streq(buffer, addrtype, "bech32"))
is_p2wpkh = true;
else {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid address type "
"(expected bech32 or p2sh-segwit)");
if (!param(cmd, buffer, params,
p_opt_def("addresstype", json_tok_newaddr, &is_p2wpkh, true),
NULL))
return;
}
keyidx = wallet_get_newindex(cmd->ld);
if (keyidx < 0) {
@ -287,18 +279,15 @@ static void json_listaddrs(struct command *cmd,
struct json_result *response = new_json_result(cmd);
struct ext_key ext;
struct pubkey pubkey;
jsmntok_t *bip32tok;
u64 bip32_max_index;
if (!json_get_params(cmd, buffer, params,
"?bip32_max_index", &bip32tok,
NULL)) {
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)),
NULL))
return;
}
if (!bip32tok || !json_tok_u64(buffer, bip32tok, &bip32_max_index)) {
bip32_max_index = db_get_intvar(cmd->ld->wallet->db, "bip32_max_index", 0);
}
json_object_start(response, NULL);
json_array_start(response, "addresses");

Loading…
Cancel
Save