mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
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>
This commit is contained in:
@@ -463,7 +463,7 @@ u32 feerate_to_style(u32 feerate_perkw, enum feerate_style style)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_feerates(struct command *cmd,
|
static struct command_result *json_feerates(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -477,7 +477,7 @@ static void json_feerates(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("style", param_feerate_style, &style),
|
p_req("style", param_feerate_style, &style),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
missing = false;
|
missing = false;
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(feerates); i++) {
|
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);
|
json_object_end(response);
|
||||||
|
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command feerates_command = {
|
static const struct json_command feerates_command = {
|
||||||
|
|||||||
@@ -65,16 +65,17 @@ static struct connect *find_connect(struct lightningd *ld,
|
|||||||
return NULL;
|
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);
|
struct json_stream *response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_pubkey(response, "id", id);
|
json_add_pubkey(response, "id", id);
|
||||||
json_object_end(response);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -96,7 +97,7 @@ static void json_connect(struct command *cmd,
|
|||||||
p_opt("host", param_string, &name),
|
p_opt("host", param_string, &name),
|
||||||
p_opt("port", param_number, &port),
|
p_opt("port", param_number, &port),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Check for id@addrport form */
|
/* Check for id@addrport form */
|
||||||
id_str = json_strdup(cmd, buffer, idtok);
|
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)) {
|
if (!json_to_pubkey(buffer, idtok, &id)) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"id %.*s not valid",
|
"id %.*s not valid",
|
||||||
json_tok_full_len(idtok),
|
json_tok_full_len(idtok),
|
||||||
json_tok_full(buffer, idtok));
|
json_tok_full(buffer, idtok));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name && ataddr) {
|
if (name && ataddr) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Can't specify host as both xxx@yyy "
|
"Can't specify host as both xxx@yyy "
|
||||||
"and separate argument");
|
"and separate argument");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get parseable host if provided somehow */
|
/* Get parseable host if provided somehow */
|
||||||
@@ -129,9 +128,8 @@ static void json_connect(struct command *cmd,
|
|||||||
|
|
||||||
/* Port without host name? */
|
/* Port without host name? */
|
||||||
if (port && !name) {
|
if (port && !name) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Can't specify port without host");
|
"Can't specify port without host");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we know about peer, see if it's already connected. */
|
/* 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
|
if (peer->uncommitted_channel
|
||||||
|| (channel && channel->connected)) {
|
|| (channel && channel->connected)) {
|
||||||
connect_cmd_succeed(cmd, &id);
|
return connect_cmd_succeed(cmd, &id);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +156,10 @@ static void json_connect(struct command *cmd,
|
|||||||
&& !cmd->ld->pure_tor_setup,
|
&& !cmd->ld->pure_tor_setup,
|
||||||
true,
|
true,
|
||||||
&err_msg)) {
|
&err_msg)) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Host %s:%u not valid: %s",
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
name, *port, err_msg ? err_msg : "port is 0");
|
"Host %s:%u not valid: %s",
|
||||||
return;
|
name, *port,
|
||||||
|
err_msg ? err_msg : "port is 0");
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
addr = NULL;
|
addr = NULL;
|
||||||
@@ -171,7 +169,7 @@ static void json_connect(struct command *cmd,
|
|||||||
|
|
||||||
/* Leave this here for peer_connected or connect_failed. */
|
/* Leave this here for peer_connected or connect_failed. */
|
||||||
new_connect(cmd->ld, &id, cmd);
|
new_connect(cmd->ld, &id, cmd);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command connect_command = {
|
static const struct json_command connect_command = {
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
|
|||||||
command_success(cmd, response);
|
command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_listnodes(struct command *cmd,
|
static struct command_result *json_listnodes(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -255,11 +255,11 @@ static void json_listnodes(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt("id", param_pubkey, &id),
|
p_opt("id", param_pubkey, &id),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
req = towire_gossip_getnodes_request(cmd, id);
|
req = towire_gossip_getnodes_request(cmd, id);
|
||||||
subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd);
|
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 = {
|
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);
|
command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_getroute(struct command *cmd,
|
static struct command_result *json_getroute(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -318,7 +318,7 @@ static void json_getroute(struct command *cmd,
|
|||||||
p_opt("seed", param_tok, &seedtok),
|
p_opt("seed", param_tok, &seedtok),
|
||||||
p_opt_def("fuzzpercent", param_percent, &fuzz, 75.0),
|
p_opt_def("fuzzpercent", param_percent, &fuzz, 75.0),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Convert from percentage */
|
/* Convert from percentage */
|
||||||
*fuzz = *fuzz / 100.0;
|
*fuzz = *fuzz / 100.0;
|
||||||
@@ -338,7 +338,7 @@ static void json_getroute(struct command *cmd,
|
|||||||
*msatoshi, *riskfactor * 1000,
|
*msatoshi, *riskfactor * 1000,
|
||||||
*cltv, fuzz, &seed);
|
*cltv, fuzz, &seed);
|
||||||
subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd);
|
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 = {
|
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);
|
command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_listchannels(struct command *cmd,
|
static struct command_result *json_listchannels(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -409,12 +409,12 @@ static void json_listchannels(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt("short_channel_id", param_short_channel_id, &id),
|
p_opt("short_channel_id", param_short_channel_id, &id),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
req = towire_gossip_getchannels_request(cmd, id);
|
req = towire_gossip_getchannels_request(cmd, id);
|
||||||
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
||||||
req, -1, 0, json_listchannels_reply, cmd);
|
req, -1, 0, json_listchannels_reply, cmd);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listchannels_command = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("id", param_pubkey, &id),
|
||||||
p_req("scids", param_array, &scidstok),
|
p_req("scids", param_array, &scidstok),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
scids = tal_arr(cmd, struct short_channel_id, scidstok->size);
|
scids = tal_arr(cmd, struct short_channel_id, scidstok->size);
|
||||||
end = json_next(scidstok);
|
end = json_next(scidstok);
|
||||||
for (i = 0, t = scidstok + 1; t < end; t = json_next(t), i++) {
|
for (i = 0, t = scidstok + 1; t < end; t = json_next(t), i++) {
|
||||||
if (!json_to_short_channel_id(buffer, t, &scids[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",
|
"scid %zu '%.*s' is not an scid",
|
||||||
i, json_tok_full_len(t),
|
i, json_tok_full_len(t),
|
||||||
json_tok_full(buffer, 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);
|
msg = towire_gossip_query_scids(cmd, id, scids);
|
||||||
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
||||||
take(msg), -1, 0, json_scids_reply, cmd);
|
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 = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("first", param_number, &first),
|
||||||
p_req("range", param_number, &range),
|
p_req("range", param_number, &range),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
log_debug(cmd->ld->log, "Setting timestamp range %u+%u", *first, *range);
|
log_debug(cmd->ld->log, "Setting timestamp range %u+%u", *first, *range);
|
||||||
/* Tell gossipd, since this is a gossip query. */
|
/* Tell gossipd, since this is a gossip query. */
|
||||||
msg = towire_gossip_send_timestamp_filter(NULL, id, *first, *range);
|
msg = towire_gossip_send_timestamp_filter(NULL, id, *first, *range);
|
||||||
subd_send_msg(cmd->ld->gossip, take(msg));
|
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 = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("first", param_number, &first),
|
||||||
p_req("num", param_number, &num),
|
p_req("num", param_number, &num),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Tell gossipd, since this is a gossip query. */
|
/* Tell gossipd, since this is a gossip query. */
|
||||||
msg = towire_gossip_query_channel_range(cmd, id, *first, *num);
|
msg = towire_gossip_query_channel_range(cmd, id, *first, *num);
|
||||||
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
||||||
take(msg), -1, 0, json_channel_range_reply, cmd);
|
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 = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("max", param_number, &max),
|
p_req("max", param_number, &max),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
msg = towire_gossip_dev_set_max_scids_encode_size(NULL, *max);
|
msg = towire_gossip_dev_set_max_scids_encode_size(NULL, *max);
|
||||||
subd_send_msg(cmd->ld->gossip, take(msg));
|
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 = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
subd_send_msg(cmd->ld->gossip, take(towire_gossip_dev_suppress(NULL)));
|
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 = {
|
static const struct json_command dev_suppress_gossip = {
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ static void json_add_invoice(struct json_stream *response,
|
|||||||
json_object_end(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;
|
struct json_stream *response;
|
||||||
const struct invoice_details *details;
|
const struct invoice_details *details;
|
||||||
@@ -71,13 +72,13 @@ static void tell_waiter(struct command *cmd, const struct invoice *inv)
|
|||||||
if (details->state == PAID) {
|
if (details->state == PAID) {
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_add_invoice(response, details);
|
json_add_invoice(response, details);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
|
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
|
||||||
response = json_stream_fail(cmd, -2,
|
response = json_stream_fail(cmd, -2,
|
||||||
"invoice expired during wait");
|
"invoice expired during wait");
|
||||||
json_add_invoice(response, details);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_fallback(struct command *cmd,
|
static struct command_result *parse_fallback(struct command *cmd,
|
||||||
const char *buffer, const jsmntok_t *fallback,
|
const char *buffer,
|
||||||
|
const jsmntok_t *fallback,
|
||||||
const u8 **fallback_script)
|
const u8 **fallback_script)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -124,15 +126,14 @@ static bool parse_fallback(struct command *cmd,
|
|||||||
buffer, fallback,
|
buffer, fallback,
|
||||||
fallback_script);
|
fallback_script);
|
||||||
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Fallback address not valid");
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
return false;
|
"Fallback address not valid");
|
||||||
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
} 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",
|
"Fallback address does not match our network %s",
|
||||||
get_chainparams(cmd->ld)->network_name);
|
get_chainparams(cmd->ld)->network_name);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT11 struct wants an array of arrays (can provide multiple routes) */
|
/* 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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -316,23 +317,21 @@ static void json_invoice(struct command *cmd,
|
|||||||
p_opt("fallbacks", param_array, &fallbacks),
|
p_opt("fallbacks", param_array, &fallbacks),
|
||||||
p_opt("preimage", param_tok, &preimagetok),
|
p_opt("preimage", param_tok, &preimagetok),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (strlen(info->label->s) > INVOICE_MAX_LABEL_LEN) {
|
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,
|
"Label '%s' over %u bytes", info->label->s,
|
||||||
INVOICE_MAX_LABEL_LEN);
|
INVOICE_MAX_LABEL_LEN);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(desc_val) >= BOLT11_FIELD_BYTE_LIMIT) {
|
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 "
|
"Descriptions greater than %d bytes "
|
||||||
"not yet supported "
|
"not yet supported "
|
||||||
"(description length %zu)",
|
"(description length %zu)",
|
||||||
BOLT11_FIELD_BYTE_LIMIT,
|
BOLT11_FIELD_BYTE_LIMIT,
|
||||||
strlen(desc_val));
|
strlen(desc_val));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallbacks) {
|
if (fallbacks) {
|
||||||
@@ -340,9 +339,11 @@ static void json_invoice(struct command *cmd,
|
|||||||
|
|
||||||
fallback_scripts = tal_arr(cmd, const u8 *, 0);
|
fallback_scripts = tal_arr(cmd, const u8 *, 0);
|
||||||
for (i = fallbacks + 1; i < end; i = json_next(i)) {
|
for (i = fallbacks + 1; i < end; i = json_next(i)) {
|
||||||
if (!parse_fallback(cmd, buffer, i,
|
struct command_result *r;
|
||||||
tal_arr_expand(&fallback_scripts)))
|
r = parse_fallback(cmd, buffer, i,
|
||||||
return;
|
tal_arr_expand(&fallback_scripts));
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,9 +353,8 @@ static void json_invoice(struct command *cmd,
|
|||||||
preimagetok->end - preimagetok->start,
|
preimagetok->end - preimagetok->start,
|
||||||
&info->payment_preimage,
|
&info->payment_preimage,
|
||||||
sizeof(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");
|
"preimage must be 64 hex digits");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
/* Generate random secret preimage. */
|
/* Generate random secret preimage. */
|
||||||
@@ -381,7 +381,7 @@ static void json_invoice(struct command *cmd,
|
|||||||
take(towire_gossip_get_incoming_channels(NULL)),
|
take(towire_gossip_get_incoming_channels(NULL)),
|
||||||
-1, 0, gossipd_incoming_channels_reply, info);
|
-1, 0, gossipd_incoming_channels_reply, info);
|
||||||
|
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command invoice_command = {
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -427,14 +427,14 @@ static void json_listinvoices(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt("label", param_label, &label),
|
p_opt("label", param_label, &label),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_array_start(response, "invoices");
|
json_array_start(response, "invoices");
|
||||||
json_add_invoices(response, wallet, label);
|
json_add_invoices(response, wallet, label);
|
||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listinvoices_command = {
|
static const struct json_command listinvoices_command = {
|
||||||
@@ -444,7 +444,7 @@ static const struct json_command listinvoices_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -460,11 +460,10 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
p_req("label", param_label, &label),
|
p_req("label", param_label, &label),
|
||||||
p_req("status", param_string, &status),
|
p_req("status", param_string, &status),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Unknown invoice");
|
return command_fail(cmd, LIGHTNINGD, "Unknown invoice");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
|
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! */
|
* might not make sense if it changed! */
|
||||||
actual_status = invoice_status_str(details);
|
actual_status = invoice_status_str(details);
|
||||||
if (!streq(actual_status, status)) {
|
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);
|
actual_status, status);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wallet_invoice_delete(wallet, i)) {
|
if (!wallet_invoice_delete(wallet, i)) {
|
||||||
log_broken(cmd->ld->log,
|
log_broken(cmd->ld->log,
|
||||||
"Error attempting to remove invoice %"PRIu64,
|
"Error attempting to remove invoice %"PRIu64,
|
||||||
i.id);
|
i.id);
|
||||||
command_fail(cmd, LIGHTNINGD, "Database error");
|
return command_fail(cmd, LIGHTNINGD, "Database error");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_add_invoice(response, details);
|
json_add_invoice(response, details);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command delinvoice_command = {
|
static const struct json_command delinvoice_command = {
|
||||||
@@ -498,7 +496,7 @@ static const struct json_command delinvoice_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -509,11 +507,11 @@ static void json_delexpiredinvoice(struct command *cmd,
|
|||||||
p_opt_def("maxexpirytime", param_u64, &maxexpirytime,
|
p_opt_def("maxexpirytime", param_u64, &maxexpirytime,
|
||||||
time_now().ts.tv_sec),
|
time_now().ts.tv_sec),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
wallet_invoice_delete_expired(cmd->ld->wallet, *maxexpirytime);
|
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 = {
|
static const struct json_command delexpiredinvoice_command = {
|
||||||
"delexpiredinvoice",
|
"delexpiredinvoice",
|
||||||
@@ -522,7 +520,7 @@ static const struct json_command delexpiredinvoice_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("cycle_seconds", param_u64, &cycle, 3600),
|
||||||
p_opt_def("expired_by", param_u64, &exby, 86400),
|
p_opt_def("expired_by", param_u64, &exby, 86400),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
wallet_invoice_autoclean(cmd->ld->wallet, *cycle, *exby);
|
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 = {
|
static const struct json_command autocleaninvoice_command = {
|
||||||
"autocleaninvoice",
|
"autocleaninvoice",
|
||||||
@@ -549,7 +547,7 @@ static const struct json_command autocleaninvoice_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -560,7 +558,7 @@ static void json_waitanyinvoice(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt_def("lastpay_index", param_u64, &pay_index, 0),
|
p_opt_def("lastpay_index", param_u64, &pay_index, 0),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Set command as pending. We do not know if
|
/* Set command as pending. We do not know if
|
||||||
* wallet_invoice_waitany will return immediately
|
* wallet_invoice_waitany will return immediately
|
||||||
@@ -570,6 +568,8 @@ static void json_waitanyinvoice(struct command *cmd,
|
|||||||
/* Find next paid invoice. */
|
/* Find next paid invoice. */
|
||||||
wallet_invoice_waitany(cmd, wallet, *pay_index,
|
wallet_invoice_waitany(cmd, wallet, *pay_index,
|
||||||
&wait_on_invoice, (void*) cmd);
|
&wait_on_invoice, (void*) cmd);
|
||||||
|
|
||||||
|
return command_its_complicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command waitanyinvoice_command = {
|
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
|
* already been received or it may add the `cmd` to the list of
|
||||||
* waiters, if the payment is still pending.
|
* 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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -598,23 +598,22 @@ static void json_waitinvoice(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("label", param_label, &label),
|
p_req("label", param_label, &label),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
if (!wallet_invoice_find_by_label(wallet, &i, label)) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Label not found");
|
return command_fail(cmd, LIGHTNINGD, "Label not found");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
|
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
|
||||||
|
|
||||||
/* If paid or expired return immediately */
|
/* If paid or expired return immediately */
|
||||||
if (details->state == PAID || details->state == EXPIRED) {
|
if (details->state == PAID || details->state == EXPIRED) {
|
||||||
tell_waiter(cmd, &i);
|
return tell_waiter(cmd, &i);
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
/* There is an unpaid one matching, let's wait... */
|
/* There is an unpaid one matching, let's wait... */
|
||||||
command_still_pending(cmd);
|
command_still_pending(cmd);
|
||||||
wallet_invoice_waitone(cmd, wallet, i,
|
wallet_invoice_waitone(cmd, wallet, i,
|
||||||
&wait_on_invoice, (void *) cmd);
|
&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);
|
json_object_end(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_decodepay(struct command *cmd,
|
static struct command_result *json_decodepay(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -674,13 +673,12 @@ static void json_decodepay(struct command *cmd,
|
|||||||
p_req("bolt11", param_string, &str),
|
p_req("bolt11", param_string, &str),
|
||||||
p_opt("description", param_string, &desc),
|
p_opt("description", param_string, &desc),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
b11 = bolt11_decode(cmd, str, desc, &fail);
|
b11 = bolt11_decode(cmd, str, desc, &fail);
|
||||||
|
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
|
return command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -766,7 +764,7 @@ static void json_decodepay(struct command *cmd,
|
|||||||
type_to_string(cmd, secp256k1_ecdsa_signature,
|
type_to_string(cmd, secp256k1_ecdsa_signature,
|
||||||
&b11->sig));
|
&b11->sig));
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command decodepay_command = {
|
static const struct json_command decodepay_command = {
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ static void destroy_jcon(struct json_connection *jcon)
|
|||||||
tal_free(jcon->log);
|
tal_free(jcon->log);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_help(struct command *cmd,
|
static struct command_result *json_help(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params);
|
const jsmntok_t *params);
|
||||||
@@ -166,7 +166,7 @@ static const struct json_command help_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -174,13 +174,13 @@ static void json_stop(struct command *cmd,
|
|||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* This can't have closed yet! */
|
/* This can't have closed yet! */
|
||||||
cmd->jcon->stop = true;
|
cmd->jcon->stop = true;
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_add_string(response, NULL, "Shutting down");
|
json_add_string(response, NULL, "Shutting down");
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command stop_command = {
|
static const struct json_command stop_command = {
|
||||||
@@ -191,7 +191,7 @@ static const struct json_command stop_command = {
|
|||||||
AUTODATA(json_command, &stop_command);
|
AUTODATA(json_command, &stop_command);
|
||||||
|
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
static void json_rhash(struct command *cmd,
|
static struct command_result *json_rhash(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNUSED,
|
const jsmntok_t *obj UNUSED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -202,7 +202,7 @@ static void json_rhash(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("secret", param_sha256, &secret),
|
p_req("secret", param_sha256, &secret),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Hash in place. */
|
/* Hash in place. */
|
||||||
sha256(secret, secret, sizeof(*secret));
|
sha256(secret, secret, sizeof(*secret));
|
||||||
@@ -210,7 +210,7 @@ static void json_rhash(struct command *cmd,
|
|||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_hex(response, "rhash", secret, sizeof(*secret));
|
json_add_hex(response, "rhash", secret, sizeof(*secret));
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_rhash_command = {
|
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_object_start(sc->js, NULL);
|
||||||
json_add_num(sc->js, "msec", *sc->msec);
|
json_add_num(sc->js, "msec", *sc->msec);
|
||||||
json_object_end(sc->js);
|
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)
|
static void slowcmd_start(struct slowcmd *sc)
|
||||||
@@ -241,7 +241,7 @@ static void slowcmd_start(struct slowcmd *sc)
|
|||||||
slowcmd_finish, sc);
|
slowcmd_finish, sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_slowcmd(struct command *cmd,
|
static struct command_result *json_slowcmd(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNUSED,
|
const jsmntok_t *obj UNUSED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -252,10 +252,10 @@ static void json_slowcmd(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt_def("msec", param_number, &sc->msec, 1000),
|
p_opt_def("msec", param_number, &sc->msec, 1000),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
new_reltimer(&cmd->ld->timers, sc, time_from_msec(0), slowcmd_start, sc);
|
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 = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
fatal("Crash at user request");
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -337,7 +337,7 @@ static void json_help(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt("command", param_tok, &cmdtok),
|
p_opt("command", param_tok, &cmdtok),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (cmdtok) {
|
if (cmdtok) {
|
||||||
for (size_t i = 0; i < tal_count(commands); i++) {
|
for (size_t i = 0; i < tal_count(commands); i++) {
|
||||||
@@ -347,11 +347,10 @@ static void json_help(struct command *cmd,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
command_fail(cmd, JSONRPC2_METHOD_NOT_FOUND,
|
return command_fail(cmd, JSONRPC2_METHOD_NOT_FOUND,
|
||||||
"Unknown command '%.*s'",
|
"Unknown command '%.*s'",
|
||||||
json_tok_full_len(cmdtok),
|
json_tok_full_len(cmdtok),
|
||||||
json_tok_full(buffer, cmdtok));
|
json_tok_full(buffer, cmdtok));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -364,7 +363,7 @@ static void json_help(struct command *cmd,
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command *find_cmd(const struct jsonrpc *rpc,
|
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;
|
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;
|
const jsmntok_t *method, *id, *params;
|
||||||
struct command *c;
|
struct command *c;
|
||||||
|
struct command_result *res;
|
||||||
|
|
||||||
if (tok[0].type != JSMN_OBJECT) {
|
if (tok[0].type != JSMN_OBJECT) {
|
||||||
json_command_malformed(jcon, "null",
|
json_command_malformed(jcon, "null",
|
||||||
"Expected {} for json command");
|
"Expected {} for json command");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
method = json_get_member(jcon->buffer, tok, "method");
|
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) {
|
if (!id) {
|
||||||
json_command_malformed(jcon, "null", "No id");
|
json_command_malformed(jcon, "null", "No id");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (id->type != JSMN_STRING && id->type != JSMN_PRIMITIVE) {
|
if (id->type != JSMN_STRING && id->type != JSMN_PRIMITIVE) {
|
||||||
json_command_malformed(jcon, "null",
|
json_command_malformed(jcon, "null",
|
||||||
"Expected string/primitive for id");
|
"Expected string/primitive for id");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the command off of the `jsonrpc` object and not
|
/* 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);
|
tal_add_destructor(c, destroy_command);
|
||||||
|
|
||||||
if (!method || !params) {
|
if (!method || !params) {
|
||||||
command_fail(c, JSONRPC2_INVALID_REQUEST,
|
return command_fail(c, JSONRPC2_INVALID_REQUEST,
|
||||||
method ? "No params" : "No method");
|
method ? "No params" : "No method");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method->type != JSMN_STRING) {
|
if (method->type != JSMN_STRING) {
|
||||||
command_fail(c, JSONRPC2_INVALID_REQUEST,
|
return command_fail(c, JSONRPC2_INVALID_REQUEST,
|
||||||
"Expected string for method");
|
"Expected string for method");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->json_cmd = find_cmd(jcon->ld->jsonrpc, jcon->buffer, method);
|
c->json_cmd = find_cmd(jcon->ld->jsonrpc, jcon->buffer, method);
|
||||||
if (!c->json_cmd) {
|
if (!c->json_cmd) {
|
||||||
command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
|
return command_fail(c, JSONRPC2_METHOD_NOT_FOUND,
|
||||||
"Unknown command '%.*s'",
|
"Unknown command '%.*s'",
|
||||||
json_tok_full_len(method),
|
json_tok_full_len(method),
|
||||||
json_tok_full(jcon->buffer, method));
|
json_tok_full(jcon->buffer, method));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (c->json_cmd->deprecated && !deprecated_apis) {
|
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",
|
"Command '%.*s' is deprecated",
|
||||||
method->end - method->start,
|
method->end - method->start,
|
||||||
jcon->buffer + method->start);
|
jcon->buffer + method->start);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db_begin_transaction(jcon->ld->wallet->db);
|
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);
|
db_commit_transaction(jcon->ld->wallet->db);
|
||||||
|
|
||||||
|
assert(res == ¶m_failed
|
||||||
|
|| res == &complete
|
||||||
|
|| res == &pending
|
||||||
|
|| res == &unknown);
|
||||||
|
|
||||||
/* If they didn't complete it, they must call command_still_pending.
|
/* If they didn't complete it, they must call command_still_pending.
|
||||||
* If they completed it, it's freed already. */
|
* If they completed it, it's freed already. */
|
||||||
|
if (res == &pending)
|
||||||
|
assert(c->pending);
|
||||||
list_for_each(&jcon->commands, c, list)
|
list_for_each(&jcon->commands, c, list)
|
||||||
assert(c->pending);
|
assert(c->pending);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mutual recursion */
|
/* Mutual recursion */
|
||||||
@@ -1002,7 +1009,7 @@ static void destroy_command_canary(struct command *cmd, bool *failed)
|
|||||||
*failed = true;
|
*failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_check(struct command *cmd,
|
static struct command_result *json_check(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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_req("command_to_check", param_command, &name_tok),
|
||||||
p_opt_any(),
|
p_opt_any(),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* Point name_tok to the name, not the value */
|
/* Point name_tok to the name, not the value */
|
||||||
if (params->type == JSMN_OBJECT)
|
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);
|
cmd->json_cmd->dispatch(cmd, buffer, mod_params, mod_params);
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
return;
|
return command_its_complicated();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_string(response, "command_to_check", cmd->json_cmd->name);
|
json_add_string(response, "command_to_check", cmd->json_cmd->name);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command check_command = {
|
static const struct json_command check_command = {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ struct command_result;
|
|||||||
|
|
||||||
struct json_command {
|
struct json_command {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*dispatch)(struct command *,
|
struct command_result *(*dispatch)(struct command *,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj,
|
const jsmntok_t *obj,
|
||||||
const jsmntok_t *params);
|
const jsmntok_t *params);
|
||||||
|
|||||||
@@ -728,7 +728,7 @@ struct command_result *param_loglevel(struct command *cmd,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_getlog(struct command *cmd,
|
static struct command_result *json_getlog(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t * params)
|
const jsmntok_t * params)
|
||||||
@@ -740,7 +740,7 @@ static void json_getlog(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt_def("level", param_loglevel, &minlevel, LOG_INFORM),
|
p_opt_def("level", param_loglevel, &minlevel, LOG_INFORM),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
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_num(response, "bytes_max", (unsigned int) log_max_mem(lr));
|
||||||
json_add_log(response, lr, *minlevel);
|
json_add_log(response, lr, *minlevel);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command getlog_command = {
|
static const struct json_command getlog_command = {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ static void add_memdump(struct json_stream *response,
|
|||||||
json_array_end(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -70,12 +70,12 @@ static void json_memdump(struct command *cmd,
|
|||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
add_memdump(response, NULL, NULL, cmd);
|
add_memdump(response, NULL, NULL, cmd);
|
||||||
|
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_memdump_command = {
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (!getenv("LIGHTNINGD_DEV_MEMLEAK")) {
|
if (!getenv("LIGHTNINGD_DEV_MEMLEAK")) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Leak detection needs $LIGHTNINGD_DEV_MEMLEAK");
|
"Leak detection needs $LIGHTNINGD_DEV_MEMLEAK");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For simplicity, we mark pending, though an error may complete it
|
/* 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. */
|
/* This calls opening_memleak_done() async when all done. */
|
||||||
opening_dev_memleak(cmd);
|
opening_dev_memleak(cmd);
|
||||||
|
|
||||||
|
return command_its_complicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_memleak_command = {
|
static const struct json_command dev_memleak_command = {
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ void opening_peer_no_active_channels(struct peer *peer)
|
|||||||
/**
|
/**
|
||||||
* json_fund_channel - Entrypoint for funding a channel
|
* 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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("feerate", param_feerate, &feerate_per_kw),
|
||||||
p_opt_def("announce", param_bool, &announce_channel, true),
|
p_opt_def("announce", param_bool, &announce_channel, true),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
res = param_wtx(&fc->wtx, buffer, sattok, max_funding_satoshi);
|
res = param_wtx(&fc->wtx, buffer, sattok, max_funding_satoshi);
|
||||||
if (res)
|
if (res)
|
||||||
return;
|
return res;
|
||||||
|
|
||||||
if (!feerate_per_kw) {
|
if (!feerate_per_kw) {
|
||||||
feerate_per_kw = tal(cmd, u32);
|
feerate_per_kw = tal(cmd, u32);
|
||||||
*feerate_per_kw = opening_feerate(cmd->ld->topology);
|
*feerate_per_kw = opening_feerate(cmd->ld->topology);
|
||||||
if (!*feerate_per_kw) {
|
if (!*feerate_per_kw) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Cannot estimate fees");
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
return;
|
"Cannot estimate fees");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*feerate_per_kw < feerate_floor()) {
|
if (*feerate_per_kw < feerate_floor()) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Feerate below feerate floor");
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
return;
|
"Feerate below feerate floor");
|
||||||
}
|
}
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, id);
|
peer = peer_by_id(cmd->ld, id);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Unknown peer");
|
return command_fail(cmd, LIGHTNINGD, "Unknown peer");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
||||||
channel_state_name(channel));
|
channel_state_name(channel));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!peer->uncommitted_channel) {
|
if (!peer->uncommitted_channel) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer->uncommitted_channel->fc) {
|
if (peer->uncommitted_channel->fc) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Already funding channel");
|
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Support push_msat? */
|
/* 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,
|
res = wtx_select_utxos(&fc->wtx, *feerate_per_kw,
|
||||||
BITCOIN_SCRIPTPUBKEY_P2WSH_LEN);
|
BITCOIN_SCRIPTPUBKEY_P2WSH_LEN);
|
||||||
if (res)
|
if (res)
|
||||||
return;
|
return res;
|
||||||
|
|
||||||
assert(fc->wtx.amount <= max_funding_satoshi);
|
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
|
/* Openingd will either succeed, or fail, or tell us the other side
|
||||||
* funded first. */
|
* funded first. */
|
||||||
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
|
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 = {
|
static const struct json_command fund_channel_command = {
|
||||||
|
|||||||
@@ -1046,7 +1046,7 @@ static void add_config(struct lightningd *ld,
|
|||||||
tal_free(name0);
|
tal_free(name0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_listconfigs(struct command *cmd,
|
static struct command_result *json_listconfigs(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1058,7 +1058,7 @@ static void json_listconfigs(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt("config", param_tok, &configtok),
|
p_opt("config", param_tok, &configtok),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (!configtok) {
|
if (!configtok) {
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -1097,14 +1097,13 @@ static void json_listconfigs(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (configtok && !response) {
|
if (configtok && !response) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Unknown config option '%.*s'",
|
"Unknown config option '%.*s'",
|
||||||
json_tok_full_len(configtok),
|
json_tok_full_len(configtok),
|
||||||
json_tok_full(buffer, configtok));
|
json_tok_full(buffer, configtok));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listconfigs_command = {
|
static const struct json_command listconfigs_command = {
|
||||||
|
|||||||
@@ -941,7 +941,7 @@ static void json_sendpay_on_resolve(const struct sendpay_result* r,
|
|||||||
json_waitsendpay_on_resolve(r, cmd);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -960,7 +960,7 @@ static void json_sendpay(struct command *cmd,
|
|||||||
p_opt("description", param_escaped_string, &description),
|
p_opt("description", param_escaped_string, &description),
|
||||||
p_opt("msatoshi", param_u64, &msatoshi),
|
p_opt("msatoshi", param_u64, &msatoshi),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
end = json_next(routetok);
|
end = json_next(routetok);
|
||||||
n_hops = 0;
|
n_hops = 0;
|
||||||
@@ -978,7 +978,7 @@ static void json_sendpay(struct command *cmd,
|
|||||||
p_req("delay", param_number, &delay),
|
p_req("delay", param_number, &delay),
|
||||||
p_req("channel", param_short_channel_id, &channel),
|
p_req("channel", param_short_channel_id, &channel),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
tal_resize(&route, n_hops + 1);
|
tal_resize(&route, n_hops + 1);
|
||||||
|
|
||||||
@@ -990,8 +990,7 @@ static void json_sendpay(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n_hops == 0) {
|
if (n_hops == 0) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Empty route");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The given msatoshi is the actual payment that the payee is
|
/* 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) {
|
||||||
if (!(*msatoshi <= route[n_hops-1].amount &&
|
if (!(*msatoshi <= route[n_hops-1].amount &&
|
||||||
route[n_hops-1].amount <= 2 * *msatoshi)) {
|
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 %"PRIu64" out of range",
|
||||||
*msatoshi);
|
*msatoshi);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,7 +1011,8 @@ static void json_sendpay(struct command *cmd,
|
|||||||
msatoshi ? *msatoshi : route[n_hops-1].amount,
|
msatoshi ? *msatoshi : route[n_hops-1].amount,
|
||||||
description,
|
description,
|
||||||
&json_sendpay_on_resolve, cmd))
|
&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 = {
|
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");
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1040,15 +1039,15 @@ static void json_waitsendpay(struct command *cmd,
|
|||||||
p_req("payment_hash", param_sha256, &rhash),
|
p_req("payment_hash", param_sha256, &rhash),
|
||||||
p_opt("timeout", param_number, &timeout),
|
p_opt("timeout", param_number, &timeout),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (!wait_payment(cmd, cmd->ld, rhash, &json_waitsendpay_on_resolve, cmd))
|
if (!wait_payment(cmd, cmd->ld, rhash, &json_waitsendpay_on_resolve, cmd))
|
||||||
return;
|
return command_its_complicated();
|
||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
new_reltimer(&cmd->ld->timers, cmd, time_from_sec(*timeout),
|
new_reltimer(&cmd->ld->timers, cmd, time_from_sec(*timeout),
|
||||||
&waitsendpay_timeout, cmd);
|
&waitsendpay_timeout, cmd);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command waitsendpay_command = {
|
static const struct json_command waitsendpay_command = {
|
||||||
@@ -1059,7 +1058,7 @@ static const struct json_command waitsendpay_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1073,13 +1072,12 @@ static void json_listpayments(struct command *cmd,
|
|||||||
p_opt("bolt11", param_string, &b11str),
|
p_opt("bolt11", param_string, &b11str),
|
||||||
p_opt("payment_hash", param_sha256, &rhash),
|
p_opt("payment_hash", param_sha256, &rhash),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
if (rhash && b11str) {
|
if (rhash && b11str) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Can only specify one of"
|
"Can only specify one of"
|
||||||
" {bolt11} or {payment_hash}");
|
" {bolt11} or {payment_hash}");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b11str) {
|
if (b11str) {
|
||||||
@@ -1088,9 +1086,8 @@ static void json_listpayments(struct command *cmd,
|
|||||||
|
|
||||||
b11 = bolt11_decode(cmd, b11str, NULL, &fail);
|
b11 = bolt11_decode(cmd, b11str, NULL, &fail);
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Invalid bolt11: %s", fail);
|
"Invalid bolt11: %s", fail);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
rhash = &b11->payment_hash;
|
rhash = &b11->payment_hash;
|
||||||
}
|
}
|
||||||
@@ -1109,7 +1106,7 @@ static void json_listpayments(struct command *cmd,
|
|||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
|
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listpayments_command = {
|
static const struct json_command listpayments_command = {
|
||||||
|
|||||||
@@ -592,7 +592,7 @@ static void json_pay_stop_retrying(struct pay *pay)
|
|||||||
json_pay_failure(pay, sr);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -619,13 +619,12 @@ static void json_pay(struct command *cmd,
|
|||||||
cmd->ld->config.locktime_max),
|
cmd->ld->config.locktime_max),
|
||||||
p_opt_def("exemptfee", param_number, &exemptfee, 5000),
|
p_opt_def("exemptfee", param_number, &exemptfee, 5000),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
b11 = bolt11_decode(pay, b11str, desc, &fail);
|
b11 = bolt11_decode(pay, b11str, desc, &fail);
|
||||||
if (!b11) {
|
if (!b11) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Invalid bolt11: %s", fail);
|
"Invalid bolt11: %s", fail);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pay->cmd = cmd;
|
pay->cmd = cmd;
|
||||||
@@ -638,16 +637,14 @@ static void json_pay(struct command *cmd,
|
|||||||
|
|
||||||
if (b11->msatoshi) {
|
if (b11->msatoshi) {
|
||||||
if (msatoshi) {
|
if (msatoshi) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"msatoshi parameter unnecessary");
|
"msatoshi parameter unnecessary");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
msatoshi = b11->msatoshi;
|
msatoshi = b11->msatoshi;
|
||||||
} else {
|
} else {
|
||||||
if (!msatoshi) {
|
if (!msatoshi) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"msatoshi parameter required");
|
"msatoshi parameter required");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pay->msatoshi = *msatoshi;
|
pay->msatoshi = *msatoshi;
|
||||||
@@ -655,12 +652,11 @@ static void json_pay(struct command *cmd,
|
|||||||
pay->maxfeepercent = *maxfeepercent;
|
pay->maxfeepercent = *maxfeepercent;
|
||||||
|
|
||||||
if (*maxdelay < pay->min_final_cltv_expiry) {
|
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 "
|
"maxdelay (%u) must be greater than "
|
||||||
"min_final_cltv_expiry (%"PRIu32") of "
|
"min_final_cltv_expiry (%"PRIu32") of "
|
||||||
"invoice",
|
"invoice",
|
||||||
*maxdelay, pay->min_final_cltv_expiry);
|
*maxdelay, pay->min_final_cltv_expiry);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pay->maxdelay = *maxdelay;
|
pay->maxdelay = *maxdelay;
|
||||||
|
|
||||||
@@ -688,11 +684,12 @@ static void json_pay(struct command *cmd,
|
|||||||
if (json_pay_try(pay))
|
if (json_pay_try(pay))
|
||||||
command_still_pending(cmd);
|
command_still_pending(cmd);
|
||||||
else
|
else
|
||||||
return;
|
return command_its_complicated();
|
||||||
|
|
||||||
/* Set up timeout. */
|
/* Set up timeout. */
|
||||||
new_reltimer(&cmd->ld->timers, pay, time_from_sec(*retryfor),
|
new_reltimer(&cmd->ld->timers, pay, time_from_sec(*retryfor),
|
||||||
&json_pay_stop_retrying, pay);
|
&json_pay_stop_retrying, pay);
|
||||||
|
return command_its_complicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command pay_command = {
|
static const struct json_command pay_command = {
|
||||||
|
|||||||
@@ -803,7 +803,7 @@ static void json_add_peer(struct lightningd *ld,
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_listpeers(struct command *cmd,
|
static struct command_result *json_listpeers(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -817,7 +817,7 @@ static void json_listpeers(struct command *cmd,
|
|||||||
p_opt("id", param_pubkey, &specific_id),
|
p_opt("id", param_pubkey, &specific_id),
|
||||||
p_opt("level", param_loglevel, &ll),
|
p_opt("level", param_loglevel, &ll),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@@ -832,7 +832,7 @@ static void json_listpeers(struct command *cmd,
|
|||||||
}
|
}
|
||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listpeers_command = {
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("force", param_bool, &force, false),
|
||||||
p_opt_def("timeout", param_number, &timeout, 30),
|
p_opt_def("timeout", param_number, &timeout, 30),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_from_json(cmd->ld, buffer, idtok);
|
peer = peer_from_json(cmd->ld, buffer, idtok);
|
||||||
if (peer)
|
if (peer)
|
||||||
@@ -915,7 +915,7 @@ static void json_close(struct command *cmd,
|
|||||||
else {
|
else {
|
||||||
channel = command_find_channel(cmd, buffer, idtok);
|
channel = command_find_channel(cmd, buffer, idtok);
|
||||||
if (!channel)
|
if (!channel)
|
||||||
return;
|
return command_its_complicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel && peer) {
|
if (!channel && peer) {
|
||||||
@@ -924,12 +924,10 @@ static void json_close(struct command *cmd,
|
|||||||
/* Easy case: peer can simply be forgotten. */
|
/* Easy case: peer can simply be forgotten. */
|
||||||
kill_uncommitted_channel(uc, "close command called");
|
kill_uncommitted_channel(uc, "close command called");
|
||||||
|
|
||||||
command_success(cmd, null_response(cmd));
|
return command_success(cmd, null_response(cmd));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Peer has no active channel");
|
"Peer has no active channel");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal case.
|
/* Normal case.
|
||||||
@@ -941,9 +939,8 @@ static void json_close(struct command *cmd,
|
|||||||
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
||||||
channel->state != CHANNELD_SHUTTING_DOWN &&
|
channel->state != CHANNELD_SHUTTING_DOWN &&
|
||||||
channel->state != CLOSINGD_SIGEXCHANGE) {
|
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));
|
channel_state_name(channel));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If normal or locking in, transition to shutting down
|
/* 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);
|
register_close_command(cmd->ld, cmd, channel, *timeout, *force);
|
||||||
|
|
||||||
/* Wait until close drops down to chain. */
|
/* Wait until close drops down to chain. */
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command close_command = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1049,32 +1046,28 @@ static void json_disconnect(struct command *cmd,
|
|||||||
p_req("id", param_pubkey, &id),
|
p_req("id", param_pubkey, &id),
|
||||||
p_opt_def("force", param_bool, &force, false),
|
p_opt_def("force", param_bool, &force, false),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, id);
|
peer = peer_by_id(cmd->ld, id);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
if (*force) {
|
if (*force) {
|
||||||
channel_fail_transient(channel,
|
channel_fail_transient(channel,
|
||||||
"disconnect command force=true");
|
"disconnect command force=true");
|
||||||
command_success(cmd, null_response(cmd));
|
return command_success(cmd, null_response(cmd));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
command_fail(cmd, LIGHTNINGD, "Peer is in state %s",
|
return command_fail(cmd, LIGHTNINGD, "Peer is in state %s",
|
||||||
channel_state_name(channel));
|
channel_state_name(channel));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!peer->uncommitted_channel) {
|
if (!peer->uncommitted_channel) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
kill_uncommitted_channel(peer->uncommitted_channel,
|
kill_uncommitted_channel(peer->uncommitted_channel,
|
||||||
"disconnect command");
|
"disconnect command");
|
||||||
command_success(cmd, null_response(cmd));
|
return command_success(cmd, null_response(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command disconnect_command = {
|
static const struct json_command disconnect_command = {
|
||||||
@@ -1084,7 +1077,7 @@ static const struct json_command disconnect_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1096,7 +1089,7 @@ static void json_getinfo(struct command *cmd,
|
|||||||
inactive_channels = 0, num_peers = 0;
|
inactive_channels = 0, num_peers = 0;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@@ -1148,7 +1141,7 @@ static void json_getinfo(struct command *cmd,
|
|||||||
json_add_u64(response, "msatoshi_fees_collected",
|
json_add_u64(response, "msatoshi_fees_collected",
|
||||||
wallet_total_forward_fees(cmd->ld->wallet));
|
wallet_total_forward_fees(cmd->ld->wallet));
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command getinfo_command = {
|
static const struct json_command getinfo_command = {
|
||||||
@@ -1159,7 +1152,7 @@ static const struct json_command getinfo_command = {
|
|||||||
AUTODATA(json_command, &getinfo_command);
|
AUTODATA(json_command, &getinfo_command);
|
||||||
|
|
||||||
#if DEVELOPER
|
#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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1173,19 +1166,17 @@ static void json_sign_last_tx(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("id", param_pubkey, &peerid),
|
p_req("id", param_pubkey, &peerid),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, peerid);
|
peer = peer_by_id(cmd->ld, peerid);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find peer with that id");
|
"Could not find peer with that id");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find active channel");
|
"Could not find active channel");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -1198,7 +1189,7 @@ static void json_sign_last_tx(struct command *cmd,
|
|||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_hex_talarr(response, "tx", linear);
|
json_add_hex_talarr(response, "tx", linear);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_sign_last_tx = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1220,24 +1211,22 @@ static void json_dev_fail(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("id", param_pubkey, &peerid),
|
p_req("id", param_pubkey, &peerid),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, peerid);
|
peer = peer_by_id(cmd->ld, peerid);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find peer with that id");
|
"Could not find peer with that id");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find active channel with peer");
|
"Could not find active channel with peer");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_internal_error(channel, "Failing due to dev-fail command");
|
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 = {
|
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,
|
const int *fds UNUSED,
|
||||||
struct command *cmd)
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1268,37 +1257,33 @@ static void json_dev_reenable_commit(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("id", param_pubkey, &peerid),
|
p_req("id", param_pubkey, &peerid),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, peerid);
|
peer = peer_by_id(cmd->ld, peerid);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find peer with that id");
|
"Could not find peer with that id");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Peer has no active channel");
|
"Peer has no active channel");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!channel->owner) {
|
if (!channel->owner) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Peer has no owner");
|
"Peer has no owner");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!streq(channel->owner->name, "lightning_channeld")) {
|
if (!streq(channel->owner->name, "lightning_channeld")) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Peer owned by %s", channel->owner->name);
|
"Peer owned by %s", channel->owner->name);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = towire_channel_dev_reenable_commit(channel);
|
msg = towire_channel_dev_reenable_commit(channel);
|
||||||
subd_req(peer, channel->owner, take(msg), -1, 0,
|
subd_req(peer, channel->owner, take(msg), -1, 0,
|
||||||
dev_reenable_commit_finished, cmd);
|
dev_reenable_commit_finished, cmd);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_reenable_commit = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("short_channel_id", param_short_channel_id, &scid),
|
||||||
p_opt_def("force", param_bool, &force, false),
|
p_opt_def("force", param_bool, &force, false),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
forget->force = *force;
|
forget->force = *force;
|
||||||
peer = peer_by_id(cmd->ld, peerid);
|
peer = peer_by_id(cmd->ld, peerid);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find channel with that peer");
|
"Could not find channel with that peer");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forget->channel = NULL;
|
forget->channel = NULL;
|
||||||
@@ -1384,34 +1368,30 @@ static void json_dev_forget_channel(struct command *cmd,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (forget->channel) {
|
if (forget->channel) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Multiple channels:"
|
"Multiple channels:"
|
||||||
" please specify short_channel_id");
|
" please specify short_channel_id");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
forget->channel = channel;
|
forget->channel = channel;
|
||||||
}
|
}
|
||||||
if (!forget->channel) {
|
if (!forget->channel) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"No channels matching that short_channel_id");
|
"No channels matching that short_channel_id");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel_has_htlc_out(forget->channel) ||
|
if (channel_has_htlc_out(forget->channel) ||
|
||||||
channel_has_htlc_in(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 "
|
"This channel has HTLCs attached and it is "
|
||||||
"not safe to forget it. Please use `close` "
|
"not safe to forget it. Please use `close` "
|
||||||
"or `dev-fail` instead.");
|
"or `dev-fail` instead.");
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitcoind_gettxout(cmd->ld->topology->bitcoind,
|
bitcoind_gettxout(cmd->ld->topology->bitcoind,
|
||||||
&forget->channel->funding_txid,
|
&forget->channel->funding_txid,
|
||||||
forget->channel->funding_outnum,
|
forget->channel->funding_outnum,
|
||||||
process_dev_forget_channel, forget);
|
process_dev_forget_channel, forget);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_forget_channel_command = {
|
static const struct json_command dev_forget_channel_command = {
|
||||||
|
|||||||
@@ -1792,7 +1792,7 @@ void htlcs_reconnect(struct lightningd *ld,
|
|||||||
|
|
||||||
|
|
||||||
#if DEVELOPER
|
#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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("id", param_pubkey, &peerid),
|
||||||
p_req("ignore", param_bool, &ignore),
|
p_req("ignore", param_bool, &ignore),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
peer = peer_by_id(cmd->ld, peerid);
|
peer = peer_by_id(cmd->ld, peerid);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Could not find channel with that peer");
|
"Could not find channel with that peer");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
peer->ignore_htlcs = *ignore;
|
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 = {
|
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);
|
tal_free(forwardings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_listforwards(struct command *cmd,
|
static struct command_result *json_listforwards(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -1857,14 +1856,14 @@ static void json_listforwards(struct command *cmd,
|
|||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
listforwardings_add_forwardings(response, cmd->ld->wallet);
|
listforwardings_add_forwardings(response, cmd->ld->wallet);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
|
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listforwards_command = {
|
static const struct json_command listforwards_command = {
|
||||||
|
|||||||
@@ -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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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("len", param_number, &len, 128),
|
||||||
p_opt_def("pongbytes", param_number, &pongbytes, 128),
|
p_opt_def("pongbytes", param_number, &pongbytes, 128),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
/* BOLT #1:
|
/* BOLT #1:
|
||||||
*
|
*
|
||||||
@@ -110,16 +110,14 @@ static void json_ping(struct command *cmd,
|
|||||||
* * [`byteslen`:`ignored`]
|
* * [`byteslen`:`ignored`]
|
||||||
*/
|
*/
|
||||||
if (*len > 65535 - 2 - 2 - 2) {
|
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);
|
"%u would result in oversize ping", *len);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that > 65531 is valid: it means "no pong reply" */
|
/* Note that > 65531 is valid: it means "no pong reply" */
|
||||||
if (*pongbytes > 65535) {
|
if (*pongbytes > 65535) {
|
||||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"pongbytes %u > 65535", *pongbytes);
|
"pongbytes %u > 65535", *pongbytes);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent is cmd, so when we complete cmd, we free this. */
|
/* 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. */
|
/* gossipd handles all pinging, even if it's in another daemon. */
|
||||||
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
|
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
|
||||||
subd_send_msg(cmd->ld->gossip, take(msg));
|
subd_send_msg(cmd->ld->gossip, take(msg));
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command ping_command = {
|
static const struct json_command ping_command = {
|
||||||
|
|||||||
@@ -656,7 +656,8 @@ static struct plugin *find_plugin_for_command(struct command *cmd)
|
|||||||
abort();
|
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 *toks,
|
||||||
const jsmntok_t *params UNNEEDED)
|
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) {
|
if (cmd->mode == CMD_USAGE) {
|
||||||
/* FIXME! */
|
/* FIXME! */
|
||||||
cmd->usage = "[params]";
|
cmd->usage = "[params]";
|
||||||
return;
|
return command_param_failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin = find_plugin_for_command(cmd);
|
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);
|
json_stream_forward_change_id(req->stream, buffer, toks, idtok, id);
|
||||||
plugin_request_queue(plugin, req);
|
plugin_request_queue(plugin, req);
|
||||||
|
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool plugin_rpcmethod_add(struct plugin *plugin,
|
static bool plugin_rpcmethod_add(struct plugin *plugin,
|
||||||
|
|||||||
@@ -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 command_result *command_failed(struct command *cmd UNNEEDED,
|
||||||
struct json_stream *result UNNEEDED)
|
struct json_stream *result UNNEEDED)
|
||||||
{ fprintf(stderr, "command_failed called!\n"); abort(); }
|
{ 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 */
|
/* Generated stub for command_still_pending */
|
||||||
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
|
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
|
||||||
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
|
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
|
||||||
|
|||||||
@@ -55,6 +55,12 @@ struct command_result *command_fail(struct command *cmd UNNEEDED, int code UNNEE
|
|||||||
const char *fmt UNNEEDED, ...)
|
const char *fmt UNNEEDED, ...)
|
||||||
|
|
||||||
{ fprintf(stderr, "command_fail called!\n"); abort(); }
|
{ 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 */
|
/* Generated stub for command_still_pending */
|
||||||
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
|
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
|
||||||
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
|
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
|
||||||
|
|||||||
@@ -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
|
* request, select coins and a change key. Then send the request to
|
||||||
* the HSM to generate the signatures.
|
* 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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -105,17 +105,17 @@ static void json_withdraw(struct command *cmd,
|
|||||||
p_req("satoshi", param_tok, &sattok),
|
p_req("satoshi", param_tok, &sattok),
|
||||||
p_opt("feerate", param_feerate, &feerate_per_kw),
|
p_opt("feerate", param_feerate, &feerate_per_kw),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
res = param_wtx(&withdraw->wtx, buffer, sattok, -1ULL);
|
res = param_wtx(&withdraw->wtx, buffer, sattok, -1ULL);
|
||||||
if (res)
|
if (res)
|
||||||
return;
|
return res;
|
||||||
|
|
||||||
if (!feerate_per_kw) {
|
if (!feerate_per_kw) {
|
||||||
res = param_feerate_estimate(cmd, &feerate_per_kw,
|
res = param_feerate_estimate(cmd, &feerate_per_kw,
|
||||||
FEERATE_NORMAL);
|
FEERATE_NORMAL);
|
||||||
if (res)
|
if (res)
|
||||||
return;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse address. */
|
/* Parse address. */
|
||||||
@@ -126,22 +126,21 @@ static void json_withdraw(struct command *cmd,
|
|||||||
|
|
||||||
/* Check that destination address could be understood. */
|
/* Check that destination address could be understood. */
|
||||||
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
if (addr_parse == ADDRESS_PARSE_UNRECOGNIZED) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Could not parse destination address");
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
return;
|
"Could not parse destination address");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check address given is compatible with the chain we are on. */
|
/* Check address given is compatible with the chain we are on. */
|
||||||
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
if (addr_parse == ADDRESS_PARSE_WRONG_NETWORK) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Destination address is not on network %s",
|
"Destination address is not on network %s",
|
||||||
get_chainparams(cmd->ld)->network_name);
|
get_chainparams(cmd->ld)->network_name);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = wtx_select_utxos(&withdraw->wtx, *feerate_per_kw,
|
res = wtx_select_utxos(&withdraw->wtx, *feerate_per_kw,
|
||||||
tal_count(withdraw->destination));
|
tal_count(withdraw->destination));
|
||||||
if (res)
|
if (res)
|
||||||
return;
|
return res;
|
||||||
|
|
||||||
u8 *msg = towire_hsm_sign_withdrawal(cmd,
|
u8 *msg = towire_hsm_sign_withdrawal(cmd,
|
||||||
withdraw->wtx.amount,
|
withdraw->wtx.amount,
|
||||||
@@ -164,7 +163,7 @@ static void json_withdraw(struct command *cmd,
|
|||||||
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
|
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
|
||||||
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
|
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
|
||||||
wallet_withdrawal_broadcast, withdraw);
|
wallet_withdrawal_broadcast, withdraw);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command withdraw_command = {
|
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);
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -263,24 +262,21 @@ static void json_newaddr(struct command *cmd,
|
|||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_opt_def("addresstype", param_newaddr, &is_p2wpkh, true),
|
p_opt_def("addresstype", param_newaddr, &is_p2wpkh, true),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
keyidx = wallet_get_newindex(cmd->ld);
|
keyidx = wallet_get_newindex(cmd->ld);
|
||||||
if (keyidx < 0) {
|
if (keyidx < 0) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
|
return command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base, keyidx,
|
||||||
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Keys generation failure");
|
return command_fail(cmd, LIGHTNINGD, "Keys generation failure");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey.pubkey,
|
||||||
ext.pub_key, sizeof(ext.pub_key))) {
|
ext.pub_key, sizeof(ext.pub_key))) {
|
||||||
command_fail(cmd, LIGHTNINGD, "Key parsing failure");
|
return command_fail(cmd, LIGHTNINGD, "Key parsing failure");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
|
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
|
||||||
@@ -289,16 +285,15 @@ static void json_newaddr(struct command *cmd,
|
|||||||
&pubkey, !*is_p2wpkh,
|
&pubkey, !*is_p2wpkh,
|
||||||
NULL);
|
NULL);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"p2wpkh address encoding failure.");
|
"p2wpkh address encoding failure.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_string(response, "address", out);
|
json_add_string(response, "address", out);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command newaddr_command = {
|
static const struct json_command newaddr_command = {
|
||||||
@@ -309,7 +304,7 @@ static const struct json_command newaddr_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -324,7 +319,7 @@ static void json_listaddrs(struct command *cmd,
|
|||||||
db_get_intvar(cmd->ld->wallet->db,
|
db_get_intvar(cmd->ld->wallet->db,
|
||||||
"bip32_max_index", 0)),
|
"bip32_max_index", 0)),
|
||||||
NULL))
|
NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@@ -377,7 +372,7 @@ static void json_listaddrs(struct command *cmd,
|
|||||||
}
|
}
|
||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listaddrs_command = {
|
static const struct json_command listaddrs_command = {
|
||||||
@@ -389,7 +384,7 @@ static const struct json_command listaddrs_command = {
|
|||||||
};
|
};
|
||||||
AUTODATA(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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
@@ -401,7 +396,7 @@ static void json_listfunds(struct command *cmd,
|
|||||||
struct pubkey funding_pubkey;
|
struct pubkey funding_pubkey;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available);
|
utxos = wallet_get_utxos(cmd, cmd->ld->wallet, output_state_available);
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
@@ -422,9 +417,8 @@ static void json_listfunds(struct command *cmd,
|
|||||||
utxos[i]->is_p2sh,
|
utxos[i]->is_p2sh,
|
||||||
NULL);
|
NULL);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"p2wpkh address encoding failure.");
|
"p2wpkh address encoding failure.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
json_add_string(response, "address", out);
|
json_add_string(response, "address", out);
|
||||||
}
|
}
|
||||||
@@ -464,7 +458,7 @@ static void json_listfunds(struct command *cmd,
|
|||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
|
|
||||||
command_success(cmd, response);
|
return command_success(cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command listfunds_command = {
|
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 char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
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);
|
struct txo_rescan *rescan = tal(cmd, struct txo_rescan);
|
||||||
|
|
||||||
if (!param(cmd, buffer, params, NULL))
|
if (!param(cmd, buffer, params, NULL))
|
||||||
return;
|
return command_param_failed();
|
||||||
|
|
||||||
rescan->response = json_stream_success(cmd);
|
rescan->response = json_stream_success(cmd);
|
||||||
rescan->cmd = cmd;
|
rescan->cmd = cmd;
|
||||||
@@ -537,13 +531,12 @@ static void json_dev_rescan_outputs(struct command *cmd,
|
|||||||
if (tal_count(rescan->utxos) == 0) {
|
if (tal_count(rescan->utxos) == 0) {
|
||||||
json_array_end(rescan->response);
|
json_array_end(rescan->response);
|
||||||
json_object_end(rescan->response);
|
json_object_end(rescan->response);
|
||||||
command_success(cmd, rescan->response);
|
return command_success(cmd, rescan->response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
bitcoind_gettxout(cmd->ld->topology->bitcoind, &rescan->utxos[0]->txid,
|
bitcoind_gettxout(cmd->ld->topology->bitcoind, &rescan->utxos[0]->txid,
|
||||||
rescan->utxos[0]->outnum, process_utxo_result,
|
rescan->utxos[0]->outnum, process_utxo_result,
|
||||||
rescan);
|
rescan);
|
||||||
command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct json_command dev_rescan_output_command = {
|
static const struct json_command dev_rescan_output_command = {
|
||||||
|
|||||||
Reference in New Issue
Block a user