Skip to content

Commit

Permalink
plugins: libplugin support for dynamic config options.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jun 20, 2023
1 parent aa5c7e7 commit a65f2ef
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 18 deletions.
70 changes: 57 additions & 13 deletions plugins/libplugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ handle_getmanifest(struct command *getmanifest_cmd,
json_add_string(params, "type", p->opts[i].type);
json_add_string(params, "description", p->opts[i].description);
json_add_bool(params, "deprecated", p->opts[i].deprecated);
json_add_bool(params, "dynamic", p->opts[i].dynamic);
json_object_end(params);
}
json_array_end(params);
Expand Down Expand Up @@ -1136,6 +1137,15 @@ static struct feature_set *json_to_feature_set(struct plugin *plugin,
return fset;
}

static struct plugin_option *find_opt(struct plugin *plugin, const char *name)
{
for (size_t i = 0; i < tal_count(plugin->opts); i++) {
if (streq(plugin->opts[i].name, name))
return &plugin->opts[i];
}
return NULL;
}

static struct command_result *handle_init(struct command *cmd,
const char *buf,
const jsmntok_t *params)
Expand Down Expand Up @@ -1197,19 +1207,17 @@ static struct command_result *handle_init(struct command *cmd,

opttok = json_get_member(buf, params, "options");
json_for_each_obj(i, t, opttok) {
char *opt = json_strdup(NULL, buf, t);
for (size_t optnum = 0; optnum < tal_count(p->opts); optnum++) {
char *problem;
if (!streq(p->opts[optnum].name, opt))
continue;
problem = p->opts[optnum].handle(p, json_strdup(opt, buf, t+1),
p->opts[optnum].arg);
if (problem)
plugin_err(p, "option '%s': %s",
p->opts[optnum].name, problem);
break;
}
tal_free(opt);
const char *name, *problem;
struct plugin_option *popt;

name = json_strdup(tmpctx, buf, t);
popt = find_opt(p, name);
if (!popt)
plugin_err(p, "lightningd specified unknown option '%s'?", name);

problem = popt->handle(p, json_strdup(tmpctx, buf, t+1), popt->arg);
if (problem)
plugin_err(p, "option '%s': %s", popt->name, problem);
}

if (p->init) {
Expand Down Expand Up @@ -1638,6 +1646,41 @@ static void ld_command_handle(struct plugin *plugin,
}
}

/* Dynamic parameters */
if (streq(cmd->methodname, "setconfig")) {
const jsmntok_t *valtok;
const char *config, *val, *problem;
struct plugin_option *popt;
struct command_result *ret;
config = json_strdup(tmpctx, plugin->buffer,
json_get_member(plugin->buffer, paramstok, "config"));
popt = find_opt(plugin, config);
if (!popt) {
plugin_err(plugin,
"lightningd setconfig unknown option '%s'?",
config);
}
if (!popt->dynamic) {
plugin_err(plugin,
"lightningd setconfig non-dynamic option '%s'?",
config);
}
valtok = json_get_member(plugin->buffer, paramstok, "val");
if (valtok)
val = json_strdup(tmpctx, plugin->buffer, valtok);
else
val = "true";

problem = popt->handle(plugin, val, popt->arg);
if (problem)
ret = command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s", problem);
else
ret = command_finished(cmd, jsonrpc_stream_success(cmd));
assert(ret == &complete);
return;
}

plugin_err(plugin, "Unknown command '%s'", cmd->methodname);
}

Expand Down Expand Up @@ -1842,6 +1885,7 @@ static struct plugin *new_plugin(const tal_t *ctx,
o.handle = va_arg(ap, char *(*)(struct plugin *, const char *str, void *arg));
o.arg = va_arg(ap, void *);
o.deprecated = va_arg(ap, int); /* bool gets promoted! */
o.dynamic = va_arg(ap, int); /* bool gets promoted! */
tal_arr_expand(&p->opts, o);
}

Expand Down
16 changes: 11 additions & 5 deletions plugins/libplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ struct plugin_option {
void *arg;
/* If true, this options *disabled* if allow-deprecated-apis = false */
bool deprecated;
/* If true, allow setting after plugin has initialized */
bool dynamic;
};

/* Create an array of these, one for each notification you subscribe to. */
Expand Down Expand Up @@ -401,7 +403,7 @@ static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin,
}

/* Macro to define arguments */
#define plugin_option_(name, type, description, set, arg, deprecated) \
#define plugin_option_(name, type, description, set, arg, deprecated, dynamic) \
(name), \
(type), \
(description), \
Expand All @@ -410,13 +412,17 @@ static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin,
struct plugin *, \
const char *)), \
(arg), \
(deprecated)
(deprecated), \
(dynamic)

#define plugin_option(name, type, description, set, arg) \
plugin_option_((name), (type), (description), (set), (arg), false)
plugin_option_((name), (type), (description), (set), (arg), false, false)

#define plugin_option_deprecated(name, type, description, set, arg) \
plugin_option_((name), (type), (description), (set), (arg), true)
#define plugin_option_dynamic(name, type, description, set, arg) \
plugin_option_((name), (type), (description), (set), (arg), false, true)

#define plugin_option_deprecated(name, type, description, set, arg) \
plugin_option_((name), (type), (description), (set), (arg), true, false)

/* Standard helpers */
char *u64_option(struct plugin *plugin, const char *arg, u64 *i);
Expand Down

0 comments on commit a65f2ef

Please sign in to comment.