2017-08-28 18:06:01 +02:00
|
|
|
#ifndef LIGHTNING_LIGHTNINGD_JSONRPC_H
|
|
|
|
#define LIGHTNING_LIGHTNINGD_JSONRPC_H
|
2016-01-21 21:11:48 +01:00
|
|
|
#include "config.h"
|
2018-11-20 02:46:32 +01:00
|
|
|
#include <ccan/list/list.h>
|
2021-09-21 09:23:10 +02:00
|
|
|
#include <common/autodata.h>
|
2020-01-20 10:23:55 +01:00
|
|
|
#include <common/json_stream.h>
|
2020-10-12 07:33:51 +02:00
|
|
|
#include <common/status_levels.h>
|
2016-01-21 21:11:48 +01:00
|
|
|
|
2019-02-04 11:55:42 +01:00
|
|
|
struct jsonrpc;
|
|
|
|
|
2018-09-12 17:56:39 +02:00
|
|
|
/* The command mode tells param() how to process. */
|
|
|
|
enum command_mode {
|
|
|
|
/* Normal command processing */
|
|
|
|
CMD_NORMAL,
|
|
|
|
/* Create command usage string, nothing else. */
|
2018-11-27 00:48:18 +01:00
|
|
|
CMD_USAGE,
|
|
|
|
/* Check parameters, nothing else. */
|
2023-10-24 04:29:45 +02:00
|
|
|
CMD_CHECK,
|
|
|
|
/* Check parameters, and one failed. */
|
|
|
|
CMD_CHECK_FAILED,
|
2018-09-12 17:56:39 +02:00
|
|
|
};
|
|
|
|
|
2018-11-20 02:46:32 +01:00
|
|
|
/* Context for a command (from JSON, but might outlive the connection!). */
|
|
|
|
/* FIXME: move definition into jsonrpc.c */
|
2016-01-21 21:11:48 +01:00
|
|
|
struct command {
|
2021-11-02 08:55:19 +01:00
|
|
|
/* Off list jcon->commands */
|
2018-11-20 02:46:32 +01:00
|
|
|
struct list_node list;
|
2016-01-21 21:11:48 +01:00
|
|
|
/* The global state */
|
2017-08-28 18:09:01 +02:00
|
|
|
struct lightningd *ld;
|
2016-01-21 21:11:48 +01:00
|
|
|
/* The 'id' which we need to include in the response. */
|
|
|
|
const char *id;
|
2022-09-12 23:19:11 +02:00
|
|
|
/* If 'id' needs to be quoted (i.e. it's a string) */
|
|
|
|
bool id_is_string;
|
2018-07-26 23:19:37 +02:00
|
|
|
/* What command we're running (for logging) */
|
|
|
|
const struct json_command *json_cmd;
|
2016-01-21 21:11:48 +01:00
|
|
|
/* The connection, or NULL if it closed. */
|
|
|
|
struct json_connection *jcon;
|
2020-10-12 07:33:50 +02:00
|
|
|
/* Does this want notifications? */
|
|
|
|
bool send_notifications;
|
2017-12-15 11:15:54 +01:00
|
|
|
/* Have we been marked by command_still_pending? For debugging... */
|
|
|
|
bool pending;
|
2018-09-12 17:56:39 +02:00
|
|
|
/* Tell param() how to process the command */
|
|
|
|
enum command_mode mode;
|
2018-10-19 03:17:48 +02:00
|
|
|
/* Have we started a json stream already? For debugging. */
|
2019-06-12 02:38:55 +02:00
|
|
|
struct json_stream *json_stream;
|
2022-11-04 04:30:48 +01:00
|
|
|
/* Optional output field filter. */
|
|
|
|
struct json_filter *filter;
|
2016-01-21 21:11:48 +01:00
|
|
|
};
|
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
/**
|
|
|
|
* Dummy structure to make sure you call one of
|
|
|
|
* command_success / command_failed / command_still_pending.
|
|
|
|
*/
|
|
|
|
struct command_result;
|
|
|
|
|
2016-01-21 21:11:48 +01:00
|
|
|
struct json_command {
|
|
|
|
const char *name;
|
2019-05-22 16:08:16 +02:00
|
|
|
const char *category;
|
2018-12-16 05:52:06 +01:00
|
|
|
struct command_result *(*dispatch)(struct command *,
|
|
|
|
const char *buffer,
|
|
|
|
const jsmntok_t *obj,
|
|
|
|
const jsmntok_t *params);
|
2016-01-21 21:11:48 +01:00
|
|
|
const char *description;
|
2018-01-29 01:30:15 +01:00
|
|
|
const char *verbose;
|
2023-09-21 07:36:27 +02:00
|
|
|
bool dev_only;
|
2024-01-25 01:28:55 +01:00
|
|
|
const char *depr_start, *depr_end;
|
2016-01-21 21:11:48 +01:00
|
|
|
};
|
|
|
|
|
2018-12-11 18:14:15 +01:00
|
|
|
struct jsonrpc_notification {
|
|
|
|
/* The topic that this notification is for. Internally this
|
|
|
|
* will be serialized as "method", hence the different name
|
|
|
|
* here */
|
|
|
|
const char *method;
|
|
|
|
struct json_stream *stream;
|
|
|
|
};
|
|
|
|
|
2018-12-21 14:02:34 +01:00
|
|
|
struct jsonrpc_request {
|
2022-09-12 23:19:11 +02:00
|
|
|
const char *id;
|
2022-11-21 02:48:32 +01:00
|
|
|
bool id_is_string;
|
2018-12-21 14:02:34 +01:00
|
|
|
const char *method;
|
|
|
|
struct json_stream *stream;
|
2020-10-12 07:33:50 +02:00
|
|
|
void (*notify_cb)(const char *buffer,
|
|
|
|
const jsmntok_t *idtok,
|
|
|
|
const jsmntok_t *methodtok,
|
|
|
|
const jsmntok_t *paramtoks,
|
|
|
|
void *);
|
2018-12-21 14:02:34 +01:00
|
|
|
void (*response_cb)(const char *buffer, const jsmntok_t *toks,
|
|
|
|
const jsmntok_t *idtok, void *);
|
|
|
|
void *response_cb_arg;
|
|
|
|
};
|
|
|
|
|
2018-11-20 02:46:32 +01:00
|
|
|
/**
|
2019-06-12 02:38:54 +02:00
|
|
|
* json_stream_success - start streaming a successful json result object.
|
2018-11-20 02:46:32 +01:00
|
|
|
* @cmd: the command we're running.
|
|
|
|
*
|
|
|
|
* The returned value should go to command_success() when done.
|
|
|
|
* json_add_* will be placed into the 'result' field of the JSON reply.
|
|
|
|
*/
|
|
|
|
struct json_stream *json_stream_success(struct command *cmd);
|
|
|
|
|
|
|
|
/**
|
2019-06-12 02:38:54 +02:00
|
|
|
* json_stream_fail - start streaming a failed json result, with data object.
|
2018-11-20 02:46:32 +01:00
|
|
|
* @cmd: the command we're running.
|
2018-12-08 01:39:28 +01:00
|
|
|
* @code: the error code from common/jsonrpc_errors.h
|
2018-11-20 02:46:32 +01:00
|
|
|
* @errmsg: the error string.
|
|
|
|
*
|
|
|
|
* The returned value should go to command_failed() when done;
|
|
|
|
* json_add_* will be placed into the 'data' field of the 'error' JSON reply.
|
2019-06-12 02:38:54 +02:00
|
|
|
* You need to json_object_end() once you're done!
|
2018-11-20 02:46:32 +01:00
|
|
|
*/
|
|
|
|
struct json_stream *json_stream_fail(struct command *cmd,
|
2022-09-18 02:20:50 +02:00
|
|
|
enum jsonrpc_errcode code,
|
2018-11-20 02:46:32 +01:00
|
|
|
const char *errmsg);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* json_stream_fail_nodata - start streaming a failed json result.
|
|
|
|
* @cmd: the command we're running.
|
2018-12-08 01:39:28 +01:00
|
|
|
* @code: the error code from common/jsonrpc_errors.h
|
2018-11-20 02:46:32 +01:00
|
|
|
* @errmsg: the error string.
|
|
|
|
*
|
|
|
|
* This is used by command_fail(), which doesn't add any JSON data.
|
|
|
|
*/
|
|
|
|
struct json_stream *json_stream_fail_nodata(struct command *cmd,
|
2022-09-18 02:20:50 +02:00
|
|
|
enum jsonrpc_errcode code,
|
2018-11-20 02:46:32 +01:00
|
|
|
const char *errmsg);
|
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
/* These returned values are never NULL. */
|
|
|
|
struct command_result *command_success(struct command *cmd,
|
2018-12-16 05:53:06 +01:00
|
|
|
struct json_stream *response)
|
|
|
|
WARN_UNUSED_RESULT;
|
2019-06-12 02:38:54 +02:00
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
struct command_result *command_failed(struct command *cmd,
|
2018-12-16 05:53:06 +01:00
|
|
|
struct json_stream *result)
|
|
|
|
WARN_UNUSED_RESULT;
|
2016-01-21 21:11:48 +01:00
|
|
|
|
2017-12-15 11:15:54 +01:00
|
|
|
/* Mainly for documentation, that we plan to close this later. */
|
2018-12-16 05:53:06 +01:00
|
|
|
struct command_result *command_still_pending(struct command *cmd)
|
|
|
|
WARN_UNUSED_RESULT;
|
2017-12-15 11:15:54 +01:00
|
|
|
|
2018-12-08 01:35:56 +01:00
|
|
|
/* For low-level JSON stream access: */
|
|
|
|
struct json_stream *json_stream_raw_for_cmd(struct command *cmd);
|
2019-05-23 12:09:17 +02:00
|
|
|
void json_stream_log_suppress_for_cmd(struct json_stream *js,
|
|
|
|
const struct command *cmd);
|
2018-12-16 05:49:06 +01:00
|
|
|
struct command_result *command_raw_complete(struct command *cmd,
|
|
|
|
struct json_stream *result);
|
|
|
|
|
2022-09-13 02:27:43 +02:00
|
|
|
/* Logging point to use for this command (usually, the JSON connection). */
|
2023-07-16 07:56:52 +02:00
|
|
|
struct logger *command_log(struct command *cmd);
|
2022-09-13 02:27:43 +02:00
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
/* To return if param() fails. */
|
2018-12-16 05:53:06 +01:00
|
|
|
extern struct command_result *command_param_failed(void)
|
|
|
|
WARN_UNUSED_RESULT;
|
2018-12-16 05:49:06 +01:00
|
|
|
|
2023-10-24 04:29:45 +02:00
|
|
|
/* To return after param_check() succeeds but we're still
|
|
|
|
* command_check_only(cmd). */
|
|
|
|
struct command_result *command_check_done(struct command *cmd)
|
|
|
|
WARN_UNUSED_RESULT;
|
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
/* Wrapper for pending commands (ignores return) */
|
|
|
|
static inline void was_pending(const struct command_result *res)
|
|
|
|
{
|
|
|
|
assert(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transition for ignoring command */
|
|
|
|
static inline void fixme_ignore(const struct command_result *res)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-10-12 07:33:51 +02:00
|
|
|
/* Notifier to the caller. */
|
|
|
|
void json_notify_fmt(struct command *cmd,
|
|
|
|
enum log_level level,
|
|
|
|
const char *fmt, ...)
|
|
|
|
PRINTF_FMT(3, 4);
|
|
|
|
|
2018-12-16 05:49:06 +01:00
|
|
|
/* FIXME: For the few cases where return value is indeterminate */
|
2018-12-17 04:52:08 +01:00
|
|
|
struct command_result *command_its_complicated(const char *why);
|
2018-12-08 01:35:56 +01:00
|
|
|
|
2024-01-25 01:28:56 +01:00
|
|
|
/* command can override ld->deprecated_ok */
|
|
|
|
bool command_deprecated_ok_flag(const struct command *cmd);
|
|
|
|
|
2018-11-22 11:37:08 +01:00
|
|
|
/**
|
|
|
|
* Create a new jsonrpc to wrap all related information.
|
|
|
|
*
|
|
|
|
* This doesn't setup the listener yet, see `jsonrpc_listen` for
|
|
|
|
* that. This just creates the container for all jsonrpc-related
|
|
|
|
* information so we can start gathering it before actually starting.
|
2019-02-04 11:55:42 +01:00
|
|
|
*
|
|
|
|
* It initializes ld->jsonrpc.
|
2018-11-22 11:37:08 +01:00
|
|
|
*/
|
2019-02-04 11:55:42 +01:00
|
|
|
void jsonrpc_setup(struct lightningd *ld);
|
2018-11-22 11:37:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2022-09-11 09:51:18 +02:00
|
|
|
* Start listening on ld->rpc_filename.
|
2018-11-22 11:37:08 +01:00
|
|
|
*
|
|
|
|
* Sets up the listener effectively starting the RPC interface.
|
|
|
|
*/
|
|
|
|
void jsonrpc_listen(struct jsonrpc *rpc, struct lightningd *ld);
|
2018-11-14 08:12:03 +01:00
|
|
|
|
2022-09-11 09:51:18 +02:00
|
|
|
/**
|
|
|
|
* Stop listening on ld->rpc_filename.
|
|
|
|
*
|
|
|
|
* No new connections from here in.
|
|
|
|
*/
|
|
|
|
void jsonrpc_stop_listening(struct jsonrpc *jsonrpc);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Kill any remaining JSON-RPC connections.
|
|
|
|
*/
|
|
|
|
void jsonrpc_stop_all(struct lightningd *ld);
|
|
|
|
|
2018-11-14 08:12:03 +01:00
|
|
|
/**
|
|
|
|
* Add a new command/method to the JSON-RPC interface.
|
|
|
|
*
|
|
|
|
* Returns true if the command was added correctly, false if adding
|
|
|
|
* this would clobber a command name.
|
2018-11-22 23:11:26 +01:00
|
|
|
*
|
2019-02-04 11:55:42 +01:00
|
|
|
* Free @command to remove it.
|
2018-11-22 23:11:26 +01:00
|
|
|
*/
|
2019-02-04 11:55:42 +01:00
|
|
|
bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command,
|
|
|
|
const char *usage TAKES);
|
2018-11-22 23:11:26 +01:00
|
|
|
|
2018-12-11 18:14:15 +01:00
|
|
|
/**
|
|
|
|
* Begin a JSON-RPC notification with the specified topic.
|
|
|
|
*
|
|
|
|
* Automatically starts the `params` object, hence only key-value
|
|
|
|
* based params are supported at the moment.
|
|
|
|
*/
|
|
|
|
struct jsonrpc_notification *jsonrpc_notification_start(const tal_t *ctx, const char *topic);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Counterpart to jsonrpc_notification_start.
|
|
|
|
*/
|
|
|
|
void jsonrpc_notification_end(struct jsonrpc_notification *n);
|
|
|
|
|
2022-09-12 23:19:11 +02:00
|
|
|
/**
|
|
|
|
* start a JSONRPC request; id_prefix is non-NULL if this was triggered by
|
|
|
|
* another JSONRPC request.
|
|
|
|
*/
|
2022-11-21 02:48:32 +01:00
|
|
|
#define jsonrpc_request_start(ctx, method, id_prefix, id_as_string, log, notify_cb, response_cb, response_cb_arg) \
|
2018-12-21 14:02:34 +01:00
|
|
|
jsonrpc_request_start_( \
|
2022-11-21 02:48:32 +01:00
|
|
|
(ctx), (method), (id_prefix), (id_as_string), (log), true, \
|
2020-10-12 07:33:50 +02:00
|
|
|
typesafe_cb_preargs(void, void *, (notify_cb), (response_cb_arg), \
|
|
|
|
const char *buffer, \
|
|
|
|
const jsmntok_t *idtok, \
|
|
|
|
const jsmntok_t *methodtok, \
|
|
|
|
const jsmntok_t *paramtoks), \
|
2018-12-21 14:02:34 +01:00
|
|
|
typesafe_cb_preargs(void, void *, (response_cb), (response_cb_arg), \
|
|
|
|
const char *buffer, \
|
|
|
|
const jsmntok_t *toks, \
|
|
|
|
const jsmntok_t *idtok), \
|
|
|
|
(response_cb_arg))
|
|
|
|
|
2022-11-21 02:48:32 +01:00
|
|
|
#define jsonrpc_request_start_raw(ctx, method, id_prefix, id_as_string,log, notify_cb, response_cb, response_cb_arg) \
|
2022-09-12 23:19:11 +02:00
|
|
|
jsonrpc_request_start_( \
|
2022-11-21 02:48:32 +01:00
|
|
|
(ctx), (method), (id_prefix), (id_as_string), (log), false, \
|
2022-09-12 23:19:11 +02:00
|
|
|
typesafe_cb_preargs(void, void *, (notify_cb), (response_cb_arg), \
|
|
|
|
const char *buffer, \
|
|
|
|
const jsmntok_t *idtok, \
|
|
|
|
const jsmntok_t *methodtok, \
|
|
|
|
const jsmntok_t *paramtoks), \
|
|
|
|
typesafe_cb_preargs(void, void *, (response_cb), (response_cb_arg), \
|
|
|
|
const char *buffer, \
|
|
|
|
const jsmntok_t *toks, \
|
|
|
|
const jsmntok_t *idtok), \
|
|
|
|
(response_cb_arg))
|
|
|
|
|
2018-12-21 14:02:34 +01:00
|
|
|
struct jsonrpc_request *jsonrpc_request_start_(
|
2022-09-12 23:19:11 +02:00
|
|
|
const tal_t *ctx, const char *method,
|
2022-11-21 02:48:32 +01:00
|
|
|
const char *id_prefix TAKES,
|
|
|
|
bool id_as_string,
|
2023-07-16 07:56:52 +02:00
|
|
|
struct logger *log, bool add_header,
|
2020-10-12 07:33:50 +02:00
|
|
|
void (*notify_cb)(const char *buffer,
|
|
|
|
const jsmntok_t *idtok,
|
|
|
|
const jsmntok_t *methodtok,
|
|
|
|
const jsmntok_t *paramtoks,
|
|
|
|
void *),
|
2018-12-21 14:02:34 +01:00
|
|
|
void (*response_cb)(const char *buffer, const jsmntok_t *toks,
|
|
|
|
const jsmntok_t *idtok, void *),
|
|
|
|
void *response_cb_arg);
|
|
|
|
|
|
|
|
void jsonrpc_request_end(struct jsonrpc_request *request);
|
|
|
|
|
2017-01-04 04:38:15 +01:00
|
|
|
AUTODATA_TYPE(json_command, struct json_command);
|
2019-02-04 11:55:42 +01:00
|
|
|
|
2017-08-28 18:06:01 +02:00
|
|
|
#endif /* LIGHTNING_LIGHTNINGD_JSONRPC_H */
|