-
Notifications
You must be signed in to change notification settings - Fork 901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
plugin: Allow plugins to publish and subscribe to custom notifications #4496
plugin: Allow plugins to publish and subscribe to custom notifications #4496
Conversation
71805e1
to
3215d3e
Compare
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.
A plugin might subscribe to a notification topic that is only registered by another plugin later, so push the check to that consistency check phase where we do hook ordering as well.
Changelog-Added: plugin: Plugins may now send custom notifications that other plugins can subscribe to.
They may already have subscribers, and they may crash if presented with a malformed notification.
We want to ensure that plugins register their topics before sending any notification, so we need to remember which plugin registered which topics.
We use it in a couple of places, so let's remember it for easier access.
This should allow us to differentiate the origin of the notification, and further prevent plugins from spoofing native notifications.
We want to have well-behaved notifications that are clearly announced during the initialization, kill plugins that don't behave.
Since plugins will start sending them soon, and they are likely to get it wrong sometimes, be a bit more lenient, warn them in the logs instead and then make sure it doesn't accidentally work anyway.
3215d3e
to
9faa907
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack 9faa907
Minor cleanups I will send as separate PR.
if (plugin->subscriptions == NULL) | ||
return; | ||
|
||
for (size_t i = 0; i < tal_count(plugin->subscriptions); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: tal_count(NULL) == 0, so this loop doesn't need a precursor check.
for (size_t i = 0; i < notifications->size; i++) { | ||
obj = json_get_arr(notifications, i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json_for_each_arr(i, obj, notifications)
does these two lines, BTW (and slightly more efficiently).
static void payment_notify_failure(struct payment *p, const char *error_message) { | ||
struct payment *root = payment_root(p); | ||
struct json_stream *n; | ||
n = plugin_notification_start(p->plugin, "pay_failure"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: genuinely weird indent?
So far plugins could only subscribe to native notifications that originated in
lightningd
and which were limited to a few topics directly built into the daemon. With this PR we enable plugins to announce their intention to publish notifications to custom topics, and for other plugins to subscribe to those topics and receive the notifications.Custom topics are required to be announced as part of the
getmanifest
call, allowing us to verify that subscriptions match the announced topics at startup, and print a warning message should a plugin subscribe to a topic that wasn't announced, and therefore will never receive a notification. Trying to send a notification with an unannounced topic will result in a warning being logged, and the message not being delivered to subscribers.To allow subscribers to identify the sender we wrap the notification payload in an outer object with the sender metadata alongside the payload. So the
sender
sending the first message below, will result in the second message being delivered to all subscribers:is delivered as
Notification subscribers should be lenient in what they accept, given that multiple plugins may publish to the same topic, potentially with different payload structures. This in turn allows for both fanout and fanin communication patterns.
We also instrument the
pay
plugin, reporting a minimalpay_success
orpay_failure
notification, which includes thepayment_hash
, thebolt11
string as well as the failure message for failures. The remaining fields may be added if required or can be looked up by queryinglistpays
.