From 83775e7cea49ae0119a18ad32ddc7a650ae90803 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 22 Nov 2018 11:37:08 +0100 Subject: [PATCH] jsonrpc: Split the jsonrpc object creation from starting to listen This is needed in order to be able to add methods while initializing the plugins, but before actually moving to the config dir and starting to listen. Signed-off-by: Christian Decker --- lightningd/jsonrpc.c | 18 ++++++++++-------- lightningd/jsonrpc.h | 18 ++++++++++++++++-- lightningd/lightningd.c | 9 ++++++++- lightningd/test/run-find_my_abspath.c | 9 ++++++--- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 6b36cef8b..cdfc9b2cd 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -738,7 +738,7 @@ bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command) return true; } -static struct jsonrpc *jsonrpc_new(const tal_t *ctx, struct lightningd *ld, int fd) +struct jsonrpc *jsonrpc_new(const tal_t *ctx, struct lightningd *ld) { struct jsonrpc *jsonrpc = tal(ctx, struct jsonrpc); struct json_command **commands = get_cmdlist(); @@ -748,25 +748,26 @@ static struct jsonrpc *jsonrpc_new(const tal_t *ctx, struct lightningd *ld, int for (size_t i=0; irpc_listener = io_new_listener( - ld->rpc_filename, fd, incoming_jcon_connected, ld); - log_debug(jsonrpc->log, "Listening on '%s'", ld->rpc_filename); + jsonrpc->rpc_listener = NULL; return jsonrpc; } -struct jsonrpc *setup_jsonrpc(struct lightningd *ld) +void jsonrpc_listen(struct jsonrpc *jsonrpc, struct lightningd *ld) { struct sockaddr_un addr; int fd, old_umask; const char *rpc_filename = ld->rpc_filename; + /* Should not initialize it twice. */ + assert(!jsonrpc->rpc_listener); + if (streq(rpc_filename, "/dev/tty")) { fd = open(rpc_filename, O_RDWR); if (fd == -1) err(1, "Opening %s", rpc_filename); /* Technically this is a leak, but there's only one */ notleak(io_new_conn(ld, fd, jcon_connected, ld)); - return jsonrpc_new(ld, ld, fd); + return; } fd = socket(AF_UNIX, SOCK_STREAM, 0); @@ -791,8 +792,9 @@ struct jsonrpc *setup_jsonrpc(struct lightningd *ld) if (listen(fd, 1) != 0) err(1, "Listening on '%s'", rpc_filename); - - return jsonrpc_new(ld, ld, fd); + jsonrpc->rpc_listener = io_new_listener( + ld->rpc_filename, fd, incoming_jcon_connected, ld); + log_debug(jsonrpc->log, "Listening on '%s'", ld->rpc_filename); } /** diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index 108a47625..71e7edc09 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -92,8 +92,22 @@ void PRINTF_FMT(3, 4) command_fail(struct command *cmd, int code, /* Mainly for documentation, that we plan to close this later. */ void command_still_pending(struct command *cmd); -/* For initialization */ -struct jsonrpc *setup_jsonrpc(struct lightningd *ld); +/** + * 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. + */ +struct jsonrpc *jsonrpc_new(const tal_t *ctx, struct lightningd *ld); + + +/** + * Start listeing on ld->rpc_filename. + * + * Sets up the listener effectively starting the RPC interface. + */ +void jsonrpc_listen(struct jsonrpc *rpc, struct lightningd *ld); /** * Add a new command/method to the JSON-RPC interface. diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 293f13fe2..04b9b3fef 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -201,6 +201,13 @@ static struct lightningd *new_lightningd(const tal_t *ctx) ld->tor_service_password = NULL; ld->max_funding_unconfirmed = 2016; + /*~ In the next step we will initialize the plugins. This will + * also populate the JSON-RPC with passthrough methods, hence + * lightningd needs to have something to put those in. This + * is that :-) + */ + ld->jsonrpc = jsonrpc_new(ld, ld); + /*~ We run a number of plugins (subprocesses that we talk JSON-RPC with) *alongside this process. This allows us to have an easy way for users *to add their own tools without having to modify the c-lightning source @@ -695,7 +702,7 @@ int main(int argc, char *argv[]) /*~ Create RPC socket: now lightning-cli can send us JSON RPC commands * over a UNIX domain socket specified by `ld->rpc_filename`. */ - ld->jsonrpc = setup_jsonrpc(ld); + jsonrpc_listen(ld->jsonrpc, ld); /*~ We defer --daemon until we've completed most initialization: that * way we'll exit with an error rather than silently exiting 0, then diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index 03c5ad076..dfadc0691 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -90,6 +90,12 @@ void htlcs_notify_new_block(struct lightningd *ld UNNEEDED, u32 height UNNEEDED) /* Generated stub for json_escape */ struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKES UNNEEDED) { fprintf(stderr, "json_escape called!\n"); abort(); } +/* Generated stub for jsonrpc_listen */ +void jsonrpc_listen(struct jsonrpc *rpc UNNEEDED, struct lightningd *ld UNNEEDED) +{ fprintf(stderr, "jsonrpc_listen called!\n"); abort(); } +/* Generated stub for jsonrpc_new */ +struct jsonrpc *jsonrpc_new(const tal_t *ctx UNNEEDED, struct lightningd *ld UNNEEDED) +{ fprintf(stderr, "jsonrpc_new called!\n"); abort(); } /* Generated stub for load_channels_from_wallet */ void load_channels_from_wallet(struct lightningd *ld UNNEEDED) { fprintf(stderr, "load_channels_from_wallet called!\n"); abort(); } @@ -137,9 +143,6 @@ void register_opts(struct lightningd *ld UNNEEDED) /* Generated stub for setup_color_and_alias */ void setup_color_and_alias(struct lightningd *ld UNNEEDED) { fprintf(stderr, "setup_color_and_alias called!\n"); abort(); } -/* Generated stub for setup_jsonrpc */ -struct jsonrpc *setup_jsonrpc(struct lightningd *ld UNNEEDED) -{ fprintf(stderr, "setup_jsonrpc called!\n"); abort(); } /* Generated stub for setup_topology */ void setup_topology(struct chain_topology *topology UNNEEDED, struct timers *timers UNNEEDED, u32 min_blockheight UNNEEDED, u32 max_blockheight UNNEEDED)