Browse Source

rpc: add check command

The check command allows us to check the parameters of a command
without running it. Example:

	lightning-cli check invoice 234 foo desc

We do this by removing the "command_to_check" parameter and then using the
remaining parameters as-is.

I chose the parameter name "command_to_check" instead of just "command" because
it must be unique to all other parameter names for all other commands. Why?
Because it may be ambiguous in the case of a json object, where the parameters are
not necessary ordered.  We don't know which one is the command to check and
which one is a parameter.

Signed-off-by: Mark Beckwith <wythe@intrig.com>
plugin-6
Mark Beckwith 6 years ago
committed by Rusty Russell
parent
commit
70707bf767
  1. 1
      CHANGELOG.md
  2. 68
      lightningd/jsonrpc.c
  3. 4
      lightningd/jsonrpc.h
  4. 6
      lightningd/param.c

1
CHANGELOG.md

@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- JSON API: New command `check` checks the validity of a JSON API call without running it.
- JSON API: `getinfo` now returns `num_peers` `num_pending_channels`,
`num_active_channels` and `num_inactive_channels` fields.
- JSON API: use `\n\n` to terminate responses, for simplified parsing (pylightning now relies on this)

68
lightningd/jsonrpc.c

@ -937,3 +937,71 @@ bool json_tok_wtx(struct wallet_tx * tx, const char * buffer,
}
return true;
}
static bool json_tok_command(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
const jsmntok_t **out)
{
cmd->json_cmd = find_cmd(cmd->jcon->ld->jsonrpc, buffer, tok);
if (cmd->json_cmd)
return (*out = tok);
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' of '%.*s' is invalid",
name, tok->end - tok->start, buffer + tok->start);
return false;
}
static void json_check(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *mod_params;
const jsmntok_t *name_tok;
bool ok;
struct json_stream *response;
if (cmd->mode == CMD_USAGE) {
mod_params = NULL;
} else {
mod_params = json_tok_copy(cmd, params);
cmd->allow_unused = true;
}
if (!param(cmd, buffer, mod_params,
p_req("command_to_check", json_tok_command, &name_tok),
NULL))
return;
/* Point name_tok to the name, not the value */
if (params->type == JSMN_OBJECT)
name_tok--;
json_tok_remove(&mod_params, (jsmntok_t *)name_tok, 1);
cmd->mode = CMD_CHECK;
cmd->allow_unused = false;
/* FIXME(wythe): Maybe change "ok" to "failed" since that's really what
* we're after and would be more clear. */
ok = true;
cmd->ok = &ok;
cmd->json_cmd->dispatch(cmd, buffer, mod_params);
if (!ok)
return;
response = json_stream_success(cmd);
json_object_start(response, NULL);
json_add_string(response, "command", cmd->json_cmd->name);
json_add_string(response, "parameters", "ok");
json_object_end(response);
command_success(cmd, response);
}
static const struct json_command check_command = {
"check",
json_check,
"Don't run {command_to_check}, just verify parameters.",
.verbose = "check command_to_check [parameters...]\n"
};
AUTODATA(json_command, &check_command);

4
lightningd/jsonrpc.h

@ -13,7 +13,9 @@ enum command_mode {
/* Normal command processing */
CMD_NORMAL,
/* Create command usage string, nothing else. */
CMD_USAGE
CMD_USAGE,
/* Check parameters, nothing else. */
CMD_CHECK
};
/* Context for a command (from JSON, but might outlive the connection!). */

6
lightningd/param.c

@ -283,5 +283,9 @@ bool param(struct command *cmd, const char *buffer,
return false;
}
return param_arr(cmd, buffer, tokens, params);
/* Always return false for CMD_USAGE and CMD_CHECK, signaling the caller
* to return immediately. For CMD_NORMAL, return true if all parameters
* are valid.
*/
return param_arr(cmd, buffer, tokens, params) && cmd->mode == CMD_NORMAL;
}

Loading…
Cancel
Save