lightningd: simplify injectonionmessage API.

It's undocumented and only used in one place, so we can change it (it
was new in 24.08).

We really want to be able to just handle a raw onionmessage: this allows
oblivious sending of messages, but also, in combination with the coming
onionmessage_forward_fail notification, allows us to connect then
reinject.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-12-05 13:07:57 +10:30
parent e00e7053fd
commit 57b199bb16
3 changed files with 41 additions and 69 deletions

View file

@ -160,39 +160,6 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
plugin_hook_call_onion_message_recv(ld, NULL, payload);
}
struct onion_hop {
struct pubkey node;
u8 *tlv;
};
static struct command_result *param_onion_hops(struct command *cmd,
const char *name,
const char *buffer,
const jsmntok_t *tok,
struct onion_hop **hops)
{
size_t i;
const jsmntok_t *t;
if (tok->type != JSMN_ARRAY || tok->size == 0)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s must be an (non-empty) array", name);
*hops = tal_arr(cmd, struct onion_hop, tok->size);
json_for_each_arr(i, t, tok) {
const char *err;
err = json_scan(cmd, buffer, t, "{id:%,tlv:%}",
JSON_SCAN(json_to_pubkey, &(*hops)[i].node),
JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex,
&(*hops)[i].tlv));
if (err)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu]: %s", name, i, err);
}
return NULL;
}
static void inject_onionmsg_reply(struct subd *connectd,
const u8 *reply,
const int *fds UNUSED,
@ -217,16 +184,12 @@ static struct command_result *json_injectonionmessage(struct command *cmd,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct onion_hop *hops;
struct pubkey *path_key;
struct sphinx_path *sphinx_path;
struct onionpacket *op;
struct secret *path_secrets;
size_t onion_size;
u8 *msg;
if (!param_check(cmd, buffer, params,
p_req("path_key", param_pubkey, &path_key),
p_req("hops", param_onion_hops, &hops),
p_req("message", param_bin_from_hex, &msg),
NULL))
return command_param_failed();
@ -235,31 +198,16 @@ static struct command_result *json_injectonionmessage(struct command *cmd,
return command_fail(cmd, LIGHTNINGD,
"experimental-onion-messages not enabled");
/* Create an onion which encodes this. */
sphinx_path = sphinx_path_new(cmd, NULL, 0);
for (size_t i = 0; i < tal_count(hops); i++)
sphinx_add_hop(sphinx_path, &hops[i].node, hops[i].tlv);
/* BOLT-onion-message #4:
* - SHOULD set `onion_message_packet` `len` to 1366 or 32834.
*/
if (sphinx_path_payloads_size(sphinx_path) <= ROUTING_INFO_SIZE)
onion_size = ROUTING_INFO_SIZE;
else
onion_size = 32768; /* VERSION_SIZE + HMAC_SIZE + PUBKEY_SIZE == 66 */
op = create_onionpacket(tmpctx, sphinx_path, onion_size, &path_secrets);
if (!op)
if (tal_count(msg) > 65535) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Creating onion failed (tlvs too long?)");
"onion message too long");
}
if (command_check_only(cmd))
return command_check_done(cmd);
subd_req(cmd, cmd->ld->connectd,
take(towire_connectd_inject_onionmsg(NULL,
path_key,
serialize_onionpacket(tmpctx, op))),
take(towire_connectd_inject_onionmsg(NULL, path_key, msg)),
-1, 0, inject_onionmsg_reply, cmd);
return command_still_pending(cmd);
}

View file

@ -238,7 +238,7 @@ $(PLUGIN_KEYSEND_OBJS): $(PLUGIN_PAY_LIB_HEADER)
plugins/spenderp: bitcoin/block.o bitcoin/preimage.o bitcoin/psbt.o common/psbt_open.o common/json_channel_type.o common/channel_type.o common/features.o wire/peer_wiregen.o $(PLUGIN_SPENDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/addr.o common/bolt12.o common/bolt12_merkle.o common/bolt11_json.o common/iso4217.o $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o common/blindedpath.o common/bolt12_id.o common/blinding.o common/hmac.o common/json_blinded_path.o common/gossmap.o common/fp16.o $(JSMN_OBJS) common/dijkstra.o common/route.o common/gossmods_listpeerchannels.o common/onion_message.o
plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/addr.o common/bolt12.o common/bolt12_merkle.o common/bolt11_json.o common/iso4217.o $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o common/blindedpath.o common/bolt12_id.o common/blinding.o common/hmac.o common/json_blinded_path.o common/gossmap.o common/fp16.o $(JSMN_OBJS) common/dijkstra.o common/route.o common/gossmods_listpeerchannels.o common/onion_message.o common/sphinx.o common/onionreply.o
plugins/funder: bitcoin/psbt.o common/psbt_open.o $(PLUGIN_FUNDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)

View file

@ -106,18 +106,42 @@ inject_onionmessage_(struct command *cmd,
void *arg)
{
struct out_req *req;
struct sphinx_path *sphinx_path;
struct onionpacket *op;
struct secret *path_secrets;
size_t onion_size;
req = jsonrpc_request_start(cmd, "injectonionmessage",
cb, errcb, arg);
json_add_pubkey(req->js, "path_key", &omsg->first_path_key);
json_array_start(req->js, "hops");
for (size_t i = 0; i < tal_count(omsg->hops); i++) {
json_object_start(req->js, NULL);
json_add_pubkey(req->js, "id", &omsg->hops[i]->pubkey);
json_add_hex_talarr(req->js, "tlv", omsg->hops[i]->raw_payload);
json_object_end(req->js);
/* Create an onion which encodes this. */
sphinx_path = sphinx_path_new(tmpctx, NULL, 0);
for (size_t i = 0; i < tal_count(omsg->hops); i++)
sphinx_add_hop(sphinx_path,
&omsg->hops[i]->pubkey, omsg->hops[i]->raw_payload);
/* BOLT #4:
* - SHOULD set `onion_message_packet` `len` to 1366 or 32834.
*/
if (sphinx_path_payloads_size(sphinx_path) <= ROUTING_INFO_SIZE)
onion_size = ROUTING_INFO_SIZE;
else
onion_size = 32768; /* VERSION_SIZE + HMAC_SIZE + PUBKEY_SIZE == 66 */
op = create_onionpacket(tmpctx, sphinx_path, onion_size, &path_secrets);
if (!op) {
/* errcb expects a JSON message. */
const char *err;
jsmntok_t *toks;
err = tal_fmt(tmpctx, "{\"code\":%d,\"message\":\"Creating onion failed (tlvs too long?)\"}",
JSONRPC2_INVALID_PARAMS);
toks = json_parse_simple(tmpctx, err, strlen(err));
assert(toks);
/* Not really an error from injectpaymentonion, but near enough */
return errcb(cmd, "injectpaymentonion", err, toks, arg);
}
json_array_end(req->js);
req = jsonrpc_request_start(cmd, "injectonionmessage", cb, errcb, arg);
json_add_pubkey(req->js, "path_key", &omsg->first_path_key);
json_add_hex_talarr(req->js, "message", serialize_onionpacket(tmpctx, op));
return send_outreq(req);
}