plugin: Add a list of notification topics registered by plugin

We will eventually start emitting and dispatching custom notifications
from plugins just like we dispatch internal notifications. In order to
get reasonable error messages we need to make sure that the topics
plugins are asking for were correctly registered. When doing this we
don't really care about whether the plugin that registered the
notification is still alive or not (it might have died, but
subscribers should stay up and running), so we keep a list of all
topics attached to the `struct plugins` which gathers global plugin
information.
This commit is contained in:
Christian Decker
2021-04-27 15:15:09 +02:00
committed by Rusty Russell
parent 29155c2fe8
commit 083b41f090
7 changed files with 80 additions and 9 deletions

View File

@@ -76,6 +76,7 @@ struct plugins *plugins_new(const tal_t *ctx, struct log_book *log_book,
p->startup = true;
p->json_cmds = tal_arr(p, struct command *, 0);
p->blacklist = tal_arr(p, const char *, 0);
p->notification_topics = tal_arr(p, const char *, 0);
p->shutdown = false;
p->plugin_idx = 0;
#if DEVELOPER
@@ -103,6 +104,25 @@ void plugins_free(struct plugins *plugins)
tal_free(plugins);
}
/* Check that all the plugin's subscriptions are actually for known
* notification topics. Emit a warning if that's not the case, but
* don't kill the plugin. */
static void plugin_check_subscriptions(struct plugins *plugins,
struct plugin *plugin)
{
if (plugin->subscriptions == NULL)
return;
for (size_t i = 0; i < tal_count(plugin->subscriptions); i++) {
const char *topic = plugin->subscriptions[i];
if (!notifications_have_topic(plugins, topic))
log_unusual(
plugin->log,
"topic '%s' is not a known notification topic",
topic);
}
}
/* Once they've all replied with their manifests, we can order them. */
static void check_plugins_manifests(struct plugins *plugins)
{
@@ -1136,14 +1156,12 @@ static const char *plugin_subscriptions_add(struct plugin *plugin,
json_tok_full_len(s),
json_tok_full(buffer, s));
}
/* We add all subscriptions while parsing the
* manifest, without checking that they exist, since
* later plugins may also emit notifications of custom
* types that we don't know about yet. */
topic = json_strdup(plugin, plugin->buffer, s);
if (!notifications_have_topic(topic)) {
return tal_fmt(
plugin,
"topic '%s' is not a known notification topic", topic);
}
tal_arr_expand(&plugin->subscriptions, topic);
}
return NULL;
@@ -1338,6 +1356,8 @@ static const char *plugin_parse_getmanifest_response(const char *buffer,
if (!err)
err = plugin_add_params(plugin);
plugin_check_subscriptions(plugin->plugins, plugin);
plugin->plugin_state = NEEDS_INIT;
return err;
}