From fcbd11f0c5edd09a278f2bbced05595188d40b7f Mon Sep 17 00:00:00 2001 From: darosior Date: Thu, 5 Dec 2019 11:28:32 +0100 Subject: [PATCH] plugins/libplugin: hook support Changelog-Added: plugins: libplugin now supports writing plugins which register to hooks --- plugins/autoclean.c | 2 +- plugins/fundchannel.c | 3 ++- plugins/libplugin.c | 31 ++++++++++++++++++++++++++----- plugins/libplugin.h | 10 ++++++++++ plugins/pay.c | 3 ++- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/plugins/autoclean.c b/plugins/autoclean.c index 070d2be25..d51eaa3e9 100644 --- a/plugins/autoclean.c +++ b/plugins/autoclean.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) { setup_locale(); plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), - NULL, 0, + NULL, 0, NULL, 0, plugin_option("autocleaninvoice-cycle", "string", "Perform cleanup of expired invoices every" diff --git a/plugins/fundchannel.c b/plugins/fundchannel.c index 32b7c885d..539b59ead 100644 --- a/plugins/fundchannel.c +++ b/plugins/fundchannel.c @@ -512,5 +512,6 @@ static const struct plugin_command commands[] = { { int main(int argc, char *argv[]) { setup_locale(); - plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), NULL, 0, NULL); + plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), + NULL, 0, NULL, 0, NULL); } diff --git a/plugins/libplugin.c b/plugins/libplugin.c index c1ed0bb76..51bcda64a 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -488,6 +488,8 @@ handle_getmanifest(struct command *getmanifest_cmd, size_t num_commands, const struct plugin_notification *notif_subs, size_t num_notif_subs, + const struct plugin_hook *hook_subs, + size_t num_hook_subs, const struct plugin_option *opts, const enum plugin_restartability restartability) { @@ -523,6 +525,11 @@ handle_getmanifest(struct command *getmanifest_cmd, json_out_addstr(params, NULL, notif_subs[i].name); json_out_end(params, ']'); + json_out_start(params, "hooks", '['); + for (size_t i = 0; i < num_hook_subs; i++) + json_out_addstr(params, NULL, hook_subs[i].name); + json_out_end(params, ']'); + json_out_addstr(params, "dynamic", restartability == PLUGIN_RESTARTABLE ? "true" : "false"); json_out_end(params, '}'); json_out_finished(params); @@ -625,7 +632,9 @@ static void handle_new_command(const tal_t *ctx, const struct plugin_command *commands, size_t num_commands, const struct plugin_notification *notif_subs, - size_t num_notif_subs) + size_t num_notif_subs, + const struct plugin_hook *hook_subs, + size_t num_hook_subs) { struct command *cmd; const jsmntok_t *params; @@ -643,6 +652,14 @@ static void handle_new_command(const tal_t *ctx, } return; } + for (size_t i = 0; i < num_hook_subs; i++) { + if (streq(cmd->methodname, hook_subs[i].name)) { + hook_subs[i].handle(cmd, membuf_elems(&request_conn->mb), + params); + membuf_consume(&request_conn->mb, reqlen); + return; + } + } for (size_t i = 0; i < num_commands; i++) { if (streq(cmd->methodname, commands[i].name)) { commands[i].handle(cmd, membuf_elems(&request_conn->mb), @@ -748,6 +765,8 @@ void plugin_main(char *argv[], size_t num_commands, const struct plugin_notification *notif_subs, size_t num_notif_subs, + const struct plugin_hook *hook_subs, + size_t num_hook_subs, ...) { struct plugin_conn request_conn; @@ -779,7 +798,7 @@ void plugin_main(char *argv[], membuf_tal_realloc); uintmap_init(&out_reqs); - va_start(ap, num_notif_subs); + va_start(ap, num_hook_subs); while ((optname = va_arg(ap, const char *)) != NULL) { struct plugin_option o; o.name = optname; @@ -798,7 +817,7 @@ void plugin_main(char *argv[], membuf_consume(&request_conn.mb, reqlen); handle_getmanifest(cmd, commands, num_commands, notif_subs, num_notif_subs, - opts, restartability); + hook_subs, num_hook_subs, opts, restartability); cmd = read_json_request(tmpctx, &request_conn, &rpc_conn, ¶ms, &reqlen); @@ -825,7 +844,8 @@ void plugin_main(char *argv[], /* If we already have some input, process now. */ if (membuf_num_elems(&request_conn.mb) != 0) { handle_new_command(ctx, &request_conn, &rpc_conn, - commands, num_commands, notif_subs, num_notif_subs); + commands, num_commands, notif_subs, num_notif_subs, + hook_subs, num_hook_subs); continue; } if (membuf_num_elems(&rpc_conn.mb) != 0) { @@ -852,7 +872,8 @@ void plugin_main(char *argv[], if (fds[0].revents & POLLIN) handle_new_command(ctx, &request_conn, &rpc_conn, - commands, num_commands, notif_subs, num_notif_subs); + commands, num_commands, notif_subs, num_notif_subs, + hook_subs, num_hook_subs); if (fds[1].revents & POLLIN) handle_rpc_reply(&rpc_conn); } diff --git a/plugins/libplugin.h b/plugins/libplugin.h index bdb536191..62b7c630d 100644 --- a/plugins/libplugin.h +++ b/plugins/libplugin.h @@ -50,6 +50,14 @@ struct plugin_notification { const jsmntok_t *params); }; +/* Create an array of these, one for each hook you subscribe to. */ +struct plugin_hook { + const char *name; + struct command_result *(*handle)(struct command *cmd, + const char *buf, + const jsmntok_t *params); +}; + /* Helper to create a zero or single-value JSON object; if @str is NULL, * object is empty. */ struct json_out *json_out_obj(const tal_t *ctx, @@ -173,5 +181,7 @@ void NORETURN LAST_ARG_NULL plugin_main(char *argv[], size_t num_commands, const struct plugin_notification *notif_subs, size_t num_notif_subs, + const struct plugin_hook *hook_subs, + size_t num_hook_subs, ...); #endif /* LIGHTNING_PLUGINS_LIBPLUGIN_H */ diff --git a/plugins/pay.c b/plugins/pay.c index 01e5c34d4..3dfc0a4dc 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1395,5 +1395,6 @@ static const struct plugin_command commands[] = { { int main(int argc, char *argv[]) { setup_locale(); - plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), NULL, 0, NULL); + plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), + NULL, 0, NULL, 0, NULL); }