plugin: wire JSON id for commands which caused hooks to fire.

Most obvious one is the "connect" hook.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-09-13 06:49:12 +09:30
parent eceb9f4328
commit e8ef42b741
15 changed files with 64 additions and 23 deletions

View File

@ -402,6 +402,15 @@ static void handle_connect_failed(struct lightningd *ld, const u8 *msg)
connect_failed(ld, &id, errcode, errmsg, addrhint);
}
const char *connect_any_cmd_id(const tal_t *ctx,
struct lightningd *ld, const struct peer *peer)
{
struct connect *c = find_connect(ld, &peer->id);
if (c)
return tal_strdup(ctx, c->cmd->id);
return NULL;
}
void connect_succeeded(struct lightningd *ld, const struct peer *peer,
bool incoming,
const struct wireaddr_internal *addr)
@ -469,7 +478,7 @@ static void handle_custommsg_in(struct lightningd *ld, const u8 *msg)
return;
}
plugin_hook_call_custommsg(ld, p);
plugin_hook_call_custommsg(ld, NULL, p);
}
static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fds)

View File

@ -28,4 +28,8 @@ void connect_failed_disconnect(struct lightningd *ld,
const struct node_id *id,
const struct wireaddr_internal *addr);
/* Get the id of any connect cmd which applies, to feed to hooks */
const char *connect_any_cmd_id(const tal_t *ctx,
struct lightningd *ld, const struct peer *peer);
#endif /* LIGHTNING_LIGHTNINGD_CONNECT_CONTROL_H */

View File

@ -1856,7 +1856,7 @@ static void rbf_got_offer(struct subd *dualopend, const u8 *msg)
payload->channel_max = AMOUNT_SAT(UINT_MAX);
tal_add_destructor2(dualopend, rbf_channel_remove_dualopend, payload);
plugin_hook_call_rbf_channel(dualopend->ld, payload);
plugin_hook_call_rbf_channel(dualopend->ld, NULL, payload);
}
static void accepter_got_offer(struct subd *dualopend,
@ -1917,7 +1917,7 @@ static void accepter_got_offer(struct subd *dualopend,
payload->channel_max = AMOUNT_SAT(UINT64_MAX);
tal_add_destructor2(dualopend, openchannel2_remove_dualopend, payload);
plugin_hook_call_openchannel2(dualopend->ld, payload);
plugin_hook_call_openchannel2(dualopend->ld, NULL, payload);
}
static void handle_peer_tx_sigs_msg(struct subd *dualopend,
@ -2859,7 +2859,7 @@ static void handle_psbt_changed(struct subd *dualopend,
payload);
payload->psbt = tal_steal(payload, psbt);
payload->channel = channel;
plugin_hook_call_openchannel2_changed(dualopend->ld, payload);
plugin_hook_call_openchannel2_changed(dualopend->ld, NULL, payload);
return;
}
abort();
@ -3042,7 +3042,7 @@ static void handle_commit_received(struct subd *dualopend,
payload->channel->openchannel_signed_cmd = NULL;
/* We call out to hook who will
* provide signatures for us! */
plugin_hook_call_openchannel2_sign(ld, payload);
plugin_hook_call_openchannel2_sign(ld, NULL, payload);
return;
}

View File

@ -478,7 +478,7 @@ void invoice_try_pay(struct lightningd *ld,
payload->set = set;
tal_add_destructor2(set, invoice_payload_remove_set, payload);
plugin_hook_call_invoice_payment(ld, payload);
plugin_hook_call_invoice_payment(ld, NULL, payload);
}
static bool hsm_sign_b11(const u5 *u5bytes,

View File

@ -940,7 +940,7 @@ parse_request(struct json_connection *jcon, const jsmntok_t tok[])
rpc_hook->custom_buffer = NULL;
db_begin_transaction(jcon->ld->wallet->db);
completed = plugin_hook_call_rpc_command(jcon->ld, rpc_hook);
completed = plugin_hook_call_rpc_command(jcon->ld, c->id, rpc_hook);
db_commit_transaction(jcon->ld->wallet->db);
/* If it's deferred, mark it (otherwise, it's completed) */

View File

@ -209,9 +209,9 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
/* We'll free this on return */
tal_steal(ld, payload);
if (payload->our_alias)
plugin_hook_call_onion_message_ourpath(ld, payload);
plugin_hook_call_onion_message_ourpath(ld, NULL, payload);
else
plugin_hook_call_onion_message_blinded(ld, payload);
plugin_hook_call_onion_message_blinded(ld, NULL, payload);
}
struct onion_hop {

View File

@ -832,7 +832,7 @@ static void opening_got_offer(struct subd *openingd,
}
tal_add_destructor2(openingd, openchannel_payload_remove_openingd, payload);
plugin_hook_call_openchannel(openingd->ld, payload);
plugin_hook_call_openchannel(openingd->ld, NULL, payload);
}
static unsigned int openingd_msg(struct subd *openingd,

View File

@ -1363,6 +1363,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
struct peer *peer;
struct peer_connected_hook_payload *hook_payload;
u64 connectd_counter;
const char *cmd_id;
hook_payload = tal(NULL, struct peer_connected_hook_payload);
hook_payload->ld = ld;
@ -1411,6 +1412,9 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
tal_steal(peer, hook_payload);
hook_payload->peer = peer;
/* If there's a connect command, use its id as basis for hook id */
cmd_id = connect_any_cmd_id(tmpctx, ld, peer);
/* Log and update remote_addr for Nat/IP discovery. */
if (hook_payload->remote_addr) {
log_peer_debug(ld->log, &id, "Peer says it sees our address as: %s",
@ -1423,7 +1427,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
update_remote_addr(ld, hook_payload->remote_addr, id);
}
plugin_hook_call_peer_connected(ld, hook_payload);
plugin_hook_call_peer_connected(ld, cmd_id, hook_payload);
}
/* connectd tells us a peer has a message and we've not already attached

View File

@ -1300,7 +1300,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
#endif
hook_payload->next_blinding = NULL;
plugin_hook_call_htlc_accepted(ld, hook_payload);
plugin_hook_call_htlc_accepted(ld, NULL, hook_payload);
/* Falling through here is ok, after all the HTLC locked */
return true;
@ -2399,7 +2399,7 @@ void peer_got_revoke(struct channel *channel, const u8 *msg)
payload->channel_dbid = channel->dbid;
payload->commitnum = pbase->commitment_num;
payload->channel_id = channel->cid;
plugin_hook_call_commitment_revocation(ld, payload);
plugin_hook_call_commitment_revocation(ld, NULL, payload);
}

View File

@ -1,5 +1,6 @@
#include "config.h"
#include <ccan/io/io.h>
#include <ccan/tal/str/str.h>
#include <common/json_parse.h>
#include <common/memleak.h>
#include <db/exec.h>
@ -11,6 +12,7 @@
struct plugin_hook_request {
struct list_head call_chain;
struct plugin *plugin;
const char *cmd_id;
const struct plugin_hook *hook;
void *cb_arg;
struct db *db;
@ -232,8 +234,7 @@ static void plugin_hook_call_next(struct plugin_hook_request *ph_req)
log_debug(ph_req->ld->log, "Calling %s hook of plugin %s",
ph_req->hook->name, ph_req->plugin->shortname);
/* FIXME: id_prefix from caller! */
req = jsonrpc_request_start(NULL, hook->name, NULL,
req = jsonrpc_request_start(NULL, hook->name, ph_req->cmd_id,
plugin_get_log(ph_req->plugin),
NULL,
plugin_hook_callback, ph_req);
@ -244,6 +245,7 @@ static void plugin_hook_call_next(struct plugin_hook_request *ph_req)
}
bool plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
const char *cmd_id TAKES,
tal_t *cb_arg STEALS)
{
struct plugin_hook_request *ph_req;
@ -259,6 +261,10 @@ bool plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
ph_req->cb_arg = tal_steal(ph_req, cb_arg);
ph_req->db = ld->wallet->db;
ph_req->ld = ld;
if (cmd_id)
ph_req->cmd_id = tal_strdup(ph_req, cmd_id);
else
ph_req->cmd_id = NULL;
list_head_init(&ph_req->call_chain);
for (size_t i=0; i<tal_count(hook->hooks); i++) {

View File

@ -59,7 +59,9 @@ AUTODATA_TYPE(hooks, struct plugin_hook);
* Returns true if callback called immediately, otherwise false if it's
* still waiting on a plugin response.
*/
bool plugin_hook_call_(struct lightningd *ld, const struct plugin_hook *hook,
bool plugin_hook_call_(struct lightningd *ld,
const struct plugin_hook *hook,
const char *cmd_id TAKES,
tal_t *cb_arg STEALS);
/* Generic deserialize_cb: returns true iff 'result': 'continue' */
@ -73,9 +75,9 @@ bool plugin_hook_continue(void *arg, const char *buffer, const jsmntok_t *toks);
/* FIXME: Find a way to avoid back-to-back declaration and definition */
#define PLUGIN_HOOK_CALL_DEF(name, cb_arg_type) \
UNNEEDED static inline bool plugin_hook_call_##name( \
struct lightningd *ld, cb_arg_type cb_arg STEALS) \
struct lightningd *ld, const char *cmd_id TAKES, cb_arg_type cb_arg STEALS) \
{ \
return plugin_hook_call_(ld, &name##_hook_gen, cb_arg); \
return plugin_hook_call_(ld, &name##_hook_gen, cmd_id, cb_arg); \
}
/* Typechecked registration of a plugin hook. We check that the

View File

@ -149,6 +149,10 @@ struct command_result *command_success(struct command *cmd UNNEEDED,
struct json_stream *response)
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_any_cmd_id */
const char *connect_any_cmd_id(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED)
{ fprintf(stderr, "connect_any_cmd_id called!\n"); abort(); }
/* Generated stub for connect_failed_disconnect */
void connect_failed_disconnect(struct lightningd *ld UNNEEDED,
const struct node_id *id UNNEEDED,
@ -671,7 +675,9 @@ bool peer_start_openingd(struct peer *peer UNNEEDED,
struct peer_fd *peer_fd UNNEEDED)
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
/* Generated stub for plugin_hook_call_ */
bool plugin_hook_call_(struct lightningd *ld UNNEEDED, const struct plugin_hook *hook UNNEEDED,
bool plugin_hook_call_(struct lightningd *ld UNNEEDED,
const struct plugin_hook *hook UNNEEDED,
const char *cmd_id TAKES UNNEEDED,
tal_t *cb_arg STEALS UNNEEDED)
{ fprintf(stderr, "plugin_hook_call_ called!\n"); abort(); }
/* Generated stub for plugin_request_send */

View File

@ -96,7 +96,9 @@ const char *param_subcommand(struct command *cmd UNNEEDED, const char *buffer UN
const char *name UNNEEDED, ...)
{ fprintf(stderr, "param_subcommand called!\n"); abort(); }
/* Generated stub for plugin_hook_call_ */
bool plugin_hook_call_(struct lightningd *ld UNNEEDED, const struct plugin_hook *hook UNNEEDED,
bool plugin_hook_call_(struct lightningd *ld UNNEEDED,
const struct plugin_hook *hook UNNEEDED,
const char *cmd_id TAKES UNNEEDED,
tal_t *cb_arg STEALS UNNEEDED)
{ fprintf(stderr, "plugin_hook_call_ called!\n"); abort(); }
/* Generated stub for towire_bigsize */

View File

@ -1500,9 +1500,11 @@ def test_libplugin(node_factory):
# But param takes over!
assert l1.rpc.call("helloworld", {"name": "test"}) == {"hello": "test"}
# Test hooks and notifications
l2 = node_factory.get_node()
# Test hooks and notifications (add plugin, so we can test hook id)
l2 = node_factory.get_node(options={"plugin": plugin})
l2.connect(l1)
l2.daemon.wait_for_log(": OUT:id=[0-9]*/cln:peer_connected#[0-9]*")
l1.daemon.wait_for_log("{} peer_connected".format(l2.info["id"]))
l1.daemon.wait_for_log("{} connected".format(l2.info["id"]))

View File

@ -107,6 +107,10 @@ struct command_result *command_success(struct command *cmd UNNEEDED,
struct json_stream *response)
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_any_cmd_id */
const char *connect_any_cmd_id(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED)
{ fprintf(stderr, "connect_any_cmd_id called!\n"); abort(); }
/* Generated stub for connect_failed_disconnect */
void connect_failed_disconnect(struct lightningd *ld UNNEEDED,
const struct node_id *id UNNEEDED,
@ -653,7 +657,9 @@ bool peer_start_openingd(struct peer *peer UNNEEDED,
const char *peer_wire_name(int e UNNEEDED)
{ fprintf(stderr, "peer_wire_name called!\n"); abort(); }
/* Generated stub for plugin_hook_call_ */
bool plugin_hook_call_(struct lightningd *ld UNNEEDED, const struct plugin_hook *hook UNNEEDED,
bool plugin_hook_call_(struct lightningd *ld UNNEEDED,
const struct plugin_hook *hook UNNEEDED,
const char *cmd_id TAKES UNNEEDED,
tal_t *cb_arg STEALS UNNEEDED)
{ fprintf(stderr, "plugin_hook_call_ called!\n"); abort(); }
/* Generated stub for process_onionpacket */