From a9557d5194f8aa6b41c2c35a6e17d47bf9d87e37 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 13 Sep 2022 06:49:11 +0930 Subject: [PATCH] lightningd: derive JSONRPC ids from incoming id (append /cln:#NNN). Usually the calls are spontanous, so it's just "cln:#NNN", but json_invoice() calls listincoming, and json_checkmessage calls listnodes, so those become "cli:invoice-/cln:listincoming#NNN". Signed-off-by: Rusty Russell --- lightningd/bitcoind.c | 15 +++++++++------ lightningd/invoice.c | 1 + lightningd/jsonrpc.c | 9 +++++++-- lightningd/jsonrpc.h | 15 ++++++++++----- lightningd/plugin.c | 8 +++++--- lightningd/plugin_hook.c | 6 ++++-- lightningd/signmessage.c | 1 + lightningd/test/run-invoice-select-inchan.c | 3 ++- tests/test_invoices.py | 2 +- 9 files changed, 40 insertions(+), 20 deletions(-) diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index d19968e3a..93eef2382 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -49,7 +49,7 @@ static void config_plugin(struct plugin *plugin) struct jsonrpc_request *req; void *ret; - req = jsonrpc_request_start(plugin, "init", plugin->log, + req = jsonrpc_request_start(plugin, "init", NULL, plugin->log, NULL, plugin_config_cb, plugin); plugin_populate_init_request(plugin, req); jsonrpc_request_end(req); @@ -237,7 +237,8 @@ void bitcoind_estimate_fees_(struct bitcoind *bitcoind, call->cb = cb; call->arg = arg; - req = jsonrpc_request_start(bitcoind, "estimatefees", bitcoind->log, + req = jsonrpc_request_start(bitcoind, "estimatefees", NULL, + bitcoind->log, NULL, estimatefees_callback, call); jsonrpc_request_end(req); plugin_request_send(strmap_get(&bitcoind->pluginsmap, @@ -312,7 +313,8 @@ void bitcoind_sendrawtx_ahf_(struct bitcoind *bitcoind, call->cb_arg = cb_arg; log_debug(bitcoind->log, "sendrawtransaction: %s", hextx); - req = jsonrpc_request_start(bitcoind, "sendrawtransaction", + /* FIXME: pass id_prefix from caller! */ + req = jsonrpc_request_start(bitcoind, "sendrawtransaction", NULL, bitcoind->log, NULL, sendrawtx_callback, call); @@ -408,7 +410,7 @@ void bitcoind_getrawblockbyheight_(struct bitcoind *bitcoind, call->cb = cb; call->cb_arg = cb_arg; - req = jsonrpc_request_start(bitcoind, "getrawblockbyheight", + req = jsonrpc_request_start(bitcoind, "getrawblockbyheight", NULL, bitcoind->log, NULL, getrawblockbyheight_callback, call); @@ -489,7 +491,8 @@ void bitcoind_getchaininfo_(struct bitcoind *bitcoind, call->cb_arg = cb_arg; call->first_call = first_call; - req = jsonrpc_request_start(bitcoind, "getchaininfo", bitcoind->log, + req = jsonrpc_request_start(bitcoind, "getchaininfo", NULL, + bitcoind->log, NULL, getchaininfo_callback, call); jsonrpc_request_end(req); bitcoin_plugin_send(bitcoind, req); @@ -561,7 +564,7 @@ void bitcoind_getutxout_(struct bitcoind *bitcoind, call->cb = cb; call->cb_arg = cb_arg; - req = jsonrpc_request_start(bitcoind, "getutxout", bitcoind->log, + req = jsonrpc_request_start(bitcoind, "getutxout", NULL, bitcoind->log, NULL, getutxout_callback, call); json_add_txid(req->stream, "txid", &outpoint->txid); json_add_num(req->stream, "vout", outpoint->n); diff --git a/lightningd/invoice.c b/lightningd/invoice.c index ee3d4a0f0..c8a9d817c 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -1250,6 +1250,7 @@ static struct command_result *json_invoice(struct command *cmd, info->b11->fallbacks = tal_steal(info->b11, fallback_scripts); req = jsonrpc_request_start(info, "listincoming", + cmd->id, cmd->ld->log, NULL, listincoming_done, info); diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 93aec76f3..ec601e082 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -1314,7 +1314,8 @@ void jsonrpc_notification_end(struct jsonrpc_notification *n) } struct jsonrpc_request *jsonrpc_request_start_( - const tal_t *ctx, const char *method, struct log *log, + const tal_t *ctx, const char *method, + const char *id_prefix, struct log *log, bool add_header, void (*notify_cb)(const char *buffer, const jsmntok_t *methodtok, @@ -1327,7 +1328,11 @@ struct jsonrpc_request *jsonrpc_request_start_( { struct jsonrpc_request *r = tal(ctx, struct jsonrpc_request); static u64 next_request_id = 0; - r->id = tal_fmt(r, "cln:%s#%"PRIu64, method, next_request_id); + if (id_prefix) + r->id = tal_fmt(r, "%s/cln:%s#%"PRIu64, + id_prefix, method, next_request_id); + else + r->id = tal_fmt(r, "cln:%s#%"PRIu64, method, next_request_id); next_request_id++; r->notify_cb = notify_cb; r->response_cb = response_cb; diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index 92b4e7722..2b42a24e6 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -217,9 +217,13 @@ struct jsonrpc_notification *jsonrpc_notification_start(const tal_t *ctx, const */ void jsonrpc_notification_end(struct jsonrpc_notification *n); -#define jsonrpc_request_start(ctx, method, log, notify_cb, response_cb, response_cb_arg) \ +/** + * start a JSONRPC request; id_prefix is non-NULL if this was triggered by + * another JSONRPC request. + */ +#define jsonrpc_request_start(ctx, method, id_prefix, log, notify_cb, response_cb, response_cb_arg) \ jsonrpc_request_start_( \ - (ctx), (method), (log), true, \ + (ctx), (method), (id_prefix), (log), true, \ typesafe_cb_preargs(void, void *, (notify_cb), (response_cb_arg), \ const char *buffer, \ const jsmntok_t *idtok, \ @@ -231,9 +235,9 @@ void jsonrpc_notification_end(struct jsonrpc_notification *n); const jsmntok_t *idtok), \ (response_cb_arg)) -#define jsonrpc_request_start_raw(ctx, method, log, notify_cb, response_cb, response_cb_arg) \ +#define jsonrpc_request_start_raw(ctx, method, id_prefix, log, notify_cb, response_cb, response_cb_arg) \ jsonrpc_request_start_( \ - (ctx), (method), (log), false, \ + (ctx), (method), (id_prefix), (log), false, \ typesafe_cb_preargs(void, void *, (notify_cb), (response_cb_arg), \ const char *buffer, \ const jsmntok_t *idtok, \ @@ -246,7 +250,8 @@ void jsonrpc_notification_end(struct jsonrpc_notification *n); (response_cb_arg)) struct jsonrpc_request *jsonrpc_request_start_( - const tal_t *ctx, const char *method, struct log *log, bool add_header, + const tal_t *ctx, const char *method, + const char *id_prefix, struct log *log, bool add_header, void (*notify_cb)(const char *buffer, const jsmntok_t *idtok, const jsmntok_t *methodtok, diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 20c0b1c2f..a158720ba 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -1142,7 +1142,8 @@ static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd, call = tal(plugin, struct plugin_rpccall); call->cmd = cmd; - req = jsonrpc_request_start_raw(plugin, cmd->json_cmd->name, plugin->log, + req = jsonrpc_request_start_raw(plugin, cmd->json_cmd->name, cmd->id, + plugin->log, plugin_notify_cb, plugin_rpcmethod_cb, call); call->request = req; @@ -1729,7 +1730,8 @@ const char *plugin_send_getmanifest(struct plugin *p) * write-only on p->stdin */ p->stdout_conn = io_new_conn(p, stdoutfd, plugin_stdout_conn_init, p); p->stdin_conn = io_new_conn(p, stdinfd, plugin_stdin_conn_init, p); - req = jsonrpc_request_start(p, "getmanifest", p->log, + /* FIXME: id_prefix from caller! */ + req = jsonrpc_request_start(p, "getmanifest", NULL, p->log, NULL, plugin_manifest_cb, p); json_add_bool(req->stream, "allow-deprecated-apis", deprecated_apis); jsonrpc_request_end(req); @@ -1910,7 +1912,7 @@ plugin_config(struct plugin *plugin) struct jsonrpc_request *req; plugin_set_timeout(plugin); - req = jsonrpc_request_start(plugin, "init", plugin->log, + req = jsonrpc_request_start(plugin, "init", NULL, plugin->log, NULL, plugin_config_cb, plugin); plugin_populate_init_request(plugin, req); jsonrpc_request_end(req); diff --git a/lightningd/plugin_hook.c b/lightningd/plugin_hook.c index b8d7322f4..70b2f2f85 100644 --- a/lightningd/plugin_hook.c +++ b/lightningd/plugin_hook.c @@ -232,7 +232,8 @@ 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); - req = jsonrpc_request_start(NULL, hook->name, + /* FIXME: id_prefix from caller! */ + req = jsonrpc_request_start(NULL, hook->name, NULL, plugin_get_log(ph_req->plugin), NULL, plugin_hook_callback, ph_req); @@ -371,8 +372,9 @@ void plugin_hook_db_sync(struct db *db) dwh_req->ph_req = ph_req; dwh_req->num_hooks = &num_hooks; + /* FIXME: id_prefix from caller? */ /* FIXME: do IO logging for this! */ - req = jsonrpc_request_start(NULL, hook->name, NULL, NULL, + req = jsonrpc_request_start(NULL, hook->name, NULL, NULL, NULL, db_hook_response, dwh_req); diff --git a/lightningd/signmessage.c b/lightningd/signmessage.c index b3ecab5a1..9d0197fac 100644 --- a/lightningd/signmessage.c +++ b/lightningd/signmessage.c @@ -212,6 +212,7 @@ static struct command_result *json_checkmessage(struct command *cmd, node_id_from_pubkey(&can->id, &reckey); can->cmd = cmd; req = jsonrpc_request_start(cmd, "listnodes", + cmd->id, cmd->ld->log, NULL, listnodes_done, can); diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 4550e0e0f..d8cec6186 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -491,7 +491,8 @@ void jsonrpc_request_end(struct jsonrpc_request *request UNNEEDED) { fprintf(stderr, "jsonrpc_request_end called!\n"); abort(); } /* Generated stub for jsonrpc_request_start_ */ struct jsonrpc_request *jsonrpc_request_start_( - const tal_t *ctx UNNEEDED, const char *method UNNEEDED, struct log *log UNNEEDED, bool add_header UNNEEDED, + const tal_t *ctx UNNEEDED, const char *method UNNEEDED, + const char *id_prefix UNNEEDED, struct log *log UNNEEDED, bool add_header UNNEEDED, void (*notify_cb)(const char *buffer UNNEEDED, const jsmntok_t *idtok UNNEEDED, const jsmntok_t *methodtok UNNEEDED, diff --git a/tests/test_invoices.py b/tests/test_invoices.py index 743caf9bd..bb9543676 100644 --- a/tests/test_invoices.py +++ b/tests/test_invoices.py @@ -18,7 +18,7 @@ def test_invoice(node_factory, chainparams): inv = l1.rpc.invoice(123000, 'label', 'description', 3700, [addr1, addr2]) # Side note: invoice calls out to listincoming, so check JSON id is as expected - l1.daemon.wait_for_log(": OUT:id=cln:listincoming#[0-9]*") + l1.daemon.wait_for_log(": OUT:id=1/cln:listincoming#[0-9]*") after = int(time.time()) b11 = l1.rpc.decodepay(inv['bolt11'])