diff --git a/lightningd/plugin.c b/lightningd/plugin.c index aefa5a8f2..b9a3845f2 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -69,6 +69,9 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES) p->plugins = plugins; p->cmd = tal_strdup(p, path); + for (int i = 0; i < NUM_PLUGIN_FEATURES_TYPE; i++) + p->featurebits[i] = NULL; + p->plugin_state = UNCONFIGURED; p->js_arr = tal_arr(p, struct json_stream *, 0); p->used = 0; @@ -811,12 +814,16 @@ static void plugin_manifest_timeout(struct plugin *plugin) fatal("Can't recover from plugin failure, terminating."); } +/* List of JSON keys matching `plugin_features_type`. */ +static const char *plugin_features_type_names[] = {"node", "init", "invoice"}; + bool plugin_parse_getmanifest_response(const char *buffer, const jsmntok_t *toks, const jsmntok_t *idtok, struct plugin *plugin) { - const jsmntok_t *resulttok, *dynamictok; + const jsmntok_t *resulttok, *dynamictok, *featurestok, *tok; + u8 *featurebits; resulttok = json_get_member(buffer, toks, "result"); if (!resulttok || resulttok->type != JSMN_OBJECT) @@ -828,6 +835,31 @@ bool plugin_parse_getmanifest_response(const char *buffer, json_tok_full_len(dynamictok), json_tok_full(buffer, dynamictok)); + featurestok = json_get_member(buffer, resulttok, "featurebits"); + if (featurestok) { + for (int i = 0; i < NUM_PLUGIN_FEATURES_TYPE; i++) { + tok = json_get_member(buffer, featurestok, + plugin_features_type_names[i]); + + if (!tok) + continue; + + featurebits = + json_tok_bin_from_hex(plugin, buffer, tok); + + if (featurebits) { + plugin->featurebits[i] = featurebits; + } else { + plugin_kill( + plugin, + "Featurebits returned by plugin is not a " + "valid hexadecimal string: %.*s", + tok->end - tok->start, buffer + tok->start); + return true; + } + } + } + if (!plugin_opts_add(plugin, buffer, resulttok) || !plugin_rpcmethods_add(plugin, buffer, resulttok) || !plugin_subscriptions_add(plugin, buffer, resulttok) || diff --git a/lightningd/plugin.h b/lightningd/plugin.h index 037b4593d..da26c7d3e 100644 --- a/lightningd/plugin.h +++ b/lightningd/plugin.h @@ -26,6 +26,22 @@ enum plugin_state { CONFIGURED }; +/** + * A plugin may register any number of featurebits that should be added to + * various messages as part of their manifest. The following enum enumerates + * the possible locations the featurebits can be added to, and are used as + * indices into the array of featurebits in the plugin struct itself. + * + * If you edit this make sure that there is a matching entry in the + * `plugin_features_type_names[]` array in plugin.c. + */ +enum plugin_features_type { + PLUGIN_FEATURES_NODE, + PLUGIN_FEATURES_INIT, + PLUGIN_FEATURES_INVOICE, +}; +#define NUM_PLUGIN_FEATURES_TYPE (PLUGIN_FEATURES_INVOICE+1) + /** * A plugin, exposed as a stub so we can pass it as an argument. */ @@ -66,6 +82,11 @@ struct plugin { /* An array of subscribed topics */ char **subscriptions; + + /* Featurebits for various locations that the plugin + * registered. Indices correspond to the `plugin_features_type` + * enum. */ + u8 *featurebits[NUM_PLUGIN_FEATURES_TYPE]; }; /**