Browse Source

json-rpc: make commands return 'struct command_result *'.

Usually, this means they return 'command_param_failed()' if param()
fails, and changing 'command_success(); return;' to 'return
command_success()'.

Occasionally, it's more complex: there's a command_its_complicated()
for the case where we can't exactly determine what the status is,
but it should be considered a last resort.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
plugin-7
Rusty Russell 6 years ago
parent
commit
68bb36b210
  1. 6
      lightningd/chaintopology.c
  2. 30
      lightningd/connect_control.c
  3. 53
      lightningd/gossip_control.c
  4. 104
      lightningd/invoice.c
  5. 77
      lightningd/jsonrpc.c
  6. 2
      lightningd/jsonrpc.h
  7. 6
      lightningd/log.c
  8. 15
      lightningd/memdump.c
  9. 30
      lightningd/opening_control.c
  10. 9
      lightningd/options.c
  11. 35
      lightningd/pay.c
  12. 19
      lightningd/payalgo.c
  13. 110
      lightningd/peer_control.c
  14. 15
      lightningd/peer_htlcs.c
  15. 12
      lightningd/ping.c
  16. 7
      lightningd/plugin.c
  17. 6
      lightningd/test/run-invoice-select-inchan.c
  18. 6
      wallet/test/run-wallet.c
  19. 61
      wallet/walletrpc.c

6
lightningd/chaintopology.c

@ -463,7 +463,7 @@ u32 feerate_to_style(u32 feerate_perkw, enum feerate_style style)
abort();
}
static void json_feerates(struct command *cmd,
static struct command_result *json_feerates(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -477,7 +477,7 @@ static void json_feerates(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("style", param_feerate_style, &style),
NULL))
return;
return command_param_failed();
missing = false;
for (size_t i = 0; i < ARRAY_SIZE(feerates); i++) {
@ -520,7 +520,7 @@ static void json_feerates(struct command *cmd,
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command feerates_command = {

30
lightningd/connect_control.c

@ -65,16 +65,17 @@ static struct connect *find_connect(struct lightningd *ld,
return NULL;
}
static void connect_cmd_succeed(struct command *cmd, const struct pubkey *id)
static struct command_result *connect_cmd_succeed(struct command *cmd,
const struct pubkey *id)
{
struct json_stream *response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_pubkey(response, "id", id);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static void json_connect(struct command *cmd,
static struct command_result *json_connect(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -96,7 +97,7 @@ static void json_connect(struct command *cmd,
p_opt("host", param_string, &name),
p_opt("port", param_number, &port),
NULL))
return;
return command_param_failed();
/* Check for id@addrport form */
id_str = json_strdup(cmd, buffer, idtok);
@ -109,18 +110,16 @@ static void json_connect(struct command *cmd,
}
if (!json_to_pubkey(buffer, idtok, &id)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"id %.*s not valid",
json_tok_full_len(idtok),
json_tok_full(buffer, idtok));
return;
}
if (name && ataddr) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can't specify host as both xxx@yyy "
"and separate argument");
return;
}
/* Get parseable host if provided somehow */
@ -129,9 +128,8 @@ static void json_connect(struct command *cmd,
/* Port without host name? */
if (port && !name) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can't specify port without host");
return;
}
/* If we know about peer, see if it's already connected. */
@ -141,8 +139,7 @@ static void json_connect(struct command *cmd,
if (peer->uncommitted_channel
|| (channel && channel->connected)) {
connect_cmd_succeed(cmd, &id);
return;
return connect_cmd_succeed(cmd, &id);
}
}
@ -159,9 +156,10 @@ static void json_connect(struct command *cmd,
&& !cmd->ld->pure_tor_setup,
true,
&err_msg)) {
command_fail(cmd, LIGHTNINGD, "Host %s:%u not valid: %s",
name, *port, err_msg ? err_msg : "port is 0");
return;
return command_fail(cmd, LIGHTNINGD,
"Host %s:%u not valid: %s",
name, *port,
err_msg ? err_msg : "port is 0");
}
} else
addr = NULL;
@ -171,7 +169,7 @@ static void json_connect(struct command *cmd,
/* Leave this here for peer_connected or connect_failed. */
new_connect(cmd->ld, &id, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command connect_command = {

53
lightningd/gossip_control.c

@ -244,7 +244,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
command_success(cmd, response);
}
static void json_listnodes(struct command *cmd,
static struct command_result *json_listnodes(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -255,11 +255,11 @@ static void json_listnodes(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt("id", param_pubkey, &id),
NULL))
return;
return command_param_failed();
req = towire_gossip_getnodes_request(cmd, id);
subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command listnodes_command = {
@ -289,7 +289,7 @@ static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, con
command_success(cmd, response);
}
static void json_getroute(struct command *cmd,
static struct command_result *json_getroute(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -318,7 +318,7 @@ static void json_getroute(struct command *cmd,
p_opt("seed", param_tok, &seedtok),
p_opt_def("fuzzpercent", param_percent, &fuzz, 75.0),
NULL))
return;
return command_param_failed();
/* Convert from percentage */
*fuzz = *fuzz / 100.0;
@ -338,7 +338,7 @@ static void json_getroute(struct command *cmd,
*msatoshi, *riskfactor * 1000,
*cltv, fuzz, &seed);
subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command getroute_command = {
@ -399,7 +399,7 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
command_success(cmd, response);
}
static void json_listchannels(struct command *cmd,
static struct command_result *json_listchannels(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -409,12 +409,12 @@ static void json_listchannels(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt("short_channel_id", param_short_channel_id, &id),
NULL))
return;
return command_param_failed();
req = towire_gossip_getchannels_request(cmd, id);
subd_req(cmd->ld->gossip, cmd->ld->gossip,
req, -1, 0, json_listchannels_reply, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command listchannels_command = {
@ -450,7 +450,7 @@ static void json_scids_reply(struct subd *gossip UNUSED, const u8 *reply,
command_success(cmd, response);
}
static void json_dev_query_scids(struct command *cmd,
static struct command_result *json_dev_query_scids(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -466,17 +466,16 @@ static void json_dev_query_scids(struct command *cmd,
p_req("id", param_pubkey, &id),
p_req("scids", param_array, &scidstok),
NULL))
return;
return command_param_failed();
scids = tal_arr(cmd, struct short_channel_id, scidstok->size);
end = json_next(scidstok);
for (i = 0, t = scidstok + 1; t < end; t = json_next(t), i++) {
if (!json_to_short_channel_id(buffer, t, &scids[i])) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"scid %zu '%.*s' is not an scid",
i, json_tok_full_len(t),
json_tok_full(buffer, t));
return;
}
}
@ -484,7 +483,7 @@ static void json_dev_query_scids(struct command *cmd,
msg = towire_gossip_query_scids(cmd, id, scids);
subd_req(cmd->ld->gossip, cmd->ld->gossip,
take(msg), -1, 0, json_scids_reply, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_query_scids_command = {
@ -494,7 +493,8 @@ static const struct json_command dev_query_scids_command = {
};
AUTODATA(json_command, &dev_query_scids_command);
static void json_dev_send_timestamp_filter(struct command *cmd,
static struct command_result *
json_dev_send_timestamp_filter(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -508,14 +508,14 @@ static void json_dev_send_timestamp_filter(struct command *cmd,
p_req("first", param_number, &first),
p_req("range", param_number, &range),
NULL))
return;
return command_param_failed();
log_debug(cmd->ld->log, "Setting timestamp range %u+%u", *first, *range);
/* Tell gossipd, since this is a gossip query. */
msg = towire_gossip_send_timestamp_filter(NULL, id, *first, *range);
subd_send_msg(cmd->ld->gossip, take(msg));
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command dev_send_timestamp_filter = {
@ -564,7 +564,7 @@ static void json_channel_range_reply(struct subd *gossip UNUSED, const u8 *reply
command_success(cmd, response);
}
static void json_dev_query_channel_range(struct command *cmd,
static struct command_result *json_dev_query_channel_range(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -578,13 +578,13 @@ static void json_dev_query_channel_range(struct command *cmd,
p_req("first", param_number, &first),
p_req("num", param_number, &num),
NULL))
return;
return command_param_failed();
/* Tell gossipd, since this is a gossip query. */
msg = towire_gossip_query_channel_range(cmd, id, *first, *num);
subd_req(cmd->ld->gossip, cmd->ld->gossip,
take(msg), -1, 0, json_channel_range_reply, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_query_channel_range_command = {
@ -594,7 +594,8 @@ static const struct json_command dev_query_channel_range_command = {
};
AUTODATA(json_command, &dev_query_channel_range_command);
static void json_dev_set_max_scids_encode_size(struct command *cmd,
static struct command_result *
json_dev_set_max_scids_encode_size(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -605,12 +606,12 @@ static void json_dev_set_max_scids_encode_size(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("max", param_number, &max),
NULL))
return;
return command_param_failed();
msg = towire_gossip_dev_set_max_scids_encode_size(NULL, *max);
subd_send_msg(cmd->ld->gossip, take(msg));
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command dev_set_max_scids_encode_size = {
@ -620,17 +621,17 @@ static const struct json_command dev_set_max_scids_encode_size = {
};
AUTODATA(json_command, &dev_set_max_scids_encode_size);
static void json_dev_suppress_gossip(struct command *cmd,
static struct command_result *json_dev_suppress_gossip(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
subd_send_msg(cmd->ld->gossip, take(towire_gossip_dev_suppress(NULL)));
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command dev_suppress_gossip = {

104
lightningd/invoice.c

@ -62,7 +62,8 @@ static void json_add_invoice(struct json_stream *response,
json_object_end(response);
}
static void tell_waiter(struct command *cmd, const struct invoice *inv)
static struct command_result *tell_waiter(struct command *cmd,
const struct invoice *inv)
{
struct json_stream *response;
const struct invoice_details *details;
@ -71,13 +72,13 @@ static void tell_waiter(struct command *cmd, const struct invoice *inv)
if (details->state == PAID) {
response = json_stream_success(cmd);
json_add_invoice(response, details);
command_success(cmd, response);
return command_success(cmd, response);
} else {
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
response = json_stream_fail(cmd, -2,
"invoice expired during wait");
json_add_invoice(response, details);
command_failed(cmd, response);
return command_failed(cmd, response);
}
}
@ -111,8 +112,9 @@ static bool hsm_sign_b11(const u5 *u5bytes,
return true;
}
static bool parse_fallback(struct command *cmd,
const char *buffer, const jsmntok_t *fallback,
static struct command_result *parse_fallback(struct command *cmd,
const char *buffer,
const jsmntok_t *fallback,
const u8 **fallback_script)
{
@ -124,15 +126,14 @@ static bool parse_fallback(struct command *cmd,
buffer, fallback,
fallback_script);
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, LIGHTNINGD, "Fallback address not valid");
return false;
return command_fail(cmd, LIGHTNINGD,
"Fallback address not valid");
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Fallback address does not match our network %s",
get_chainparams(cmd->ld)->network_name);
return false;
}
return true;
return NULL;
}
/* BOLT11 struct wants an array of arrays (can provide multiple routes) */
@ -291,7 +292,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
command_success(info->cmd, response);
}
static void json_invoice(struct command *cmd,
static struct command_result *json_invoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -316,23 +317,21 @@ static void json_invoice(struct command *cmd,
p_opt("fallbacks", param_array, &fallbacks),
p_opt("preimage", param_tok, &preimagetok),
NULL))
return;
return command_param_failed();
if (strlen(info->label->s) > INVOICE_MAX_LABEL_LEN) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Label '%s' over %u bytes", info->label->s,
INVOICE_MAX_LABEL_LEN);
return;
}
if (strlen(desc_val) >= BOLT11_FIELD_BYTE_LIMIT) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Descriptions greater than %d bytes "
"not yet supported "
"(description length %zu)",
BOLT11_FIELD_BYTE_LIMIT,
strlen(desc_val));
return;
}
if (fallbacks) {
@ -340,9 +339,11 @@ static void json_invoice(struct command *cmd,
fallback_scripts = tal_arr(cmd, const u8 *, 0);
for (i = fallbacks + 1; i < end; i = json_next(i)) {
if (!parse_fallback(cmd, buffer, i,
tal_arr_expand(&fallback_scripts)))
return;
struct command_result *r;
r = parse_fallback(cmd, buffer, i,
tal_arr_expand(&fallback_scripts));
if (r)
return r;
}
}
@ -352,9 +353,8 @@ static void json_invoice(struct command *cmd,
preimagetok->end - preimagetok->start,
&info->payment_preimage,
sizeof(info->payment_preimage))) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"preimage must be 64 hex digits");
return;
}
} else
/* Generate random secret preimage. */
@ -381,7 +381,7 @@ static void json_invoice(struct command *cmd,
take(towire_gossip_get_incoming_channels(NULL)),
-1, 0, gossipd_incoming_channels_reply, info);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command invoice_command = {
@ -416,7 +416,7 @@ static void json_add_invoices(struct json_stream *response,
}
}
static void json_listinvoices(struct command *cmd,
static struct command_result *json_listinvoices(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -427,14 +427,14 @@ static void json_listinvoices(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt("label", param_label, &label),
NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_array_start(response, "invoices");
json_add_invoices(response, wallet, label);
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listinvoices_command = {
@ -444,7 +444,7 @@ static const struct json_command listinvoices_command = {
};
AUTODATA(json_command, &listinvoices_command);
static void json_delinvoice(struct command *cmd,
static struct command_result *json_delinvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -460,11 +460,10 @@ static void json_delinvoice(struct command *cmd,
p_req("label", param_label, &label),
p_req("status", param_string, &status),
NULL))
return;
return command_param_failed();
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, LIGHTNINGD, "Unknown invoice");
return;
return command_fail(cmd, LIGHTNINGD, "Unknown invoice");
}
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
@ -473,22 +472,21 @@ static void json_delinvoice(struct command *cmd,
* might not make sense if it changed! */
actual_status = invoice_status_str(details);
if (!streq(actual_status, status)) {
command_fail(cmd, LIGHTNINGD, "Invoice status is %s not %s",
return command_fail(cmd, LIGHTNINGD,
"Invoice status is %s not %s",
actual_status, status);
return;
}
if (!wallet_invoice_delete(wallet, i)) {
log_broken(cmd->ld->log,
"Error attempting to remove invoice %"PRIu64,
i.id);
command_fail(cmd, LIGHTNINGD, "Database error");
return;
return command_fail(cmd, LIGHTNINGD, "Database error");
}
response = json_stream_success(cmd);
json_add_invoice(response, details);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command delinvoice_command = {
@ -498,7 +496,7 @@ static const struct json_command delinvoice_command = {
};
AUTODATA(json_command, &delinvoice_command);
static void json_delexpiredinvoice(struct command *cmd,
static struct command_result *json_delexpiredinvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -509,11 +507,11 @@ static void json_delexpiredinvoice(struct command *cmd,
p_opt_def("maxexpirytime", param_u64, &maxexpirytime,
time_now().ts.tv_sec),
NULL))
return;
return command_param_failed();
wallet_invoice_delete_expired(cmd->ld->wallet, *maxexpirytime);
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command delexpiredinvoice_command = {
"delexpiredinvoice",
@ -522,7 +520,7 @@ static const struct json_command delexpiredinvoice_command = {
};
AUTODATA(json_command, &delexpiredinvoice_command);
static void json_autocleaninvoice(struct command *cmd,
static struct command_result *json_autocleaninvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -534,11 +532,11 @@ static void json_autocleaninvoice(struct command *cmd,
p_opt_def("cycle_seconds", param_u64, &cycle, 3600),
p_opt_def("expired_by", param_u64, &exby, 86400),
NULL))
return;
return command_param_failed();
wallet_invoice_autoclean(cmd->ld->wallet, *cycle, *exby);
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command autocleaninvoice_command = {
"autocleaninvoice",
@ -549,7 +547,7 @@ static const struct json_command autocleaninvoice_command = {
};
AUTODATA(json_command, &autocleaninvoice_command);
static void json_waitanyinvoice(struct command *cmd,
static struct command_result *json_waitanyinvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -560,7 +558,7 @@ static void json_waitanyinvoice(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt_def("lastpay_index", param_u64, &pay_index, 0),
NULL))
return;
return command_param_failed();
/* Set command as pending. We do not know if
* wallet_invoice_waitany will return immediately
@ -570,6 +568,8 @@ static void json_waitanyinvoice(struct command *cmd,
/* Find next paid invoice. */
wallet_invoice_waitany(cmd, wallet, *pay_index,
&wait_on_invoice, (void*) cmd);
return command_its_complicated();
}
static const struct json_command waitanyinvoice_command = {
@ -585,7 +585,7 @@ AUTODATA(json_command, &waitanyinvoice_command);
* already been received or it may add the `cmd` to the list of
* waiters, if the payment is still pending.
*/
static void json_waitinvoice(struct command *cmd,
static struct command_result *json_waitinvoice(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -598,23 +598,22 @@ static void json_waitinvoice(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("label", param_label, &label),
NULL))
return;
return command_param_failed();
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, LIGHTNINGD, "Label not found");
return;
return command_fail(cmd, LIGHTNINGD, "Label not found");
}
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
/* If paid or expired return immediately */
if (details->state == PAID || details->state == EXPIRED) {
tell_waiter(cmd, &i);
return;
return tell_waiter(cmd, &i);
} else {
/* There is an unpaid one matching, let's wait... */
command_still_pending(cmd);
wallet_invoice_waitone(cmd, wallet, i,
&wait_on_invoice, (void *) cmd);
return command_its_complicated();
}
}
@ -660,7 +659,7 @@ static void json_add_fallback(struct json_stream *response,
json_object_end(response);
}
static void json_decodepay(struct command *cmd,
static struct command_result *json_decodepay(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -674,13 +673,12 @@ static void json_decodepay(struct command *cmd,
p_req("bolt11", param_string, &str),
p_opt("description", param_string, &desc),
NULL))
return;
return command_param_failed();
b11 = bolt11_decode(cmd, str, desc, &fail);
if (!b11) {
command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
return;
return command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
}
response = json_stream_success(cmd);
@ -766,7 +764,7 @@ static void json_decodepay(struct command *cmd,
type_to_string(cmd, secp256k1_ecdsa_signature,
&b11->sig));
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command decodepay_command = {

77
lightningd/jsonrpc.c

@ -147,7 +147,7 @@ static void destroy_jcon(struct json_connection *jcon)
tal_free(jcon->log);
}
static void json_help(struct command *cmd,
static struct command_result *json_help(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params);
@ -166,7 +166,7 @@ static const struct json_command help_command = {
};
AUTODATA(json_command, &help_command);
static void json_stop(struct command *cmd,
static struct command_result *json_stop(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -174,13 +174,13 @@ static void json_stop(struct command *cmd,
struct json_stream *response;
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
/* This can't have closed yet! */
cmd->jcon->stop = true;
response = json_stream_success(cmd);
json_add_string(response, NULL, "Shutting down");
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command stop_command = {
@ -191,7 +191,7 @@ static const struct json_command stop_command = {
AUTODATA(json_command, &stop_command);
#if DEVELOPER
static void json_rhash(struct command *cmd,
static struct command_result *json_rhash(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNUSED,
const jsmntok_t *params)
@ -202,7 +202,7 @@ static void json_rhash(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("secret", param_sha256, &secret),
NULL))
return;
return command_param_failed();
/* Hash in place. */
sha256(secret, secret, sizeof(*secret));
@ -210,7 +210,7 @@ static void json_rhash(struct command *cmd,
json_object_start(response, NULL);
json_add_hex(response, "rhash", secret, sizeof(*secret));
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command dev_rhash_command = {
@ -231,7 +231,7 @@ static void slowcmd_finish(struct slowcmd *sc)
json_object_start(sc->js, NULL);
json_add_num(sc->js, "msec", *sc->msec);
json_object_end(sc->js);
command_success(sc->cmd, sc->js);
was_pending(command_success(sc->cmd, sc->js));
}
static void slowcmd_start(struct slowcmd *sc)
@ -241,7 +241,7 @@ static void slowcmd_start(struct slowcmd *sc)
slowcmd_finish, sc);
}
static void json_slowcmd(struct command *cmd,
static struct command_result *json_slowcmd(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNUSED,
const jsmntok_t *params)
@ -252,10 +252,10 @@ static void json_slowcmd(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt_def("msec", param_number, &sc->msec, 1000),
NULL))
return;
return command_param_failed();
new_reltimer(&cmd->ld->timers, sc, time_from_msec(0), slowcmd_start, sc);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_slowcmd_command = {
@ -265,13 +265,13 @@ static const struct json_command dev_slowcmd_command = {
};
AUTODATA(json_command, &dev_slowcmd_command);
static void json_crash(struct command *cmd UNUSED,
static struct command_result *json_crash(struct command *cmd UNUSED,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
fatal("Crash at user request");
}
@ -325,7 +325,7 @@ static void json_add_help_command(struct command *cmd,
}
static void json_help(struct command *cmd,
static struct command_result *json_help(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -337,7 +337,7 @@ static void json_help(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt("command", param_tok, &cmdtok),
NULL))
return;
return command_param_failed();
if (cmdtok) {
for (size_t i = 0; i < tal_count(commands); i++) {
@ -347,11 +347,10 @@ static void json_help(struct command *cmd,
goto done;
}
}
command_fail(cmd, JSONRPC2_METHOD_NOT_FOUND,
return command_fail(cmd, JSONRPC2_METHOD_NOT_FOUND,
"Unknown command '%.*s'",
json_tok_full_len(cmdtok),
json_tok_full(buffer, cmdtok));
return;
}
response = json_stream_success(cmd);
@ -364,7 +363,7 @@ static void json_help(struct command *cmd,
json_object_end(response);
done:
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command *find_cmd(const struct jsonrpc *rpc,
@ -528,15 +527,19 @@ struct json_stream *json_stream_fail(struct command *cmd,
return r;
}
static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
/* We return struct command_result so command_fail return value has a natural
* sink; we don't actually use the result. */
static struct command_result *
parse_request(struct json_connection *jcon, const jsmntok_t tok[])
{
const jsmntok_t *method, *id, *params;
struct command *c;
struct command_result *res;
if (tok[0].type != JSMN_OBJECT) {
json_command_malformed(jcon, "null",
"Expected {} for json command");
return;
return NULL;
}
method = json_get_member(jcon->buffer, tok, "method");
@ -545,12 +548,12 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
if (!id) {
json_command_malformed(jcon, "null", "No id");
return;
return NULL;
}
if (id->type != JSMN_STRING && id->type != JSMN_PRIMITIVE) {
json_command_malformed(jcon, "null",
"Expected string/primitive for id");
return;
return NULL;
}
/* Allocate the command off of the `jsonrpc` object and not
@ -568,41 +571,45 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
tal_add_destructor(c, destroy_command);
if (!method || !params) {
command_fail(c, JSONRPC2_INVALID_REQUEST,
return command_fail(c, JSONRPC2_INVALID_REQUEST,
method ? "No params" : "No method");
return;
}
if (method->type != JSMN_STRING) {
command_fail(c, JSONRPC2_INVALID_REQUEST,
return command_fail(c, JSONRPC2_INVALID_REQUEST,
"Expected string for method");
return;
}
c->json_cmd = find_cmd(jcon->ld->jsonrpc, jcon->buffer, method);
if (!c->json_cmd) {
command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
return command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
"Unknown command '%.*s'",
json_tok_full_len(method),
json_tok_full(jcon->buffer, method));
return;
}
if (c->json_cmd->deprecated && !deprecated_apis) {
command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
return command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
"Command '%.*s' is deprecated",
method->end - method->start,
jcon->buffer + method->start);
return;
}
db_begin_transaction(jcon->ld->wallet->db);
c->json_cmd->dispatch(c, jcon->buffer, tok, params);
res = c->json_cmd->dispatch(c, jcon->buffer, tok, params);
db_commit_transaction(jcon->ld->wallet->db);
assert(res == &param_failed
|| res == &complete
|| res == &pending
|| res == &unknown);
/* If they didn't complete it, they must call command_still_pending.
* If they completed it, it's freed already. */
if (res == &pending)
assert(c->pending);
list_for_each(&jcon->commands, c, list)
assert(c->pending);
return res;
}
/* Mutual recursion */
@ -1002,7 +1009,7 @@ static void destroy_command_canary(struct command *cmd, bool *failed)
*failed = true;
}
static void json_check(struct command *cmd,
static struct command_result *json_check(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1022,7 +1029,7 @@ static void json_check(struct command *cmd,
p_req("command_to_check", param_command, &name_tok),
p_opt_any(),
NULL))
return;
return command_param_failed();
/* Point name_tok to the name, not the value */
if (params->type == JSMN_OBJECT)
@ -1036,13 +1043,13 @@ static void json_check(struct command *cmd,
cmd->json_cmd->dispatch(cmd, buffer, mod_params, mod_params);
if (failed)
return;
return command_its_complicated();
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "command_to_check", cmd->json_cmd->name);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command check_command = {

2
lightningd/jsonrpc.h

@ -49,7 +49,7 @@ struct command_result;
struct json_command {
const char *name;
void (*dispatch)(struct command *,
struct command_result *(*dispatch)(struct command *,
const char *buffer,
const jsmntok_t *obj,
const jsmntok_t *params);

6
lightningd/log.c

@ -728,7 +728,7 @@ struct command_result *param_loglevel(struct command *cmd,
return NULL;
}
static void json_getlog(struct command *cmd,
static struct command_result *json_getlog(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t * params)
@ -740,7 +740,7 @@ static void json_getlog(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt_def("level", param_loglevel, &minlevel, LOG_INFORM),
NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
@ -749,7 +749,7 @@ static void json_getlog(struct command *cmd,
json_add_num(response, "bytes_max", (unsigned int) log_max_mem(lr));
json_add_log(response, lr, *minlevel);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command getlog_command = {

15
lightningd/memdump.c

@ -62,7 +62,7 @@ static void add_memdump(struct json_stream *response,
json_array_end(response);
}
static void json_memdump(struct command *cmd,
static struct command_result *json_memdump(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -70,12 +70,12 @@ static void json_memdump(struct command *cmd,
struct json_stream *response;
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
add_memdump(response, NULL, NULL, cmd);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command dev_memdump_command = {
@ -284,18 +284,17 @@ void opening_memleak_done(struct command *cmd, struct subd *leaker)
}
}
static void json_memleak(struct command *cmd,
static struct command_result *json_memleak(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
if (!getenv("LIGHTNINGD_DEV_MEMLEAK")) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Leak detection needs $LIGHTNINGD_DEV_MEMLEAK");
return;
}
/* For simplicity, we mark pending, though an error may complete it
@ -304,6 +303,8 @@ static void json_memleak(struct command *cmd,
/* This calls opening_memleak_done() async when all done. */
opening_dev_memleak(cmd);
return command_its_complicated();
}
static const struct json_command dev_memleak_command = {

30
lightningd/opening_control.c

@ -762,7 +762,7 @@ void opening_peer_no_active_channels(struct peer *peer)
/**
* json_fund_channel - Entrypoint for funding a channel
*/
static void json_fund_channel(struct command *cmd,
static struct command_result *json_fund_channel(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -787,47 +787,43 @@ static void json_fund_channel(struct command *cmd,
p_opt("feerate", param_feerate, &feerate_per_kw),
p_opt_def("announce", param_bool, &announce_channel, true),
NULL))
return;
return command_param_failed();
res = param_wtx(&fc->wtx, buffer, sattok, max_funding_satoshi);
if (res)
return;
return res;
if (!feerate_per_kw) {
feerate_per_kw = tal(cmd, u32);
*feerate_per_kw = opening_feerate(cmd->ld->topology);
if (!*feerate_per_kw) {
command_fail(cmd, LIGHTNINGD, "Cannot estimate fees");
return;
return command_fail(cmd, LIGHTNINGD,
"Cannot estimate fees");
}
}
if (*feerate_per_kw < feerate_floor()) {
command_fail(cmd, LIGHTNINGD, "Feerate below feerate floor");
return;
return command_fail(cmd, LIGHTNINGD,
"Feerate below feerate floor");
}
peer = peer_by_id(cmd->ld, id);
if (!peer) {
command_fail(cmd, LIGHTNINGD, "Unknown peer");
return;
return command_fail(cmd, LIGHTNINGD, "Unknown peer");
}
channel = peer_active_channel(peer);
if (channel) {
command_fail(cmd, LIGHTNINGD, "Peer already %s",
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
channel_state_name(channel));
return;
}
if (!peer->uncommitted_channel) {
command_fail(cmd, LIGHTNINGD, "Peer not connected");
return;
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
}
if (peer->uncommitted_channel->fc) {
command_fail(cmd, LIGHTNINGD, "Already funding channel");
return;
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
}
/* FIXME: Support push_msat? */
@ -842,7 +838,7 @@ static void json_fund_channel(struct command *cmd,
res = wtx_select_utxos(&fc->wtx, *feerate_per_kw,
BITCOIN_SCRIPTPUBKEY_P2WSH_LEN);
if (res)
return;
return res;
assert(fc->wtx.amount <= max_funding_satoshi);
@ -862,7 +858,7 @@ static void json_fund_channel(struct command *cmd,
/* Openingd will either succeed, or fail, or tell us the other side
* funded first. */
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command fund_channel_command = {

9
lightningd/options.c

@ -1046,7 +1046,7 @@ static void add_config(struct lightningd *ld,
tal_free(name0);
}
static void json_listconfigs(struct command *cmd,
static struct command_result *json_listconfigs(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1058,7 +1058,7 @@ static void json_listconfigs(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt("config", param_tok, &configtok),
NULL))
return;
return command_param_failed();
if (!configtok) {
response = json_stream_success(cmd);
@ -1097,14 +1097,13 @@ static void json_listconfigs(struct command *cmd,
}
if (configtok && !response) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Unknown config option '%.*s'",
json_tok_full_len(configtok),
json_tok_full(buffer, configtok));
return;
}
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listconfigs_command = {

35
lightningd/pay.c

@ -941,7 +941,7 @@ static void json_sendpay_on_resolve(const struct sendpay_result* r,
json_waitsendpay_on_resolve(r, cmd);
}
static void json_sendpay(struct command *cmd,
static struct command_result *json_sendpay(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -960,7 +960,7 @@ static void json_sendpay(struct command *cmd,
p_opt("description", param_escaped_string, &description),
p_opt("msatoshi", param_u64, &msatoshi),
NULL))
return;
return command_param_failed();
end = json_next(routetok);
n_hops = 0;
@ -978,7 +978,7 @@ static void json_sendpay(struct command *cmd,
p_req("delay", param_number, &delay),
p_req("channel", param_short_channel_id, &channel),
NULL))
return;
return command_param_failed();
tal_resize(&route, n_hops + 1);
@ -990,8 +990,7 @@ static void json_sendpay(struct command *cmd,
}
if (n_hops == 0) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
return;
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
}
/* The given msatoshi is the actual payment that the payee is
@ -1002,10 +1001,9 @@ static void json_sendpay(struct command *cmd,
if (msatoshi) {
if (!(*msatoshi <= route[n_hops-1].amount &&
route[n_hops-1].amount <= 2 * *msatoshi)) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi %"PRIu64" out of range",
*msatoshi);
return;
}
}
@ -1013,7 +1011,8 @@ static void json_sendpay(struct command *cmd,
msatoshi ? *msatoshi : route[n_hops-1].amount,
description,
&json_sendpay_on_resolve, cmd))
command_still_pending(cmd);
return command_still_pending(cmd);
return command_its_complicated();
}
static const struct json_command sendpay_command = {
@ -1028,7 +1027,7 @@ static void waitsendpay_timeout(struct command *cmd)
command_fail(cmd, PAY_IN_PROGRESS, "Timed out while waiting");
}
static void json_waitsendpay(struct command *cmd,
static struct command_result *json_waitsendpay(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1040,15 +1039,15 @@ static void json_waitsendpay(struct command *cmd,
p_req("payment_hash", param_sha256, &rhash),
p_opt("timeout", param_number, &timeout),
NULL))
return;
return command_param_failed();
if (!wait_payment(cmd, cmd->ld, rhash, &json_waitsendpay_on_resolve, cmd))
return;
return command_its_complicated();
if (timeout)
new_reltimer(&cmd->ld->timers, cmd, time_from_sec(*timeout),
&waitsendpay_timeout, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command waitsendpay_command = {
@ -1059,7 +1058,7 @@ static const struct json_command waitsendpay_command = {
};
AUTODATA(json_command, &waitsendpay_command);
static void json_listpayments(struct command *cmd,
static struct command_result *json_listpayments(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1073,13 +1072,12 @@ static void json_listpayments(struct command *cmd,
p_opt("bolt11", param_string, &b11str),
p_opt("payment_hash", param_sha256, &rhash),
NULL))
return;
return command_param_failed();
if (rhash && b11str) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can only specify one of"
" {bolt11} or {payment_hash}");
return;
}
if (b11str) {
@ -1088,9 +1086,8 @@ static void json_listpayments(struct command *cmd,
b11 = bolt11_decode(cmd, b11str, NULL, &fail);
if (!b11) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid bolt11: %s", fail);
return;
}
rhash = &b11->payment_hash;
}
@ -1109,7 +1106,7 @@ static void json_listpayments(struct command *cmd,
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listpayments_command = {

19
lightningd/payalgo.c

@ -592,7 +592,7 @@ static void json_pay_stop_retrying(struct pay *pay)
json_pay_failure(pay, sr);
}
static void json_pay(struct command *cmd,
static struct command_result *json_pay(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -619,13 +619,12 @@ static void json_pay(struct command *cmd,
cmd->ld->config.locktime_max),
p_opt_def("exemptfee", param_number, &exemptfee, 5000),
NULL))
return;
return command_param_failed();
b11 = bolt11_decode(pay, b11str, desc, &fail);
if (!b11) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid bolt11: %s", fail);
return;
}
pay->cmd = cmd;
@ -638,16 +637,14 @@ static void json_pay(struct command *cmd,
if (b11->msatoshi) {
if (msatoshi) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter unnecessary");
return;
}
msatoshi = b11->msatoshi;
} else {
if (!msatoshi) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter required");
return;
}
}
pay->msatoshi = *msatoshi;
@ -655,12 +652,11 @@ static void json_pay(struct command *cmd,
pay->maxfeepercent = *maxfeepercent;
if (*maxdelay < pay->min_final_cltv_expiry) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"maxdelay (%u) must be greater than "
"min_final_cltv_expiry (%"PRIu32") of "
"invoice",
*maxdelay, pay->min_final_cltv_expiry);
return;
}
pay->maxdelay = *maxdelay;
@ -688,11 +684,12 @@ static void json_pay(struct command *cmd,
if (json_pay_try(pay))
command_still_pending(cmd);
else
return;
return command_its_complicated();
/* Set up timeout. */
new_reltimer(&cmd->ld->timers, pay, time_from_sec(*retryfor),
&json_pay_stop_retrying, pay);
return command_its_complicated();
}
static const struct json_command pay_command = {

110
lightningd/peer_control.c

@ -803,7 +803,7 @@ static void json_add_peer(struct lightningd *ld,
json_object_end(response);
}
static void json_listpeers(struct command *cmd,
static struct command_result *json_listpeers(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -817,7 +817,7 @@ static void json_listpeers(struct command *cmd,
p_opt("id", param_pubkey, &specific_id),
p_opt("level", param_loglevel, &ll),
NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
@ -832,7 +832,7 @@ static void json_listpeers(struct command *cmd,
}
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listpeers_command = {
@ -891,7 +891,7 @@ command_find_channel(struct command *cmd,
}
}
static void json_close(struct command *cmd,
static struct command_result *json_close(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -907,7 +907,7 @@ static void json_close(struct command *cmd,
p_opt_def("force", param_bool, &force, false),
p_opt_def("timeout", param_number, &timeout, 30),
NULL))
return;
return command_param_failed();
peer = peer_from_json(cmd->ld, buffer, idtok);
if (peer)
@ -915,7 +915,7 @@ static void json_close(struct command *cmd,
else {
channel = command_find_channel(cmd, buffer, idtok);
if (!channel)
return;
return command_its_complicated();
}
if (!channel && peer) {
@ -924,12 +924,10 @@ static void json_close(struct command *cmd,
/* Easy case: peer can simply be forgotten. */
kill_uncommitted_channel(uc, "close command called");
command_success(cmd, null_response(cmd));
return;
return command_success(cmd, null_response(cmd));
}
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Peer has no active channel");
return;
}
/* Normal case.
@ -941,9 +939,8 @@ static void json_close(struct command *cmd,
channel->state != CHANNELD_AWAITING_LOCKIN &&
channel->state != CHANNELD_SHUTTING_DOWN &&
channel->state != CLOSINGD_SIGEXCHANGE) {
command_fail(cmd, LIGHTNINGD, "Channel is in state %s",
return command_fail(cmd, LIGHTNINGD, "Channel is in state %s",
channel_state_name(channel));
return;
}
/* If normal or locking in, transition to shutting down
@ -963,7 +960,7 @@ static void json_close(struct command *cmd,
register_close_command(cmd->ld, cmd, channel, *timeout, *force);
/* Wait until close drops down to chain. */
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command close_command = {
@ -1035,7 +1032,7 @@ void load_channels_from_wallet(struct lightningd *ld)
htlcs_reconnect(ld, &ld->htlcs_in, &ld->htlcs_out);
}
static void json_disconnect(struct command *cmd,
static struct command_result *json_disconnect(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1049,32 +1046,28 @@ static void json_disconnect(struct command *cmd,
p_req("id", param_pubkey, &id),
p_opt_def("force", param_bool, &force, false),
NULL))
return;
return command_param_failed();
peer = peer_by_id(cmd->ld, id);
if (!peer) {
command_fail(cmd, LIGHTNINGD, "Peer not connected");
return;
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
}
channel = peer_active_channel(peer);
if (channel) {
if (*force) {
channel_fail_transient(channel,
"disconnect command force=true");
command_success(cmd, null_response(cmd));
return;
return command_success(cmd, null_response(cmd));
}
command_fail(cmd, LIGHTNINGD, "Peer is in state %s",
return command_fail(cmd, LIGHTNINGD, "Peer is in state %s",
channel_state_name(channel));
return;
}
if (!peer->uncommitted_channel) {
command_fail(cmd, LIGHTNINGD, "Peer not connected");
return;
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
}
kill_uncommitted_channel(peer->uncommitted_channel,
"disconnect command");
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command disconnect_command = {
@ -1084,7 +1077,7 @@ static const struct json_command disconnect_command = {
};
AUTODATA(json_command, &disconnect_command);
static void json_getinfo(struct command *cmd,
static struct command_result *json_getinfo(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1096,7 +1089,7 @@ static void json_getinfo(struct command *cmd,
inactive_channels = 0, num_peers = 0;
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
@ -1148,7 +1141,7 @@ static void json_getinfo(struct command *cmd,
json_add_u64(response, "msatoshi_fees_collected",
wallet_total_forward_fees(cmd->ld->wallet));
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command getinfo_command = {
@ -1159,7 +1152,7 @@ static const struct json_command getinfo_command = {
AUTODATA(json_command, &getinfo_command);
#if DEVELOPER
static void json_sign_last_tx(struct command *cmd,
static struct command_result *json_sign_last_tx(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1173,19 +1166,17 @@ static void json_sign_last_tx(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("id", param_pubkey, &peerid),
NULL))
return;
return command_param_failed();
peer = peer_by_id(cmd->ld, peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
return;
}
channel = peer_active_channel(peer);
if (!channel) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find active channel");
return;
}
response = json_stream_success(cmd);
@ -1198,7 +1189,7 @@ static void json_sign_last_tx(struct command *cmd,
json_object_start(response, NULL);
json_add_hex_talarr(response, "tx", linear);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command dev_sign_last_tx = {
@ -1208,7 +1199,7 @@ static const struct json_command dev_sign_last_tx = {
};
AUTODATA(json_command, &dev_sign_last_tx);
static void json_dev_fail(struct command *cmd,
static struct command_result *json_dev_fail(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1220,24 +1211,22 @@ static void json_dev_fail(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("id", param_pubkey, &peerid),
NULL))
return;
return command_param_failed();
peer = peer_by_id(cmd->ld, peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
return;
}
channel = peer_active_channel(peer);
if (!channel) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find active channel with peer");
return;
}
channel_internal_error(channel, "Failing due to dev-fail command");
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command dev_fail_command = {
@ -1252,10 +1241,10 @@ static void dev_reenable_commit_finished(struct subd *channeld UNUSED,
const int *fds UNUSED,
struct command *cmd)
{
command_success(cmd, null_response(cmd));
was_pending(command_success(cmd, null_response(cmd)));
}
static void json_dev_reenable_commit(struct command *cmd,
static struct command_result *json_dev_reenable_commit(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1268,37 +1257,33 @@ static void json_dev_reenable_commit(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("id", param_pubkey, &peerid),
NULL))
return;
return command_param_failed();
peer = peer_by_id(cmd->ld, peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find peer with that id");
return;
}
channel = peer_active_channel(peer);
if (!channel) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Peer has no active channel");
return;
}
if (!channel->owner) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Peer has no owner");
return;
}
if (!streq(channel->owner->name, "lightning_channeld")) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Peer owned by %s", channel->owner->name);
return;
}
msg = towire_channel_dev_reenable_commit(channel);
subd_req(peer, channel->owner, take(msg), -1, 0,
dev_reenable_commit_finished, cmd);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_reenable_commit = {
@ -1347,7 +1332,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
command_success(forget->cmd, response);
}
static void json_dev_forget_channel(struct command *cmd,
static struct command_result *json_dev_forget_channel(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1365,14 +1350,13 @@ static void json_dev_forget_channel(struct command *cmd,
p_opt("short_channel_id", param_short_channel_id, &scid),
p_opt_def("force", param_bool, &force, false),
NULL))
return;
return command_param_failed();
forget->force = *force;
peer = peer_by_id(cmd->ld, peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find channel with that peer");
return;
}
forget->channel = NULL;
@ -1384,34 +1368,30 @@ static void json_dev_forget_channel(struct command *cmd,
continue;
}
if (forget->channel) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Multiple channels:"
" please specify short_channel_id");
return;
}
forget->channel = channel;
}
if (!forget->channel) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"No channels matching that short_channel_id");
return;
}
if (channel_has_htlc_out(forget->channel) ||
channel_has_htlc_in(forget->channel)) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"This channel has HTLCs attached and it is "
"not safe to forget it. Please use `close` "
"or `dev-fail` instead.");
return;
}
bitcoind_gettxout(cmd->ld->topology->bitcoind,
&forget->channel->funding_txid,
forget->channel->funding_outnum,
process_dev_forget_channel, forget);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_forget_channel_command = {

15
lightningd/peer_htlcs.c

@ -1792,7 +1792,7 @@ void htlcs_reconnect(struct lightningd *ld,
#if DEVELOPER
static void json_dev_ignore_htlcs(struct command *cmd,
static struct command_result *json_dev_ignore_htlcs(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1805,17 +1805,16 @@ static void json_dev_ignore_htlcs(struct command *cmd,
p_req("id", param_pubkey, &peerid),
p_req("ignore", param_bool, &ignore),
NULL))
return;
return command_param_failed();
peer = peer_by_id(cmd->ld, peerid);
if (!peer) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Could not find channel with that peer");
return;
}
peer->ignore_htlcs = *ignore;
command_success(cmd, null_response(cmd));
return command_success(cmd, null_response(cmd));
}
static const struct json_command dev_ignore_htlcs = {
@ -1849,7 +1848,7 @@ static void listforwardings_add_forwardings(struct json_stream *response, struct
tal_free(forwardings);
}
static void json_listforwards(struct command *cmd,
static struct command_result *json_listforwards(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -1857,14 +1856,14 @@ static void json_listforwards(struct command *cmd,
struct json_stream *response;
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
listforwardings_add_forwardings(response, cmd->ld->wallet);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listforwards_command = {

12
lightningd/ping.c

@ -79,7 +79,7 @@ void ping_reply(struct subd *subd, const u8 *msg)
}
}
static void json_ping(struct command *cmd,
static struct command_result *json_ping(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -93,7 +93,7 @@ static void json_ping(struct command *cmd,
p_opt_def("len", param_number, &len, 128),
p_opt_def("pongbytes", param_number, &pongbytes, 128),
NULL))
return;
return command_param_failed();
/* BOLT #1:
*
@ -110,16 +110,14 @@ static void json_ping(struct command *cmd,
* * [`byteslen`:`ignored`]
*/
if (*len > 65535 - 2 - 2 - 2) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%u would result in oversize ping", *len);
return;
}
/* Note that > 65531 is valid: it means "no pong reply" */
if (*pongbytes > 65535) {
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"pongbytes %u > 65535", *pongbytes);
return;
}
/* parent is cmd, so when we complete cmd, we free this. */
@ -128,7 +126,7 @@ static void json_ping(struct command *cmd,
/* gossipd handles all pinging, even if it's in another daemon. */
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
subd_send_msg(cmd->ld->gossip, take(msg));
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command ping_command = {

7
lightningd/plugin.c

@ -656,7 +656,8 @@ static struct plugin *find_plugin_for_command(struct command *cmd)
abort();
}
static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd,
const char *buffer,
const jsmntok_t *toks,
const jsmntok_t *params UNNEEDED)
{
@ -668,7 +669,7 @@ static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
if (cmd->mode == CMD_USAGE) {
/* FIXME! */
cmd->usage = "[params]";
return;
return command_param_failed();
}
plugin = find_plugin_for_command(cmd);
@ -683,7 +684,7 @@ static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
json_stream_forward_change_id(req->stream, buffer, toks, idtok, id);
plugin_request_queue(plugin, req);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static bool plugin_rpcmethod_add(struct plugin *plugin,

6
lightningd/test/run-invoice-select-inchan.c

@ -49,6 +49,12 @@ struct command_result *command_fail(struct command *cmd UNNEEDED, int code UNNEE
struct command_result *command_failed(struct command *cmd UNNEEDED,
struct json_stream *result UNNEEDED)
{ fprintf(stderr, "command_failed called!\n"); abort(); }
/* Generated stub for command_its_complicated */
struct command_result *command_its_complicated(void)
{ fprintf(stderr, "command_its_complicated called!\n"); abort(); }
/* Generated stub for command_param_failed */
struct command_result *command_param_failed(void)
{ fprintf(stderr, "command_param_failed called!\n"); abort(); }
/* Generated stub for command_still_pending */
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }

6
wallet/test/run-wallet.c

@ -55,6 +55,12 @@ struct command_result *command_fail(struct command *cmd UNNEEDED, int code UNNEE
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "command_fail called!\n"); abort(); }
/* Generated stub for command_its_complicated */
struct command_result *command_its_complicated(void)
{ fprintf(stderr, "command_its_complicated called!\n"); abort(); }
/* Generated stub for command_param_failed */
struct command_result *command_param_failed(void)
{ fprintf(stderr, "command_param_failed called!\n"); abort(); }
/* Generated stub for command_still_pending */
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }

61
wallet/walletrpc.c

@ -85,7 +85,7 @@ static void wallet_withdrawal_broadcast(struct bitcoind *bitcoind UNUSED,
* request, select coins and a change key. Then send the request to
* the HSM to generate the signatures.
*/
static void json_withdraw(struct command *cmd,
static struct command_result *json_withdraw(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -105,17 +105,17 @@ static void json_withdraw(struct command *cmd,
p_req("satoshi", param_tok, &sattok),
p_opt("feerate", param_feerate, &feerate_per_kw),
NULL))
return;
return command_param_failed();
res = param_wtx(&withdraw->wtx, buffer, sattok, -1ULL);
if (res)
return;
return res;
if (!feerate_per_kw) {
res = param_feerate_estimate(cmd, &feerate_per_kw,
FEERATE_NORMAL);
if (res)
return;
return res;
}
/* Parse address. */
@ -126,22 +126,21 @@ static void json_withdraw(struct command *cmd,
/* Check that destination address could be understood. */
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, LIGHTNINGD, "Could not parse destination address");
return;
return command_fail(cmd, LIGHTNINGD,
"Could not parse destination address");
}
/* Check address given is compatible with the chain we are on. */
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"Destination address is not on network %s",
get_chainparams(cmd->ld)->network_name);
return;
}
res = wtx_select_utxos(&withdraw->wtx, *feerate_per_kw,
tal_count(withdraw->destination));
if (res)
return;
return res;
u8 *msg = towire_hsm_sign_withdrawal(cmd,
withdraw->wtx.amount,
@ -164,7 +163,7 @@ static void json_withdraw(struct command *cmd,
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
wallet_withdrawal_broadcast, withdraw);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command withdraw_command = {
@ -248,7 +247,7 @@ static struct command_result *param_newaddr(struct command *cmd,
name, tok->end - tok->start, buffer + tok->start);
}
static void json_newaddr(struct command *cmd,
static struct command_result *json_newaddr(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -263,24 +262,21 @@ static void json_newaddr(struct command *cmd,
if (!param(cmd, buffer, params,
p_opt_def("addresstype", param_newaddr, &is_p2wpkh, true),
NULL))
return;
return command_param_failed();
keyidx = wallet_get_newindex(cmd->ld);
if (keyidx < 0) {
command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
return;
return command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
}
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
command_fail(cmd, LIGHTNINGD, "Keys generation failure");
return;
return command_fail(cmd, LIGHTNINGD, "Keys generation failure");
}
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
ext.pub_key, sizeof(ext.pub_key))) {
command_fail(cmd, LIGHTNINGD, "Key parsing failure");
return;
return command_fail(cmd, LIGHTNINGD, "Key parsing failure");
}
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
@ -289,16 +285,15 @@ static void json_newaddr(struct command *cmd,
&pubkey, !*is_p2wpkh,
NULL);
if (!out) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"p2wpkh address encoding failure.");
return;
}
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "address", out);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command newaddr_command = {
@ -309,7 +304,7 @@ static const struct json_command newaddr_command = {
};
AUTODATA(json_command, &newaddr_command);
static void json_listaddrs(struct command *cmd,
static struct command_result *json_listaddrs(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -324,7 +319,7 @@ static void json_listaddrs(struct command *cmd,
db_get_intvar(cmd->ld->wallet->db,
"bip32_max_index", 0)),
NULL))
return;
return command_param_failed();
response = json_stream_success(cmd);
json_object_start(response, NULL);
@ -377,7 +372,7 @@ static void json_listaddrs(struct command *cmd,
}
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listaddrs_command = {
@ -389,7 +384,7 @@ static const struct json_command listaddrs_command = {
};
AUTODATA(json_command, &listaddrs_command);
static void json_listfunds(struct command *cmd,
static struct command_result *json_listfunds(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -401,7 +396,7 @@ static void json_listfunds(struct command *cmd,
struct pubkey funding_pubkey;
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available);
response = json_stream_success(cmd);
@ -422,9 +417,8 @@ static void json_listfunds(struct command *cmd,
utxos[i]->is_p2sh,
NULL);
if (!out) {
command_fail(cmd, LIGHTNINGD,
return command_fail(cmd, LIGHTNINGD,
"p2wpkh address encoding failure.");
return;
}
json_add_string(response, "address", out);
}
@ -464,7 +458,7 @@ static void json_listfunds(struct command *cmd,
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return command_success(cmd, response);
}
static const struct json_command listfunds_command = {
@ -517,7 +511,7 @@ static void process_utxo_result(struct bitcoind *bitcoind,
}
}
static void json_dev_rescan_outputs(struct command *cmd,
static struct command_result *json_dev_rescan_outputs(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
@ -525,7 +519,7 @@ static void json_dev_rescan_outputs(struct command *cmd,
struct txo_rescan *rescan = tal(cmd, struct txo_rescan);
if (!param(cmd, buffer, params, NULL))
return;
return command_param_failed();
rescan->response = json_stream_success(cmd);
rescan->cmd = cmd;
@ -537,13 +531,12 @@ static void json_dev_rescan_outputs(struct command *cmd,
if (tal_count(rescan->utxos) == 0) {
json_array_end(rescan->response);
json_object_end(rescan->response);
command_success(cmd, rescan->response);
return;
return command_success(cmd, rescan->response);
}
bitcoind_gettxout(cmd->ld->topology->bitcoind, &rescan->utxos[0]->txid,
rescan->utxos[0]->outnum, process_utxo_result,
rescan);
command_still_pending(cmd);
return command_still_pending(cmd);
}
static const struct json_command dev_rescan_output_command = {

Loading…
Cancel
Save