diff --git a/common/json_parse.c b/common/json_parse.c index 958d94eb7..e4776d87b 100644 --- a/common/json_parse.c +++ b/common/json_parse.c @@ -647,15 +647,15 @@ struct wally_psbt *json_to_psbt(const tal_t *ctx, const char *buffer, return psbt_from_b64(ctx, buffer + tok->start, tok->end - tok->start); } -struct tlv_onionmsg_payload_reply_path * -json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) +struct blinded_path * +json_to_blinded_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) { - struct tlv_onionmsg_payload_reply_path *rpath; + struct blinded_path *rpath; const jsmntok_t *hops, *t; size_t i; const char *err; - rpath = tal(ctx, struct tlv_onionmsg_payload_reply_path); + rpath = tal(ctx, struct blinded_path); err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}", JSON_SCAN(json_to_pubkey, &rpath->blinding), JSON_SCAN(json_to_pubkey, &rpath->first_node_id), @@ -667,12 +667,12 @@ json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok) if (!hops || hops->size < 1) return tal_free(rpath); - rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size); + rpath->path = tal_arr(rpath, struct onionmsg_hop *, hops->size); json_for_each_arr(i, t, hops) { - rpath->path[i] = tal(rpath->path, struct onionmsg_path); - err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}", + rpath->path[i] = tal(rpath->path, struct onionmsg_hop); + err = json_scan(tmpctx, buffer, t, "{blinded_node_id:%,encrypted_recipient_data:%}", JSON_SCAN(json_to_pubkey, - &rpath->path[i]->node_id), + &rpath->path[i]->blinded_node_id), JSON_SCAN_TAL(rpath->path[i], json_tok_bin_from_hex, &rpath->path[i]->encrypted_recipient_data)); diff --git a/common/json_parse.h b/common/json_parse.h index 9a7d962b3..0c45a925b 100644 --- a/common/json_parse.h +++ b/common/json_parse.h @@ -115,8 +115,8 @@ bool json_to_coin_mvt_tag(const char *buffer, const jsmntok_t *tok, enum mvt_tag *tag); /* Extract reply path from this JSON */ -struct tlv_onionmsg_payload_reply_path * -json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok); +struct blinded_path * +json_to_blinded_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok); bool json_tok_channel_id(const char *buffer, const jsmntok_t *tok, struct channel_id *cid); diff --git a/common/test/run-blindedpath_onion.c b/common/test/run-blindedpath_onion.c index 81b19f8be..4bff3d81c 100644 --- a/common/test/run-blindedpath_onion.c +++ b/common/test/run-blindedpath_onion.c @@ -112,7 +112,7 @@ static u8 *next_onion(const tal_t *ctx, u8 *omsg, struct onionpacket *op; struct pubkey blinding, ephemeral; struct pubkey next_blinding; - struct tlv_onionmsg_payload *om; + struct tlv_onionmsg_tlv *om; struct secret ss, onion_ss; const u8 *cursor; size_t max, maxlen; @@ -136,12 +136,12 @@ static u8 *next_onion(const tal_t *ctx, u8 *omsg, cursor = rs->raw_payload; max = tal_bytelen(rs->raw_payload); maxlen = fromwire_bigsize(&cursor, &max); - om = fromwire_tlv_onionmsg_payload(tmpctx, &cursor, &maxlen); + om = fromwire_tlv_onionmsg_tlv(tmpctx, &cursor, &maxlen); if (rs->nextcase == ONION_END) return NULL; - enc = decrypt_encrypted_data(tmpctx, &blinding, &ss, om->encrypted_data_tlv); + enc = decrypt_encrypted_data(tmpctx, &blinding, &ss, om->encrypted_recipient_data); assert(enc); blindedpath_next_blinding(enc, &blinding, &ss, &next_blinding); return towire_onion_message(ctx, &next_blinding, @@ -154,7 +154,7 @@ int main(int argc, char *argv[]) struct pubkey id[4], blinding_pub[4], override_blinding_pub, alias[4]; struct secret self_id; u8 *enctlv[4]; - u8 *onionmsg_payload[4]; + u8 *onionmsg_tlv[4]; u8 *omsg; struct sphinx_path *sphinx_path; struct secret *path_secrets; @@ -206,12 +206,12 @@ int main(int argc, char *argv[]) /* Create an onion which encodes this. */ sphinx_path = sphinx_path_new(tmpctx, NULL); for (size_t i = 0; i < 4; i++) { - struct tlv_onionmsg_payload *payload - = tlv_onionmsg_payload_new(tmpctx); - payload->encrypted_data_tlv = enctlv[i]; - onionmsg_payload[i] = tal_arr(tmpctx, u8, 0); - towire_tlv_onionmsg_payload(&onionmsg_payload[i], payload); - sphinx_add_hop(sphinx_path, &alias[i], onionmsg_payload[i]); + struct tlv_onionmsg_tlv *payload + = tlv_onionmsg_tlv_new(tmpctx); + payload->encrypted_recipient_data = enctlv[i]; + onionmsg_tlv[i] = tal_arr(tmpctx, u8, 0); + towire_tlv_onionmsg_tlv(&onionmsg_tlv[i], payload); + sphinx_add_hop(sphinx_path, &alias[i], onionmsg_tlv[i]); } op = create_onionpacket(tmpctx, sphinx_path, ROUTING_INFO_SIZE, &path_secrets); @@ -242,8 +242,8 @@ int main(int argc, char *argv[]) type_to_string(tmpctx, struct pubkey, &blinding_pub[i])); json_strfield("blinded_alias", type_to_string(tmpctx, struct pubkey, &alias[i])); - json_strfield("onionmsg_payload", - tal_hex(tmpctx, onionmsg_payload[i])); + json_strfield("onionmsg_tlv", + tal_hex(tmpctx, onionmsg_tlv[i])); printf("\"enctlv\": \"%s\"}\n", tal_hex(tmpctx, enctlv[i])); printf("}"); diff --git a/common/test/run-bolt12_merkle-json.c b/common/test/run-bolt12_merkle-json.c index ae597cb7c..204f9ecf7 100644 --- a/common/test/run-bolt12_merkle-json.c +++ b/common/test/run-bolt12_merkle-json.c @@ -19,6 +19,9 @@ #include /* AUTOGENERATED MOCKS START */ +/* Generated stub for fromwire_blinded_path */ +struct blinded_path *fromwire_blinded_path(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED) +{ fprintf(stderr, "fromwire_blinded_path called!\n"); abort(); } /* Generated stub for fromwire_channel_id */ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct channel_id *channel_id UNNEEDED) @@ -26,9 +29,6 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, /* Generated stub for fromwire_node_id */ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED) { fprintf(stderr, "fromwire_node_id called!\n"); abort(); } -/* Generated stub for fromwire_onionmsg_path */ -struct onionmsg_path *fromwire_onionmsg_path(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED) -{ fprintf(stderr, "fromwire_onionmsg_path called!\n"); abort(); } /* Generated stub for mvt_tag_str */ const char *mvt_tag_str(enum mvt_tag tag UNNEEDED) { fprintf(stderr, "mvt_tag_str called!\n"); abort(); } @@ -38,6 +38,9 @@ bool node_id_from_hexstr(const char *str UNNEEDED, size_t slen UNNEEDED, struct /* Generated stub for towire */ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "towire called!\n"); abort(); } +/* Generated stub for towire_blinded_path */ +void towire_blinded_path(u8 **p UNNEEDED, const struct blinded_path *blinded_path UNNEEDED) +{ fprintf(stderr, "towire_blinded_path called!\n"); abort(); } /* Generated stub for towire_bool */ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) { fprintf(stderr, "towire_bool called!\n"); abort(); } @@ -47,9 +50,6 @@ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id U /* Generated stub for towire_node_id */ void towire_node_id(u8 **pptr UNNEEDED, const struct node_id *id UNNEEDED) { fprintf(stderr, "towire_node_id called!\n"); abort(); } -/* Generated stub for towire_onionmsg_path */ -void towire_onionmsg_path(u8 **p UNNEEDED, const struct onionmsg_path *onionmsg_path UNNEEDED) -{ fprintf(stderr, "towire_onionmsg_path called!\n"); abort(); } /* Generated stub for towire_secp256k1_ecdsa_signature */ void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED, const secp256k1_ecdsa_signature *signature UNNEEDED) diff --git a/common/test/run-bolt12_merkle.c b/common/test/run-bolt12_merkle.c index b953c51c4..53bcf2767 100644 --- a/common/test/run-bolt12_merkle.c +++ b/common/test/run-bolt12_merkle.c @@ -19,19 +19,19 @@ int features_unsupported(const struct feature_set *our_features UNNEEDED, const u8 *their_features UNNEEDED, enum feature_place p UNNEEDED) { fprintf(stderr, "features_unsupported called!\n"); abort(); } +/* Generated stub for fromwire_blinded_path */ +struct blinded_path *fromwire_blinded_path(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED) +{ fprintf(stderr, "fromwire_blinded_path called!\n"); abort(); } /* Generated stub for fromwire_channel_id */ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "fromwire_channel_id called!\n"); abort(); } -/* Generated stub for fromwire_onionmsg_path */ -struct onionmsg_path *fromwire_onionmsg_path(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED) -{ fprintf(stderr, "fromwire_onionmsg_path called!\n"); abort(); } +/* Generated stub for towire_blinded_path */ +void towire_blinded_path(u8 **p UNNEEDED, const struct blinded_path *blinded_path UNNEEDED) +{ fprintf(stderr, "towire_blinded_path called!\n"); abort(); } /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); } -/* Generated stub for towire_onionmsg_path */ -void towire_onionmsg_path(u8 **p UNNEEDED, const struct onionmsg_path *onionmsg_path UNNEEDED) -{ fprintf(stderr, "towire_onionmsg_path called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ /* Contat several tal objects */ diff --git a/common/test/run-route_blinding_onion_test.c b/common/test/run-route_blinding_onion_test.c index c40f21710..b07001ce4 100644 --- a/common/test/run-route_blinding_onion_test.c +++ b/common/test/run-route_blinding_onion_test.c @@ -97,11 +97,12 @@ int main(int argc, char *argv[]) JSON_SCAN(json_to_pubkey, &bpath->blinding), JSON_SCAN(json_to_tok, &hops_tok)) == NULL); - bpath->path = tal_arr(bpath, struct onionmsg_path *, hops_tok->size); + bpath->path = tal_arr(bpath, struct onionmsg_hop *, hops_tok->size); json_for_each_arr(i, t, hops_tok) { - bpath->path[i] = tal(bpath->path, struct onionmsg_path); + bpath->path[i] = tal(bpath->path, struct onionmsg_hop); assert(json_scan(tmpctx, json, t, "{blinded_node_id:%,encrypted_data:%}", - JSON_SCAN(json_to_pubkey, &bpath->path[i]->node_id), + JSON_SCAN(json_to_pubkey, + &bpath->path[i]->blinded_node_id), JSON_SCAN_TAL(bpath->path[i], json_tok_bin_from_hex, &bpath->path[i]->encrypted_recipient_data)) == NULL); diff --git a/connectd/connectd_wire.csv b/connectd/connectd_wire.csv index 4b8666c26..9f3e47f02 100644 --- a/connectd/connectd_wire.csv +++ b/connectd/connectd_wire.csv @@ -120,10 +120,7 @@ msgdata,connectd_ping_reply,totlen,u16, msgtype,connectd_got_onionmsg_to_us,2145 msgdata,connectd_got_onionmsg_to_us,node_alias,pubkey, msgdata,connectd_got_onionmsg_to_us,self_id,?secret, -msgdata,connectd_got_onionmsg_to_us,reply_blinding,?pubkey, -msgdata,connectd_got_onionmsg_to_us,reply_first_node,?pubkey, -msgdata,connectd_got_onionmsg_to_us,reply_path_len,u16, -msgdata,connectd_got_onionmsg_to_us,reply_path,onionmsg_path,reply_path_len +msgdata,connectd_got_onionmsg_to_us,reply,?blinded_path, msgdata,connectd_got_onionmsg_to_us,rawmsg_len,u16, msgdata,connectd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len diff --git a/connectd/onion_message.c b/connectd/onion_message.c index ecc7bbacf..bf22caa37 100644 --- a/connectd/onion_message.c +++ b/connectd/onion_message.c @@ -109,7 +109,7 @@ void handle_onion_message(struct daemon *daemon, struct pubkey blinding, ephemeral; struct route_step *rs; u8 *onion; - struct tlv_onionmsg_payload *om; + struct tlv_onionmsg_tlv *om; struct secret ss, onion_ss; const u8 *cursor; size_t max, maxlen; @@ -166,57 +166,38 @@ void handle_onion_message(struct daemon *daemon, return; } - om = fromwire_tlv_onionmsg_payload(msg, &cursor, &maxlen); + om = fromwire_tlv_onionmsg_tlv(msg, &cursor, &maxlen); if (!om) { - status_peer_debug(&peer->id, "onion msg: invalid onionmsg_payload %s", + status_peer_debug(&peer->id, "onion msg: invalid onionmsg_tlv %s", tal_hex(tmpctx, rs->raw_payload)); return; } if (rs->nextcase == ONION_END) { - struct pubkey *reply_blinding, *first_node_id, me, alias; - const struct onionmsg_path **reply_path; + struct pubkey alias; struct secret *self_id; u8 *omsg; - if (!pubkey_from_node_id(&me, &daemon->id)) { - status_broken("Failed to convert own id"); - return; - } - /* Final enctlv is actually optional */ - if (!om->encrypted_data_tlv) { - alias = me; + if (!om->encrypted_recipient_data) { + alias = daemon->mykey; self_id = NULL; } else if (!decrypt_final_onionmsg(tmpctx, &blinding, &ss, - om->encrypted_data_tlv, &me, &alias, + om->encrypted_recipient_data, &daemon->mykey, &alias, &self_id)) { status_peer_debug(&peer->id, - "onion msg: failed to decrypt enctlv" - " %s", tal_hex(tmpctx, om->encrypted_data_tlv)); + "onion msg: failed to decrypt encrypted_recipient_data" + " %s", tal_hex(tmpctx, om->encrypted_recipient_data)); return; } - if (om->reply_path) { - first_node_id = &om->reply_path->first_node_id; - reply_blinding = &om->reply_path->blinding; - reply_path = cast_const2(const struct onionmsg_path **, - om->reply_path->path); - } else { - first_node_id = NULL; - reply_blinding = NULL; - reply_path = NULL; - } - /* We re-marshall here by policy, before handing to lightningd */ omsg = tal_arr(tmpctx, u8, 0); towire_tlvstream_raw(&omsg, om->fields); daemon_conn_send(daemon->master, take(towire_connectd_got_onionmsg_to_us(NULL, &alias, self_id, - reply_blinding, - first_node_id, - reply_path, + om->reply_path, omsg))); } else { struct pubkey next_node, next_blinding; @@ -224,11 +205,11 @@ void handle_onion_message(struct daemon *daemon, struct node_id next_node_id; /* This fails as expected if no enctlv. */ - if (!decrypt_forwarding_onionmsg(&blinding, &ss, om->encrypted_data_tlv, &next_node, + if (!decrypt_forwarding_onionmsg(&blinding, &ss, om->encrypted_recipient_data, &next_node, &next_blinding)) { status_peer_debug(&peer->id, - "onion msg: invalid enctlv %s", - tal_hex(tmpctx, om->encrypted_data_tlv)); + "onion msg: invalid encrypted_recipient_data %s", + tal_hex(tmpctx, om->encrypted_recipient_data)); return; } diff --git a/devtools/bolt12-cli.c b/devtools/bolt12-cli.c index 6cd4e79a7..b2fdd00c2 100644 --- a/devtools/bolt12-cli.c +++ b/devtools/bolt12-cli.c @@ -260,7 +260,7 @@ static bool print_blindedpaths(struct blinded_path **paths, size_t bp_idx = 0; for (size_t i = 0; i < tal_count(paths); i++) { - struct onionmsg_path **p = paths[i]->path; + struct onionmsg_hop **p = paths[i]->path; printf("blindedpath %zu/%zu: blinding %s", i, tal_count(paths), type_to_string(tmpctx, struct pubkey, @@ -270,7 +270,7 @@ static bool print_blindedpaths(struct blinded_path **paths, for (size_t j = 0; j < tal_count(p); j++) { printf(" %s:%s", type_to_string(tmpctx, struct pubkey, - &p[j]->node_id), + &p[j]->blinded_node_id), tal_hex(tmpctx, p[j]->encrypted_recipient_data)); if (blindedpay) { if (bp_idx < tal_count(blindedpay)) diff --git a/lightningd/onion_message.c b/lightningd/onion_message.c index 666ce78f3..dbcf1b99b 100644 --- a/lightningd/onion_message.c +++ b/lightningd/onion_message.c @@ -15,28 +15,25 @@ struct onion_message_hook_payload { /* Optional */ - struct pubkey *reply_blinding; - struct onionmsg_path **reply_path; - struct pubkey *reply_first_node; + struct blinded_path *reply_path; struct pubkey *our_alias; - struct tlv_onionmsg_payload *om; + struct tlv_onionmsg_tlv *om; }; static void json_add_blindedpath(struct json_stream *stream, const char *fieldname, - const struct pubkey *blinding, - const struct pubkey *first_node_id, - struct onionmsg_path **path) + const struct blinded_path *path) { json_object_start(stream, fieldname); - json_add_pubkey(stream, "blinding", blinding); - json_add_pubkey(stream, "first_node_id", first_node_id); + json_add_pubkey(stream, "first_node_id", &path->first_node_id); + json_add_pubkey(stream, "blinding", &path->blinding); json_array_start(stream, "hops"); - for (size_t i = 0; i < tal_count(path); i++) { + for (size_t i = 0; i < tal_count(path->path); i++) { json_object_start(stream, NULL); - json_add_pubkey(stream, "id", &path[i]->node_id); + json_add_pubkey(stream, "blinded_node_id", + &path->path[i]->blinded_node_id); json_add_hex_talarr(stream, "encrypted_recipient_data", - path[i]->encrypted_recipient_data); + path->path[i]->encrypted_recipient_data); json_object_end(stream); }; json_array_end(stream); @@ -51,12 +48,9 @@ static void onion_message_serialize(struct onion_message_hook_payload *payload, if (payload->our_alias) json_add_pubkey(stream, "our_alias", payload->our_alias); - if (payload->reply_first_node) { + if (payload->reply_path) json_add_blindedpath(stream, "reply_blindedpath", - payload->reply_blinding, - payload->reply_first_node, payload->reply_path); - } if (payload->om->invoice_request) json_add_hex_talarr(stream, "invoice_request", @@ -120,8 +114,6 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg) if (!fromwire_connectd_got_onionmsg_to_us(payload, msg, payload->our_alias, &self_id, - &payload->reply_blinding, - &payload->reply_first_node, &payload->reply_path, &submsg)) { log_broken(ld->log, "bad got_onionmsg_tous: %s", @@ -142,7 +134,7 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg) submsglen = tal_bytelen(submsg); subptr = submsg; - payload->om = fromwire_tlv_onionmsg_payload(payload, &subptr, &submsglen); + payload->om = fromwire_tlv_onionmsg_tlv(payload, &subptr, &submsglen); if (!payload->om) { log_broken(ld->log, "bad got_onionmsg_tous om: %s", tal_hex(tmpctx, msg)); @@ -151,13 +143,6 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg) tal_free(submsg); /* Make sure connectd gets this right. */ - if (payload->reply_path - && (!payload->reply_blinding || !payload->reply_first_node)) { - log_broken(ld->log, - "No reply blinding/first_node, ignoring reply path"); - payload->reply_path = tal_free(payload->reply_path); - } - log_debug(ld->log, "Got onionmsg%s%s", payload->our_alias ? " via-ourpath": "", payload->reply_path ? " reply_path": ""); @@ -295,9 +280,9 @@ static struct command_result *json_blindedpath(struct command *cmd, const jsmntok_t *params) { struct pubkey *ids; - struct onionmsg_path **path; struct privkey first_blinding, blinding_iter; - struct pubkey first_blinding_pubkey, first_node, me; + struct pubkey me; + struct blinded_path *path; size_t nhops; struct json_stream *response; @@ -306,6 +291,7 @@ static struct command_result *json_blindedpath(struct command *cmd, NULL)) return command_param_failed(); + path = tal(cmd, struct blinded_path); nhops = tal_count(ids); /* Final id should be us! */ @@ -313,7 +299,7 @@ static struct command_result *json_blindedpath(struct command *cmd, fatal("My id %s is invalid?", type_to_string(tmpctx, struct node_id, &cmd->ld->id)); - first_node = ids[0]; + path->first_node_id = ids[0]; if (!pubkey_eq(&ids[nhops-1], &me)) return command_fail(cmd, LIGHTNINGD, "Final of ids must be this node (%s), not %s", @@ -322,42 +308,43 @@ static struct command_result *json_blindedpath(struct command *cmd, &ids[nhops-1])); randombytes_buf(&first_blinding, sizeof(first_blinding)); - if (!pubkey_from_privkey(&first_blinding, &first_blinding_pubkey)) + if (!pubkey_from_privkey(&first_blinding, &path->blinding)) /* Should not happen! */ return command_fail(cmd, LIGHTNINGD, "Could not convert blinding to pubkey!"); /* We convert ids into aliases as we go. */ - path = tal_arr(cmd, struct onionmsg_path *, nhops); + path->path = tal_arr(cmd, struct onionmsg_hop *, nhops); blinding_iter = first_blinding; for (size_t i = 0; i < nhops - 1; i++) { - path[i] = tal(path, struct onionmsg_path); - path[i]->encrypted_recipient_data = create_enctlv(path[i], - &blinding_iter, - &ids[i], - &ids[i+1], NULL, - /* FIXME: Pad? */ - 0, - NULL, NULL, NULL, NULL, - &blinding_iter, - &path[i]->node_id); + path->path[i] = tal(path->path, struct onionmsg_hop); + path->path[i]->encrypted_recipient_data + = create_enctlv(path->path[i], + &blinding_iter, + &ids[i], + &ids[i+1], NULL, + /* FIXME: Pad? */ + 0, + NULL, NULL, NULL, NULL, + &blinding_iter, + &path->path[i]->blinded_node_id); } /* FIXME: Add padding! */ - path[nhops-1] = tal(path, struct onionmsg_path); - path[nhops-1]->encrypted_recipient_data = create_final_enctlv(path[nhops-1], - &blinding_iter, - &ids[nhops-1], - /* FIXME: Pad? */ - 0, - &cmd->ld->onion_reply_secret, - NULL, - &path[nhops-1]->node_id); + path->path[nhops-1] = tal(path->path, struct onionmsg_hop); + path->path[nhops-1]->encrypted_recipient_data + = create_final_enctlv(path->path[nhops-1], + &blinding_iter, + &ids[nhops-1], + /* FIXME: Pad? */ + 0, + &cmd->ld->onion_reply_secret, + NULL, + &path->path[nhops-1]->blinded_node_id); response = json_stream_success(cmd); - json_add_blindedpath(response, "blindedpath", - &first_blinding_pubkey, &first_node, path); + json_add_blindedpath(response, "blindedpath", path); return command_success(cmd, response); } diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index fd54d90ee..8d3d41e9b 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -601,7 +601,7 @@ static struct pubkey *path_to_node(const tal_t *ctx, /* Marshal arguments for sending onion messages */ struct sending { struct sent *sent; - struct tlv_onionmsg_payload *payload; + struct tlv_onionmsg_tlv *payload; struct command_result *(*done)(struct command *cmd, const char *buf UNUSED, const jsmntok_t *result UNUSED, @@ -610,14 +610,14 @@ struct sending { static struct command_result * send_modern_message(struct command *cmd, - struct tlv_onionmsg_payload_reply_path *reply_path, + struct blinded_path *reply_path, struct sending *sending) { struct sent *sent = sending->sent; struct privkey blinding_iter; struct pubkey fwd_blinding, *node_alias; size_t nhops = tal_count(sent->path); - struct tlv_onionmsg_payload **payloads; + struct tlv_onionmsg_tlv **payloads; struct out_req *req; /* Now create enctlvs for *forward* path. */ @@ -629,12 +629,12 @@ send_modern_message(struct command *cmd, &blinding_iter)); /* We overallocate: this node (0) doesn't have payload or alias */ - payloads = tal_arr(cmd, struct tlv_onionmsg_payload *, nhops); + payloads = tal_arr(cmd, struct tlv_onionmsg_tlv *, nhops); node_alias = tal_arr(cmd, struct pubkey, nhops); for (size_t i = 1; i < nhops - 1; i++) { - payloads[i] = tlv_onionmsg_payload_new(payloads); - payloads[i]->encrypted_data_tlv = create_enctlv(payloads[i], + payloads[i] = tlv_onionmsg_tlv_new(payloads); + payloads[i]->encrypted_recipient_data = create_enctlv(payloads[i], &blinding_iter, &sent->path[i], &sent->path[i+1], @@ -672,7 +672,7 @@ send_modern_message(struct command *cmd, json_object_start(req->js, NULL); json_add_pubkey(req->js, "id", &node_alias[i]); tlv = tal_arr(tmpctx, u8, 0); - towire_tlv_onionmsg_payload(&tlv, payloads[i]); + towire_tlv_onionmsg_tlv(&tlv, payloads[i]); json_add_hex_talarr(req->js, "tlv", tlv); json_object_end(req->js); } @@ -687,10 +687,10 @@ static struct command_result *use_reply_path(struct command *cmd, const jsmntok_t *result, struct sending *sending) { - struct tlv_onionmsg_payload_reply_path *rpath; + struct blinded_path *rpath; - rpath = json_to_reply_path(cmd, buf, - json_get_member(buf, result, "blindedpath")); + rpath = json_to_blinded_path(cmd, buf, + json_get_member(buf, result, "blindedpath")); if (!rpath) plugin_err(cmd->plugin, "could not parse reply path %.*s?", @@ -700,7 +700,7 @@ static struct command_result *use_reply_path(struct command *cmd, /* Remember our alias we used so we can recognize reply */ sending->sent->reply_alias = tal_dup(sending->sent, struct pubkey, - &rpath->path[tal_count(rpath->path)-1]->node_id); + &rpath->path[tal_count(rpath->path)-1]->blinded_node_id); return send_modern_message(cmd, rpath, sending); } @@ -732,7 +732,7 @@ static struct command_result *make_reply_path(struct command *cmd, static struct command_result *send_message(struct command *cmd, struct sent *sent, - struct tlv_onionmsg_payload *payload STEALS, + struct tlv_onionmsg_tlv *payload STEALS, struct command_result *(*done) (struct command *cmd, const char *buf UNUSED, @@ -780,7 +780,7 @@ sendinvreq_after_connect(struct command *cmd, const jsmntok_t *result UNUSED, struct sent *sent) { - struct tlv_onionmsg_payload *payload = tlv_onionmsg_payload_new(sent); + struct tlv_onionmsg_tlv *payload = tlv_onionmsg_tlv_new(sent); payload->invoice_request = tal_arr(payload, u8, 0); towire_tlv_invoice_request(&payload->invoice_request, sent->invreq); @@ -1279,7 +1279,7 @@ sendinvoice_after_connect(struct command *cmd, const jsmntok_t *result UNUSED, struct sent *sent) { - struct tlv_onionmsg_payload *payload = tlv_onionmsg_payload_new(sent); + struct tlv_onionmsg_tlv *payload = tlv_onionmsg_tlv_new(sent); payload->invoice = tal_arr(payload, u8, 0); towire_tlv_invoice(&payload->invoice, sent->inv); diff --git a/plugins/offers.c b/plugins/offers.c index f354c24c5..e153660a1 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -45,8 +45,8 @@ static struct command_result *sendonionmessage_error(struct command *cmd, struct command_result * send_onion_reply(struct command *cmd, - struct tlv_onionmsg_payload_reply_path *reply_path, - struct tlv_onionmsg_payload *payload) + struct blinded_path *reply_path, + struct tlv_onionmsg_tlv *payload) { struct out_req *req; size_t nhops; @@ -60,22 +60,22 @@ send_onion_reply(struct command *cmd, nhops = tal_count(reply_path->path); for (size_t i = 0; i < nhops; i++) { - struct tlv_onionmsg_payload *omp; + struct tlv_onionmsg_tlv *omp; u8 *tlv; json_object_start(req->js, NULL); - json_add_pubkey(req->js, "id", &reply_path->path[i]->node_id); + json_add_pubkey(req->js, "id", &reply_path->path[i]->blinded_node_id); /* Put payload in last hop. */ if (i == nhops - 1) omp = payload; else - omp = tlv_onionmsg_payload_new(tmpctx); + omp = tlv_onionmsg_tlv_new(tmpctx); - omp->encrypted_data_tlv = reply_path->path[i]->encrypted_recipient_data; + omp->encrypted_recipient_data = reply_path->path[i]->encrypted_recipient_data; tlv = tal_arr(tmpctx, u8, 0); - towire_tlv_onionmsg_payload(&tlv, omp); + towire_tlv_onionmsg_tlv(&tlv, omp); json_add_hex_talarr(req->js, "tlv", tlv); json_object_end(req->js); } @@ -88,7 +88,7 @@ static struct command_result *onion_message_modern_call(struct command *cmd, const jsmntok_t *params) { const jsmntok_t *om, *replytok, *invreqtok, *invtok; - struct tlv_onionmsg_payload_reply_path *reply_path = NULL; + struct blinded_path *reply_path = NULL; if (!offers_enabled) return command_hook_success(cmd); @@ -96,7 +96,7 @@ static struct command_result *onion_message_modern_call(struct command *cmd, om = json_get_member(buf, params, "onion_message"); replytok = json_get_member(buf, om, "reply_blindedpath"); if (replytok) { - reply_path = json_to_reply_path(cmd, buf, replytok); + reply_path = json_to_blinded_path(cmd, buf, replytok); if (!reply_path) plugin_err(cmd->plugin, "Invalid reply path %.*s?", json_tok_full_len(replytok), @@ -228,12 +228,12 @@ static void json_add_chains(struct json_stream *js, static void json_add_onionmsg_path(struct json_stream *js, const char *fieldname, - const struct onionmsg_path *path, + const struct onionmsg_hop *hop, const struct blinded_payinfo *payinfo) { json_object_start(js, fieldname); - json_add_pubkey(js, "node_id", &path->node_id); - json_add_hex_talarr(js, "encrypted_recipient_data", path->encrypted_recipient_data); + json_add_pubkey(js, "blinded_node_id", &hop->blinded_node_id); + json_add_hex_talarr(js, "encrypted_recipient_data", hop->encrypted_recipient_data); if (payinfo) { json_add_u32(js, "fee_base_msat", payinfo->fee_base_msat); json_add_u32(js, "fee_proportional_millionths", diff --git a/plugins/offers.h b/plugins/offers.h index d283da351..dccdaff21 100644 --- a/plugins/offers.h +++ b/plugins/offers.h @@ -8,6 +8,6 @@ struct command; /* Helper to send a reply */ struct command_result *WARN_UNUSED_RESULT send_onion_reply(struct command *cmd, - struct tlv_onionmsg_payload_reply_path *reply_path, - struct tlv_onionmsg_payload *payload); + struct blinded_path *reply_path, + struct tlv_onionmsg_tlv *payload); #endif /* LIGHTNING_PLUGINS_OFFERS_H */ diff --git a/plugins/offers_inv_hook.c b/plugins/offers_inv_hook.c index a4f151f44..67816e8e8 100644 --- a/plugins/offers_inv_hook.c +++ b/plugins/offers_inv_hook.c @@ -13,7 +13,7 @@ struct inv { struct tlv_invoice *inv; /* May be NULL */ - struct tlv_onionmsg_payload_reply_path *reply_path; + struct blinded_path *reply_path; /* The offer, once we've looked it up. */ struct tlv_offer *offer; @@ -26,7 +26,7 @@ fail_inv_level(struct command *cmd, const char *fmt, va_list ap) { char *full_fmt, *msg; - struct tlv_onionmsg_payload *payload; + struct tlv_onionmsg_tlv *payload; struct tlv_invoice_error *err; full_fmt = tal_fmt(tmpctx, "Failed invoice"); @@ -56,7 +56,7 @@ fail_inv_level(struct command *cmd, err->error = tal_dup_arr(err, char, msg, strlen(msg), 0); /* FIXME: Add suggested_value / erroneous_field! */ - payload = tlv_onionmsg_payload_new(tmpctx); + payload = tlv_onionmsg_tlv_new(tmpctx); payload->invoice_error = tal_arr(payload, u8, 0); towire_tlv_invoice_error(&payload->invoice_error, err); return send_onion_reply(cmd, inv->reply_path, payload); @@ -319,7 +319,7 @@ static struct command_result *listoffers_error(struct command *cmd, struct command_result *handle_invoice(struct command *cmd, const u8 *invbin, - struct tlv_onionmsg_payload_reply_path *reply_path STEALS) + struct blinded_path *reply_path STEALS) { size_t len = tal_count(invbin); struct inv *inv = tal(cmd, struct inv); diff --git a/plugins/offers_inv_hook.h b/plugins/offers_inv_hook.h index fbc12ace6..698037391 100644 --- a/plugins/offers_inv_hook.h +++ b/plugins/offers_inv_hook.h @@ -6,5 +6,5 @@ /* We got an onionmessage with an invoice! reply_path could be NULL. */ struct command_result *handle_invoice(struct command *cmd, const u8 *invbin, - struct tlv_onionmsg_payload_reply_path *reply_path STEALS); + struct blinded_path *reply_path STEALS); #endif /* LIGHTNING_PLUGINS_OFFERS_INV_HOOK_H */ diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index b66f0894d..0cf6b71fe 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -16,7 +16,7 @@ /* We need to keep the reply path around so we can reply with invoice */ struct invreq { struct tlv_invoice_request *invreq; - struct tlv_onionmsg_payload_reply_path *reply_path; + struct blinded_path *reply_path; /* The offer, once we've looked it up. */ struct tlv_offer *offer; @@ -35,7 +35,7 @@ fail_invreq_level(struct command *cmd, const char *fmt, va_list ap) { char *full_fmt, *msg; - struct tlv_onionmsg_payload *payload; + struct tlv_onionmsg_tlv *payload; struct tlv_invoice_error *err; full_fmt = tal_fmt(tmpctx, "Failed invoice_request"); @@ -61,7 +61,7 @@ fail_invreq_level(struct command *cmd, err->error = tal_dup_arr(err, char, msg, strlen(msg), 0); /* FIXME: Add suggested_value / erroneous_field! */ - payload = tlv_onionmsg_payload_new(tmpctx); + payload = tlv_onionmsg_tlv_new(tmpctx); payload->invoice_error = tal_arr(payload, u8, 0); towire_tlv_invoice_error(&payload->invoice_error, err); return send_onion_reply(cmd, invreq->reply_path, payload); @@ -170,7 +170,7 @@ static struct command_result *createinvoice_done(struct command *cmd, { char *hrp; u8 *rawinv; - struct tlv_onionmsg_payload *payload; + struct tlv_onionmsg_tlv *payload; const jsmntok_t *t; /* We have a signed invoice, use it as a reply. */ @@ -183,7 +183,7 @@ static struct command_result *createinvoice_done(struct command *cmd, json_tok_full(buf, t)); } - payload = tlv_onionmsg_payload_new(tmpctx); + payload = tlv_onionmsg_tlv_new(tmpctx); payload->invoice = rawinv; return send_onion_reply(cmd, ir->reply_path, payload); } @@ -831,7 +831,7 @@ static struct command_result *handle_offerless_request(struct command *cmd, struct command_result *handle_invoice_request(struct command *cmd, const u8 *invreqbin, - struct tlv_onionmsg_payload_reply_path *reply_path) + struct blinded_path *reply_path) { size_t len = tal_count(invreqbin); struct invreq *ir = tal(cmd, struct invreq); diff --git a/plugins/offers_invreq_hook.h b/plugins/offers_invreq_hook.h index c9dc5f37c..edf150782 100644 --- a/plugins/offers_invreq_hook.h +++ b/plugins/offers_invreq_hook.h @@ -8,5 +8,5 @@ extern u16 cltv_final; /* We got an onionmessage with an invreq! */ struct command_result *handle_invoice_request(struct command *cmd, const u8 *invreqbin, - struct tlv_onionmsg_payload_reply_path *reply_path STEALS); + struct blinded_path *reply_path STEALS); #endif /* LIGHTNING_PLUGINS_OFFERS_INVREQ_HOOK_H */ diff --git a/tools/generate-wire.py b/tools/generate-wire.py index 24a2a1370..8b7b148d7 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -237,7 +237,8 @@ class Type(FieldSet): 'height_states', 'onionreply', 'feature_set', - 'onionmsg_path', + 'onionmsg_hop', + 'blinded_path', 'route_hop', 'tx_parts', 'wally_psbt', diff --git a/wire/bolt12_exp_wire.csv b/wire/bolt12_exp_wire.csv index 440ce32b9..8c20ced38 100644 --- a/wire/bolt12_exp_wire.csv +++ b/wire/bolt12_exp_wire.csv @@ -37,11 +37,6 @@ tlvtype,offer,refund_for,34 tlvdata,offer,refund_for,refunded_payment_hash,sha256, tlvtype,offer,signature,240 tlvdata,offer,signature,sig,bip340sig, -subtype,blinded_path -subtypedata,blinded_path,first_node_id,point, -subtypedata,blinded_path,blinding,point, -subtypedata,blinded_path,num_hops,byte, -subtypedata,blinded_path,path,onionmsg_path,num_hops tlvtype,invoice_request,chain,3 tlvdata,invoice_request,chain,chain,chain_hash, tlvtype,invoice_request,offer_id,4 diff --git a/wire/bolt12_wire.csv b/wire/bolt12_wire.csv index 440ce32b9..8c20ced38 100644 --- a/wire/bolt12_wire.csv +++ b/wire/bolt12_wire.csv @@ -37,11 +37,6 @@ tlvtype,offer,refund_for,34 tlvdata,offer,refund_for,refunded_payment_hash,sha256, tlvtype,offer,signature,240 tlvdata,offer,signature,sig,bip340sig, -subtype,blinded_path -subtypedata,blinded_path,first_node_id,point, -subtypedata,blinded_path,blinding,point, -subtypedata,blinded_path,num_hops,byte, -subtypedata,blinded_path,path,onionmsg_path,num_hops tlvtype,invoice_request,chain,3 tlvdata,invoice_request,chain,chain,chain_hash, tlvtype,invoice_request,offer_id,4 diff --git a/wire/extracted_onion_02_modernonion.patch b/wire/extracted_onion_02_modernonion.patch index 4056d2e9b..f697284ba 100644 --- a/wire/extracted_onion_02_modernonion.patch +++ b/wire/extracted_onion_02_modernonion.patch @@ -1,6 +1,6 @@ --- wire/onion_wire.csv 2021-11-16 15:17:39.446494580 +1030 +++ wire/onion_wire.csv.raw 2021-11-16 15:36:00.046441058 +1030 -@@ -8,6 +8,36 @@ +@@ -8,6 +8,41 @@ tlvdata,tlv_payload,payment_data,total_msat,tu64, tlvtype,tlv_payload,payment_metadata,16 tlvdata,tlv_payload,payment_metadata,payment_metadata,byte,... @@ -8,6 +8,8 @@ +tlvdata,tlv_payload,encrypted_recipient_data,encrypted_data,byte,... +tlvtype,tlv_payload,blinding_point,12 +tlvdata,tlv_payload,blinding_point,blinding,point, ++tlvtype,tlv_payload,total_amount_msat,18 ++tlvdata,tlv_payload,total_amount_msat,total_msat,tu64, +tlvtype,encrypted_data_tlv,padding,1 +tlvdata,encrypted_data_tlv,padding,padding,byte,... +tlvtype,encrypted_data_tlv,short_channel_id,2 @@ -18,22 +20,25 @@ +tlvdata,encrypted_data_tlv,path_id,data,byte,... +tlvtype,encrypted_data_tlv,next_blinding_override,8 +tlvdata,encrypted_data_tlv,next_blinding_override,blinding,point, -+tlvtype,onionmsg_payload,reply_path,2 -+tlvdata,onionmsg_payload,reply_path,first_node_id,point, -+tlvdata,onionmsg_payload,reply_path,blinding,point, -+tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,... -+tlvtype,onionmsg_payload,encrypted_data_tlv,4 -+tlvdata,onionmsg_payload,encrypted_data_tlv,encrypted_data_tlv,byte,... -+tlvtype,onionmsg_payload,invoice_request,64 -+tlvdata,onionmsg_payload,invoice_request,invoice_request,tlv_invoice_request, -+tlvtype,onionmsg_payload,invoice,66 -+tlvdata,onionmsg_payload,invoice,invoice,tlv_invoice, -+tlvtype,onionmsg_payload,invoice_error,68 -+tlvdata,onionmsg_payload,invoice_error,invoice_error,tlv_invoice_error, -+subtype,onionmsg_path -+subtypedata,onionmsg_path,node_id,point, -+subtypedata,onionmsg_path,enclen,u16, -+subtypedata,onionmsg_path,encrypted_recipient_data,byte,enclen ++tlvtype,onionmsg_tlv,reply_path,2 ++tlvdata,onionmsg_tlv,reply_path,path,blinded_path, ++tlvtype,onionmsg_tlv,encrypted_recipient_data,4 ++tlvdata,onionmsg_tlv,encrypted_recipient_data,encrypted_recipient_data,byte,... ++tlvtype,onionmsg_tlv,invoice_request,64 ++tlvdata,onionmsg_tlv,invoice_request,invoice_request,tlv_invoice_request, ++tlvtype,onionmsg_tlv,invoice,66 ++tlvdata,onionmsg_tlv,invoice,invoice,tlv_invoice, ++tlvtype,onionmsg_tlv,invoice_error,68 ++tlvdata,onionmsg_tlv,invoice_error,invoice_error,tlv_invoice_error, ++subtype,blinded_path ++subtypedata,blinded_path,first_node_id,point, ++subtypedata,blinded_path,blinding,point, ++subtypedata,blinded_path,num_hops,byte, ++subtypedata,blinded_path,path,onionmsg_hop,num_hops ++subtype,onionmsg_hop ++subtypedata,onionmsg_hop,blinded_node_id,point, ++subtypedata,onionmsg_hop,enclen,u16, ++subtypedata,onionmsg_hop,encrypted_recipient_data,byte,enclen msgtype,invalid_realm,PERM|1 msgtype,temporary_node_failure,NODE|2 msgtype,permanent_node_failure,PERM|NODE|2 diff --git a/wire/extracted_onion_03_onionmsg-payload-as-bytearr.patch b/wire/extracted_onion_03_onionmsg-payload-as-bytearr.patch index 41eedfd3f..e56894dda 100644 --- a/wire/extracted_onion_03_onionmsg-payload-as-bytearr.patch +++ b/wire/extracted_onion_03_onionmsg-payload-as-bytearr.patch @@ -2,18 +2,18 @@ diff --git b/wire/onion_wire.csv a/wire/onion_wire.csv index 5c52fe9a1..2ac0c4cff 100644 --- b/wire/onion_wire.csv +++ a/wire/onion_wire.csv -@@ -51,11 +29,11 @@ tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,... - tlvtype,onionmsg_payload,encrypted_data_tlv,4 - tlvdata,onionmsg_payload,encrypted_data_tlv,encrypted_data_tlv,byte,... - tlvtype,onionmsg_payload,invoice_request,64 --tlvdata,onionmsg_payload,invoice_request,invoice_request,tlv_invoice_request, -+tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,... - tlvtype,onionmsg_payload,invoice,66 --tlvdata,onionmsg_payload,invoice,invoice,tlv_invoice, -+tlvdata,onionmsg_payload,invoice,invoice,byte,... - tlvtype,onionmsg_payload,invoice_error,68 --tlvdata,onionmsg_payload,invoice_error,invoice_error,tlv_invoice_error, -+tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,... - subtype,onionmsg_path - subtypedata,onionmsg_path,node_id,point, - subtypedata,onionmsg_path,enclen,u16, +@@ -51,11 +29,11 @@ tlvdata,onionmsg_tlv,reply_path,path,onionmsg_path,... + tlvtype,onionmsg_tlv,encrypted_data_tlv,4 + tlvdata,onionmsg_tlv,encrypted_data_tlv,encrypted_data_tlv,byte,... + tlvtype,onionmsg_tlv,invoice_request,64 +-tlvdata,onionmsg_tlv,invoice_request,invoice_request,tlv_invoice_request, ++tlvdata,onionmsg_tlv,invoice_request,invoice_request,byte,... + tlvtype,onionmsg_tlv,invoice,66 +-tlvdata,onionmsg_tlv,invoice,invoice,tlv_invoice, ++tlvdata,onionmsg_tlv,invoice,invoice,byte,... + tlvtype,onionmsg_tlv,invoice_error,68 +-tlvdata,onionmsg_tlv,invoice_error,invoice_error,tlv_invoice_error, ++tlvdata,onionmsg_tlv,invoice_error,invoice_error,byte,... + subtype,blinded_path + subtypedata,blinded_path,first_node_id,point, + subtypedata,blinded_path,blinding,point, diff --git a/wire/extracted_onion_04_route-blinding-htlcs.patch b/wire/extracted_onion_04_route-blinding-htlcs.patch index d36a7545c..2df6cf3ba 100644 --- a/wire/extracted_onion_04_route-blinding-htlcs.patch +++ b/wire/extracted_onion_04_route-blinding-htlcs.patch @@ -15,6 +15,6 @@ index 9326f9f8e..d5d074d1f 100644 +tlvdata,encrypted_data_tlv,payment_constraints,htlc_minimum_msat,tu64, +tlvtype,encrypted_data_tlv,allowed_features,14 +tlvdata,encrypted_data_tlv,allowed_features,features,byte,... - tlvtype,onionmsg_payload,reply_path,2 - tlvdata,onionmsg_payload,reply_path,first_node_id,point, - tlvdata,onionmsg_payload,reply_path,blinding,point, + tlvtype,onionmsg_tlv,reply_path,2 + tlvdata,onionmsg_tlv,reply_path,first_node_id,point, + tlvdata,onionmsg_tlv,reply_path,blinding,point, diff --git a/wire/onion_wire.csv b/wire/onion_wire.csv index 5f18603ee..75f5f5e4f 100644 --- a/wire/onion_wire.csv +++ b/wire/onion_wire.csv @@ -14,6 +14,8 @@ tlvtype,tlv_payload,encrypted_recipient_data,10 tlvdata,tlv_payload,encrypted_recipient_data,encrypted_data,byte,... tlvtype,tlv_payload,blinding_point,12 tlvdata,tlv_payload,blinding_point,blinding,point, +tlvtype,tlv_payload,total_amount_msat,18 +tlvdata,tlv_payload,total_amount_msat,total_msat,tu64, tlvtype,encrypted_data_tlv,padding,1 tlvdata,encrypted_data_tlv,padding,padding,byte,... tlvtype,encrypted_data_tlv,short_channel_id,2 @@ -33,22 +35,25 @@ tlvdata,encrypted_data_tlv,payment_constraints,max_cltv_expiry,u32, tlvdata,encrypted_data_tlv,payment_constraints,htlc_minimum_msat,tu64, tlvtype,encrypted_data_tlv,allowed_features,14 tlvdata,encrypted_data_tlv,allowed_features,features,byte,... -tlvtype,onionmsg_payload,reply_path,2 -tlvdata,onionmsg_payload,reply_path,first_node_id,point, -tlvdata,onionmsg_payload,reply_path,blinding,point, -tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,... -tlvtype,onionmsg_payload,encrypted_data_tlv,4 -tlvdata,onionmsg_payload,encrypted_data_tlv,encrypted_data_tlv,byte,... -tlvtype,onionmsg_payload,invoice_request,64 -tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,... -tlvtype,onionmsg_payload,invoice,66 -tlvdata,onionmsg_payload,invoice,invoice,byte,... -tlvtype,onionmsg_payload,invoice_error,68 -tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,... -subtype,onionmsg_path -subtypedata,onionmsg_path,node_id,point, -subtypedata,onionmsg_path,enclen,u16, -subtypedata,onionmsg_path,encrypted_recipient_data,byte,enclen +tlvtype,onionmsg_tlv,reply_path,2 +tlvdata,onionmsg_tlv,reply_path,path,blinded_path, +tlvtype,onionmsg_tlv,encrypted_recipient_data,4 +tlvdata,onionmsg_tlv,encrypted_recipient_data,encrypted_recipient_data,byte,... +tlvtype,onionmsg_tlv,invoice_request,64 +tlvdata,onionmsg_tlv,invoice_request,invoice_request,byte,... +tlvtype,onionmsg_tlv,invoice,66 +tlvdata,onionmsg_tlv,invoice,invoice,byte,... +tlvtype,onionmsg_tlv,invoice_error,68 +tlvdata,onionmsg_tlv,invoice_error,invoice_error,byte,... +subtype,blinded_path +subtypedata,blinded_path,first_node_id,point, +subtypedata,blinded_path,blinding,point, +subtypedata,blinded_path,num_hops,byte, +subtypedata,blinded_path,path,onionmsg_hop,num_hops +subtype,onionmsg_hop +subtypedata,onionmsg_hop,blinded_node_id,point, +subtypedata,onionmsg_hop,enclen,u16, +subtypedata,onionmsg_hop,encrypted_recipient_data,byte,enclen msgtype,invalid_realm,PERM|1 msgtype,temporary_node_failure,NODE|2 msgtype,permanent_node_failure,PERM|NODE|2