Skip to content

Commit

Permalink
plugin: Send jsonrpc_request when calling hooks and dispatch results
Browse files Browse the repository at this point in the history
This ties all the things together, using the serializer to transform
the payload into a valid `jsonrpc_request`, sending it to the plugin,
and then using the deserializer on the way back before calling the
hook callback with the appropriate information.

Notice that the serializer and deserializer is skipped if we don't
have a plugin that registered for this hook.

Signed-off-by: Christian Decker <[email protected]>
  • Loading branch information
cdecker authored and rustyrussell committed Jan 17, 2019
1 parent a2fa078 commit a281f4b
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions lightningd/plugin_hook.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#include <common/memleak.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/plugin_hook.h>

/* Struct containing all the information needed to deserialize and
* dispatch an eventual plugin_hook response. */
struct plugin_hook_request {
const struct plugin_hook *hook;
void *cb_arg;
};

static struct plugin_hook *plugin_hook_by_name(const char *name)
{
static struct plugin_hook **hooks = NULL;
Expand Down Expand Up @@ -30,7 +39,47 @@ bool plugin_hook_register(struct plugin *plugin, const char *method)
/* FIXME(cdecker): Remove dummy hook, once we have a real one */
REGISTER_PLUGIN_HOOK(hello, NULL, void *, NULL, void *, NULL, void *);

/**
* Callback to be passed to the jsonrpc_request.
*
* Unbundles the arguments, deserializes the response and dispatches
* it to the hook callback.
*/
static void plugin_hook_callback(const char *buffer, const jsmntok_t *toks,
const jsmntok_t *idtok,
struct plugin_hook_request *r)
{
const jsmntok_t *resulttok = json_get_member(buffer, toks, "result");
void *response = r->hook->deserialize_response(r, buffer, resulttok);
r->hook->response_cb(r->cb_arg, response);
tal_free(r);
}

void plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
void *payload, void *cb_arg)
{
struct jsonrpc_request *req;
struct plugin_hook_request *ph_req;
if (hook->plugin) {
/* If we have a plugin that has registered for this
* hook, serialize and call it */
/* FIXME: technically this is a leak, but we don't
* currently have a list to store these. We might want
* to eventually to inspect in-flight requests. */
ph_req = notleak(tal(hook->plugin, struct plugin_hook_request));
req = jsonrpc_request_start(NULL, hook->name,
plugin_hook_callback, ph_req);
ph_req->hook = hook;
ph_req->cb_arg = cb_arg;
hook->serialize_payload(payload, req->stream);
jsonrpc_request_end(req);
plugin_request_send(hook->plugin, req);
} else {
/* If no plugin has registered for this hook, just
* call the callback with a NULL result. Saves us the
* roundtrip to the serializer and deserializer. If we
* were expecting a default response it should have
* been part of the `cb_arg`. */
hook->response_cb(cb_arg, NULL);
}
}

0 comments on commit a281f4b

Please sign in to comment.