diff --git a/common/bolt12.c b/common/bolt12.c index 50de689b2..03d145094 100644 --- a/common/bolt12.c +++ b/common/bolt12.c @@ -74,7 +74,7 @@ static char *check_features_and_chain(const tal_t *ctx, bool bolt12_check_signature(const struct tlv_field *fields, const char *messagename, const char *fieldname, - const struct point32 *key, + const struct pubkey *key, const struct bip340sig *sig) { struct sha256 m, shash; @@ -89,7 +89,7 @@ static char *check_signature(const tal_t *ctx, const struct tlv_field *fields, const char *messagename, const char *fieldname, - const struct point32 *node_id, + const struct pubkey *node_id, const struct bip340sig *sig) { if (!node_id) diff --git a/common/bolt12.h b/common/bolt12.h index 4aa4ce761..93801dc2d 100644 --- a/common/bolt12.h +++ b/common/bolt12.h @@ -96,7 +96,7 @@ struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx, bool bolt12_check_signature(const struct tlv_field *fields, const char *messagename, const char *fieldname, - const struct point32 *key, + const struct pubkey *key, const struct bip340sig *sig); /* Given a single bolt12 chain, does it match? (NULL == bitcoin) */ diff --git a/common/test/run-bolt12_merkle.c b/common/test/run-bolt12_merkle.c index 990692f4d..b953c51c4 100644 --- a/common/test/run-bolt12_merkle.c +++ b/common/test/run-bolt12_merkle.c @@ -310,8 +310,8 @@ int main(int argc, char *argv[]) /* Now try with an actual offer, with 6 fields. */ struct tlv_offer *offer = offer_decode(tmpctx, - "lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczs", - strlen("lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczs"), + "lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83pqf9e58aguqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2", + strlen("lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83pqf9e58aguqr0rcun0ajlvmzq3ek63cw2w282gv3z5uupmuwvgjtq2"), NULL, NULL, &fail); assert(tal_count(offer->fields) == 6); @@ -327,10 +327,10 @@ int main(int argc, char *argv[]) fieldwires[3] = tlv(20, "rusty.ozlabs.org", strlen("rusty.ozlabs.org")); /* recurrence: time_unit = 1, period = 1 */ fieldwires[4] = tlv(26, "\x01\x01", 2); - /* node_id: 4b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605 */ - fieldwires[5] = tlv(30, "\x4b\x9a\x1f\xa8\xe0\x06\xf1\xe3\x93\x7f\x65\xf6\x6c\x40\x8e\x6d\xa8\xe1\xca\x72\x8e\xa4\x32\x22\xa7\x38\x1d\xf1\xcc\x44\x96\x05", 32); + /* node_id: 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605 */ + fieldwires[5] = tlv(30, "\x02\x4b\x9a\x1f\xa8\xe0\x06\xf1\xe3\x93\x7f\x65\xf6\x6c\x40\x8e\x6d\xa8\xe1\xca\x72\x8e\xa4\x32\x22\xa7\x38\x1d\xf1\xcc\x44\x96\x05", 33); - json_out("{\"comment\": \"offer test, currency = USD, amount = 1000, description = 10USD every day, issuer = rusty.ozlabs.org, recurrence = time_unit = 1, period = 1, node_id = 4b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605\","); + json_out("{\"comment\": \"offer test, currency = USD, amount = 1000, description = 10USD every day, issuer = rusty.ozlabs.org, recurrence = time_unit = 1, period = 1, node_id = 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605\","); json_out("\"tlv\": \"offer\","); all = concat(fieldwires[0], fieldwires[1], fieldwires[2], diff --git a/devtools/bolt12-cli.c b/devtools/bolt12-cli.c index 800be2ec9..6cd4e79a7 100644 --- a/devtools/bolt12-cli.c +++ b/devtools/bolt12-cli.c @@ -152,9 +152,9 @@ static void print_issuer(const char *issuer) printf("issuer: %.*s\n", (int)tal_bytelen(issuer), issuer); } -static void print_node_id(const struct point32 *node_id) +static void print_node_id(const struct pubkey *node_id) { - printf("node_id: %s\n", type_to_string(tmpctx, struct point32, node_id)); + printf("node_id: %s\n", type_to_string(tmpctx, struct pubkey, node_id)); } static void print_quantity_min(u64 min) @@ -307,7 +307,7 @@ static void print_refund_for(const struct sha256 *payment_hash) static bool print_signature(const char *messagename, const char *fieldname, const struct tlv_field *fields, - const struct point32 *node_id, + const struct pubkey *node_id, const struct bip340sig *sig) { struct sha256 m, shash; @@ -363,11 +363,11 @@ static bool print_recurrence_counter_with_base(const u32 *recurrence_counter, return true; } -static void print_payer_key(const struct point32 *payer_key, +static void print_payer_key(const struct pubkey *payer_key, const u8 *payer_info) { printf("payer_key: %s", - type_to_string(tmpctx, struct point32, payer_key)); + type_to_string(tmpctx, struct pubkey, payer_key)); if (payer_info) printf(" (payer_info %s)", tal_hex(tmpctx, payer_info)); printf("\n"); diff --git a/doc/lightning-decode.7.md b/doc/lightning-decode.7.md index 53e23c4ea..003933bb8 100644 --- a/doc/lightning-decode.7.md +++ b/doc/lightning-decode.7.md @@ -30,7 +30,7 @@ On success, an object is returned, containing: If **type** is "bolt12 offer", and **valid** is *true*: - **offer\_id** (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters) - - **node\_id** (point32): x-only public key of the offering node + - **node\_id** (pubkey): public key of the offering node - **description** (string): the description of the purpose of the offer - **signature** (bip340sig, optional): BIP-340 signature of the *node_id* on this offer - **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): @@ -72,7 +72,7 @@ If **type** is "bolt12 offer", and **valid** is *false*: If **type** is "bolt12 invoice", and **valid** is *true*: - - **node\_id** (point32): x-only public key of the offering node + - **node\_id** (pubkey): public key of the offering node - **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer - **amount\_msat** (msat): the amount in bitcoin - **description** (string): the description of the purpose of the offer @@ -95,7 +95,7 @@ If **type** is "bolt12 invoice", and **valid** is *true*: - **recurrence\_counter** (u32, optional): the 0-based counter for a recurring payment - **recurrence\_start** (u32, optional): the optional start period for a recurring payment - **recurrence\_basetime** (u32, optional): the UNIX timestamp of the first recurrence period start - - **payer\_key** (point32, optional): the transient key which identifies the payer + - **payer\_key** (pubkey, optional): the transient key which identifies the payer - **payer\_info** (hex, optional): the payer-provided blob to derive payer_key - **fallbacks** (array of objects, optional): onchain addresses: - **version** (u8): Segwit address version @@ -123,7 +123,7 @@ If **type** is "bolt12 invoice", and **valid** is *false*: If **type** is "bolt12 invoice_request", and **valid** is *true*: - **offer\_id** (hex): the id of the offer this is requesting (merkle hash of non-signature fields) (always 64 characters) - - **payer\_key** (point32): the transient key which identifies the payer + - **payer\_key** (pubkey): the transient key which identifies the payer - **chain** (hex, optional): which blockchain this invoice_request is for (missing implies bitcoin mainnet only) (always 64 characters) - **amount\_msat** (msat, optional): the amount in bitcoin - **features** (hex, optional): the array of feature bits for this offer @@ -211,4 +211,4 @@ RESOURCES Main web site: -[comment]: # ( SHA256STAMP:610b6f9d61e79b503ff81cc164f79ea90883c6d10f5e7b28555aefabfd6e17bb) +[comment]: # ( SHA256STAMP:3348f74162c4a2737f1bc50f1903e7e25484747a1bc9ba7d3cd3f30b57589fdf) diff --git a/doc/schemas/decode.schema.json b/doc/schemas/decode.schema.json index 66b86a4f2..4d12c267a 100644 --- a/doc/schemas/decode.schema.json +++ b/doc/schemas/decode.schema.json @@ -57,8 +57,8 @@ "minLength": 64 }, "node_id": { - "type": "point32", - "description": "x-only public key of the offering node" + "type": "pubkey", + "description": "public key of the offering node" }, "signature": { "type": "bip340sig", @@ -325,8 +325,8 @@ "minLength": 64 }, "node_id": { - "type": "point32", - "description": "x-only public key of the offering node" + "type": "pubkey", + "description": "public key of the offering node" }, "signature": { "type": "bip340sig", @@ -424,7 +424,7 @@ "description": "the UNIX timestamp of the first recurrence period start" }, "payer_key": { - "type": "point32", + "type": "pubkey", "description": "the transient key which identifies the payer" }, "payer_info": { @@ -652,7 +652,7 @@ "description": "the optional start period for a recurring payment" }, "payer_key": { - "type": "point32", + "type": "pubkey", "description": "the transient key which identifies the payer" }, "payer_info": { diff --git a/lightningd/offer.c b/lightningd/offer.c index f9fc2081a..4c8e221e0 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -57,7 +57,7 @@ static void hsm_sign_b12(struct lightningd *ld, const char *fieldname, const struct sha256 *merkle, const u8 *publictweak, - const struct point32 *key, + const struct pubkey *key, struct bip340sig *sig) { u8 *msg; @@ -93,7 +93,7 @@ static struct command_result *json_createoffer(struct command *cmd, const char *b12str, *b12str_nosig; bool *single_use; enum offer_status status; - struct point32 key; + struct pubkey key; bool created; if (!param(cmd, buffer, params, @@ -109,7 +109,7 @@ static struct command_result *json_createoffer(struct command *cmd, status = OFFER_MULTIPLE_USE_UNUSED; merkle_tlv(offer->fields, &merkle); offer->signature = tal(offer, struct bip340sig); - if (!point32_from_node_id(&key, &cmd->ld->id)) + if (!pubkey_from_node_id(&key, &cmd->ld->id)) fatal("invalid own node_id?"); hsm_sign_b12(cmd->ld, "offer", "signature", &merkle, NULL, &key, offer->signature); @@ -393,14 +393,14 @@ static struct command_result *param_b12_invreq(struct command *cmd, static bool payer_key(struct lightningd *ld, const u8 *public_tweak, size_t public_tweak_len, - struct point32 *key) + struct pubkey *key) { struct sha256 tweakhash; payer_key_tweak(&ld->bolt12_base, public_tweak, public_tweak_len, &tweakhash); - key->pubkey = ld->bolt12_base.pubkey; + *key = ld->bolt12_base; return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx, &key->pubkey, tweakhash.u.u8) == 1; @@ -452,7 +452,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd, tal_bytelen(invreq->payer_info)); } - invreq->payer_key = tal(invreq, struct point32); + invreq->payer_key = tal(invreq, struct pubkey); if (!payer_key(cmd->ld, invreq->payer_info, tal_bytelen(invreq->payer_info), invreq->payer_key)) { @@ -500,7 +500,7 @@ static struct command_result *json_payersign(struct command *cmd, u8 *tweak; struct bip340sig sig; const char *messagename, *fieldname; - struct point32 key; + struct pubkey key; if (!param(cmd, buffer, params, p_req("messagename", param_string, &messagename), diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index b7682efff..8ecf9c41e 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -204,7 +204,7 @@ static struct command_result *handle_invreq_response(struct command *cmd, /* BOLT-offers #12: * - MUST reject the invoice unless `node_id` is equal to the offer. */ - if (!point32_eq(sent->offer->node_id, inv->node_id)) { + if (!pubkey_eq(sent->offer->node_id, inv->node_id)) { badfield = "node_id"; goto badinv; } @@ -556,41 +556,9 @@ static bool can_carry_onionmsg(const struct gossmap *map, || gossmap_node_get_feature(map, n, 102) != -1; } -enum nodeid_parity { - nodeid_parity_even = SECP256K1_TAG_PUBKEY_EVEN, - nodeid_parity_odd = SECP256K1_TAG_PUBKEY_ODD, - nodeid_parity_unknown = 1, -}; - -static enum nodeid_parity node_parity(const struct gossmap *gossmap, - const struct gossmap_node *node) - -{ - struct node_id id; - gossmap_node_get_id(gossmap, node, &id); - return id.k[0]; -} - -static void node_id_from_point32(struct node_id *nid, - const struct point32 *node32_id, - enum nodeid_parity parity) -{ - struct pubkey pk; - assert(parity == SECP256K1_TAG_PUBKEY_EVEN - || parity == SECP256K1_TAG_PUBKEY_ODD); - - pk.pubkey = node32_id->pubkey; - node_id_from_pubkey(nid, &pk); - nid->k[0] = parity; -} - -/* Create path to node which can carry onion messages (including - * self); if it can't find one, returns NULL. Fills in nodeid_parity - * for 33rd nodeid byte. */ static struct pubkey *path_to_node(const tal_t *ctx, struct plugin *plugin, - const struct point32 *node32_id, - enum nodeid_parity *parity) + const struct pubkey *node_id) { struct route_hop *r; const struct dijkstra *dij; @@ -600,21 +568,10 @@ static struct pubkey *path_to_node(const tal_t *ctx, struct pubkey *nodes; struct gossmap *gossmap = get_gossmap(plugin); - /* We try both parities. */ - *parity = nodeid_parity_even; - node_id_from_point32(&dstid, node32_id, *parity); + node_id_from_pubkey(&dstid, node_id); dst = gossmap_find_node(gossmap, &dstid); - if (!dst) { - *parity = nodeid_parity_odd; - node_id_from_point32(&dstid, node32_id, *parity); - dst = gossmap_find_node(gossmap, &dstid); - if (!dst) { - *parity = nodeid_parity_unknown; - return NULL; - } - } - - *parity = node_parity(gossmap, dst); + if (!dst) + return NULL; /* If we don't exist in gossip, routing can't happen. */ node_id_from_pubkey(&local_nodeid, &local_id); @@ -857,41 +814,11 @@ static struct command_result *connect_failed(struct command *command, NULL); } -/* Offers contain only a 32-byte id. If we can't find the address, we - * don't know if it's 02 or 03, so we try both. If we're here, we - * failed 02. */ -static struct command_result *try_other_parity(struct command *cmd, - const char *buf, - const jsmntok_t *result, - struct connect_attempt *ca) -{ - struct out_req *req; - - /* Flip parity */ - ca->node_id.k[0] = SECP256K1_TAG_PUBKEY_ODD; - /* Path is us -> them, so they're second entry */ - if (!pubkey_from_node_id(&ca->sent->path[1], &ca->node_id)) { - /* Should not happen! - * Pieter Wuille points out: - * y^2 = x^3 + 7 mod p - * negating y doesn’t change the left hand side - */ - return command_done_err(cmd, LIGHTNINGD, - "Failed: could not convert inverted pubkey?", - NULL); - } - req = jsonrpc_request_start(cmd->plugin, cmd, "connect", connected, - connect_failed, ca); - json_add_node_id(req->js, "id", &ca->node_id); - return send_outreq(cmd->plugin, req); -} - /* We can't find a route, so we're going to try to connect, then just blast it * to them. */ static struct command_result * connect_direct(struct command *cmd, - const struct point32 *dst, - enum nodeid_parity parity, + const struct pubkey *dst, struct command_result *(*cb)(struct command *command, const char *buf, const jsmntok_t *result, @@ -903,20 +830,7 @@ connect_direct(struct command *cmd, ca->cb = cb; ca->sent = sent; - - if (parity == nodeid_parity_unknown) { - plugin_notify_message(cmd, LOG_INFORM, - "Cannot find route, trying connect to 02/03%s directly", - type_to_string(tmpctx, struct point32, dst)); - /* Try even first. */ - node_id_from_point32(&ca->node_id, dst, SECP256K1_TAG_PUBKEY_EVEN); - } else { - plugin_notify_message(cmd, LOG_INFORM, - "Cannot find route, trying connect to %02x%s directly", - parity, - type_to_string(tmpctx, struct point32, dst)); - node_id_from_point32(&ca->node_id, dst, parity); - } + node_id_from_pubkey(&ca->node_id, dst); /* Make a direct path -> dst. */ sent->path = tal_arr(sent, struct pubkey, 2); @@ -934,14 +848,13 @@ connect_direct(struct command *cmd, "Cannot find route, but" " fetchplugin-noconnect set:" " trying direct anyway to %s", - type_to_string(tmpctx, struct point32, + type_to_string(tmpctx, struct pubkey, dst)); return cb(cmd, NULL, NULL, sent); } req = jsonrpc_request_start(cmd->plugin, cmd, "connect", connected, - parity == nodeid_parity_unknown ? - try_other_parity : connect_failed, ca); + connect_failed, ca); json_add_node_id(req->js, "id", &ca->node_id); return send_outreq(cmd->plugin, req); } @@ -953,7 +866,6 @@ static struct command_result *invreq_done(struct command *cmd, { const jsmntok_t *t; char *fail; - enum nodeid_parity parity; /* Get invoice request */ t = json_get_member(buf, result, "bolt12"); @@ -1047,10 +959,9 @@ static struct command_result *invreq_done(struct command *cmd, } sent->path = path_to_node(sent, cmd->plugin, - sent->offer->node_id, - &parity); + sent->offer->node_id); if (!sent->path) - return connect_direct(cmd, sent->offer->node_id, parity, + return connect_direct(cmd, sent->offer->node_id, sendinvreq_after_connect, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent); @@ -1065,7 +976,6 @@ force_payer_secret(struct command *cmd, const struct secret *payer_secret) { struct sha256 merkle, sha; - enum nodeid_parity parity; secp256k1_keypair kp; u8 *msg; const u8 *p; @@ -1074,7 +984,7 @@ force_payer_secret(struct command *cmd, if (secp256k1_keypair_create(secp256k1_ctx, &kp, payer_secret->data) != 1) return command_fail(cmd, LIGHTNINGD, "Bad payer_secret"); - invreq->payer_key = tal(invreq, struct point32); + invreq->payer_key = tal(invreq, struct pubkey); /* Docs say this only happens if arguments are invalid! */ if (secp256k1_keypair_pub(secp256k1_ctx, &invreq->payer_key->pubkey, @@ -1107,10 +1017,9 @@ force_payer_secret(struct command *cmd, } sent->path = path_to_node(sent, cmd->plugin, - sent->offer->node_id, - &parity); + sent->offer->node_id); if (!sent->path) - return connect_direct(cmd, sent->offer->node_id, parity, + return connect_direct(cmd, sent->offer->node_id, sendinvreq_after_connect, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent); @@ -1384,7 +1293,6 @@ static struct command_result *createinvoice_done(struct command *cmd, { const jsmntok_t *invtok = json_get_member(buf, result, "bolt12"); char *fail; - enum nodeid_parity parity; /* Replace invoice with signed one */ tal_free(sent->inv); @@ -1405,10 +1313,9 @@ static struct command_result *createinvoice_done(struct command *cmd, } sent->path = path_to_node(sent, cmd->plugin, - sent->offer->node_id, - &parity); + sent->offer->node_id); if (!sent->path) - return connect_direct(cmd, sent->offer->node_id, parity, + return connect_direct(cmd, sent->offer->node_id, sendinvoice_after_connect, sent); return sendinvoice_after_connect(cmd, NULL, NULL, sent); @@ -1585,7 +1492,7 @@ static struct command_result *json_sendinvoice(struct command *cmd, * - MUST set `node_id` to the id of the node to send payment to. * - MUST set `description` the same as the offer. */ - sent->inv->node_id = tal(sent->inv, struct point32); + sent->inv->node_id = tal(sent->inv, struct pubkey); sent->inv->node_id->pubkey = local_id.pubkey; sent->inv->description @@ -1738,34 +1645,23 @@ static struct command_result *json_rawrequest(struct command *cmd, { struct sent *sent = tal(cmd, struct sent); u32 *timeout; - struct node_id *node_id; - struct point32 node_id32; - enum nodeid_parity parity; + struct pubkey *node_id; if (!param(cmd, buffer, params, p_req("invreq", param_invreq, &sent->invreq), - p_req("nodeid", param_node_id, &node_id), + p_req("nodeid", param_pubkey, &node_id), p_opt_def("timeout", param_number, &timeout, 60), NULL)) return command_param_failed(); - if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &node_id32.pubkey, - node_id->k, sizeof(node_id->k))) - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid nodeid"); - /* This is how long we'll wait for a reply for. */ sent->wait_timeout = *timeout; sent->cmd = cmd; sent->offer = NULL; - sent->path = path_to_node(sent, cmd->plugin, - &node_id32, - &parity); + sent->path = path_to_node(sent, cmd->plugin, node_id); if (!sent->path) { - /* We *do* know parity: they gave it to us! */ - parity = node_id->k[0]; - return connect_direct(cmd, &node_id32, parity, + return connect_direct(cmd, node_id, sendinvreq_after_connect, sent); } diff --git a/plugins/offers.c b/plugins/offers.c index 6cce43f80..e813b4813 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -17,7 +17,7 @@ #include #include -struct point32 id; +struct pubkey id; u16 cltv_final; bool offers_enabled; @@ -390,7 +390,7 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer } if (offer->node_id) - json_add_point32(js, "node_id", offer->node_id); + json_add_pubkey(js, "node_id", offer->node_id); else valid = false; @@ -556,7 +556,7 @@ static void json_add_b12_invoice(struct json_stream *js, } if (invoice->payer_key) - json_add_point32(js, "payer_key", invoice->payer_key); + json_add_pubkey(js, "payer_key", invoice->payer_key); if (invoice->payer_info) json_add_hex_talarr(js, "payer_info", invoice->payer_info); if (invoice->payer_note) @@ -644,7 +644,7 @@ static void json_add_b12_invoice(struct json_stream *js, } /* invoice_decode checked these */ - json_add_point32(js, "node_id", invoice->node_id); + json_add_pubkey(js, "node_id", invoice->node_id); json_add_bip340sig(js, "signature", invoice->signature); json_add_bool(js, "valid", valid); @@ -686,7 +686,7 @@ static void json_add_invoice_request(struct json_stream *js, json_add_u32(js, "recurrence_start", *invreq->recurrence_start); if (invreq->payer_key) - json_add_point32(js, "payer_key", invreq->payer_key); + json_add_pubkey(js, "payer_key", invreq->payer_key); else { json_add_string(js, "warning_invoice_request_missing_payer_key", "invoice_request requires payer_key"); diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index b59586d9d..b66f0894d 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -136,15 +136,14 @@ static void set_recurring_inv_expiry(struct tlv_invoice *inv, u64 last_pay) /* We rely on label forms for uniqueness. */ static void json_add_label(struct json_stream *js, const struct sha256 *offer_id, - const struct point32 *payer_key, + const struct pubkey *payer_key, const u32 counter) { char *label; label = tal_fmt(tmpctx, "%s-%s-%u", type_to_string(tmpctx, struct sha256, offer_id), - type_to_string(tmpctx, struct point32, - payer_key), + type_to_string(tmpctx, struct pubkey, payer_key), counter); json_add_string(js, "label", label); } @@ -425,7 +424,7 @@ static struct command_result *check_previous_invoice(struct command *cmd, */ static bool check_payer_sig(struct command *cmd, const struct tlv_invoice_request *invreq, - const struct point32 *payer_key, + const struct pubkey *payer_key, const struct bip340sig *sig) { struct sha256 merkle, sighash; @@ -775,7 +774,7 @@ static struct command_result *listoffers_done(struct command *cmd, /* FIXME: Insert paths and payinfo */ ir->inv->issuer = tal_dup_talarr(ir->inv, char, ir->offer->issuer); - ir->inv->node_id = tal_dup(ir->inv, struct point32, ir->offer->node_id); + ir->inv->node_id = tal_dup(ir->inv, struct pubkey, ir->offer->node_id); /* BOLT-offers #12: * - MUST set (or not set) `quantity` exactly as the invoice_request * did. @@ -786,7 +785,7 @@ static struct command_result *listoffers_done(struct command *cmd, /* BOLT-offers #12: * - MUST set `payer_key` exactly as the invoice_request did. */ - ir->inv->payer_key = tal_dup(ir->inv, struct point32, + ir->inv->payer_key = tal_dup(ir->inv, struct pubkey, ir->invreq->payer_key); /* BOLT-offers #12: diff --git a/plugins/offers_offer.c b/plugins/offers_offer.c index 520513dad..51da8a536 100644 --- a/plugins/offers_offer.c +++ b/plugins/offers_offer.c @@ -405,7 +405,7 @@ struct command_result *json_offer(struct command *cmd, = tal_dup_arr(offer, char, issuer, strlen(issuer), 0); } - offer->node_id = tal_dup(offer, struct point32, &id); + offer->node_id = tal_dup(offer, struct pubkey, &id); /* If they specify a different currency, warn if we can't * convert it! */ @@ -469,7 +469,7 @@ struct command_result *json_offerout(struct command *cmd, offer->issuer = tal_dup_arr(offer, char, issuer, strlen(issuer), 0); - offer->node_id = tal_dup(offer, struct point32, &id); + offer->node_id = tal_dup(offer, struct pubkey, &id); req = jsonrpc_request_start(cmd->plugin, cmd, "createoffer", check_result, forward_error, diff --git a/plugins/offers_offer.h b/plugins/offers_offer.h index a0e436ac2..b815dc1cb 100644 --- a/plugins/offers_offer.h +++ b/plugins/offers_offer.h @@ -3,7 +3,7 @@ #include "config.h" #include -extern struct point32 id; +extern struct pubkey id; extern bool offers_enabled; struct command_result *json_offer(struct command *cmd, diff --git a/plugins/pay.c b/plugins/pay.c index 7c8c1f547..e1dafb64c 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1103,10 +1103,8 @@ static struct command_result *json_pay(struct command *cmd, } else invmsat = NULL; - /* FIXME: gossmap should store as point32 */ p->destination = tal(p, struct node_id); - gossmap_guess_node_id(get_gossmap(cmd->plugin), b12->node_id, - p->destination); + node_id_from_pubkey(p->destination, b12->node_id); p->payment_hash = tal_dup(p, struct sha256, b12->payment_hash); if (b12->recurrence_counter && !label) return command_fail( diff --git a/tests/test_pay.py b/tests/test_pay.py index ac1886190..4cece70a0 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4385,7 +4385,7 @@ def test_offer_needs_option(node_factory): l1.rpc.call('fetchinvoice', {'offer': 'aaaa'}) # Decode still works though - assert l1.rpc.decode('lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqyys5qq7ypnwgkvdr57yzh6h92zg3qctvrm7w38djg67kzcm4yeg8vc4cq633uzqaxlsxzxergsrav494jjrpuy9hcldjeglha57lxvz20fhha6hjwhv69nnzwzjsajntyf0c4z8h9e70dfdlfq8jdvc9rdht8vr955udtg')['valid'] + assert l1.rpc.decode('lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqyys5qq7yypxdeze35wncs2l2u4gfzyrpds00e6yakfrt6ctrw5n9qanzhqr2x8sgp3lqxpxd82j87j67wyff9cd9msgagq8hveftdkx5t3e98gj2x7ac99hhwlpj9yvj79yz3l8gdlmdmhq47ct9pkedfd8naksd8f8gpar')['valid'] def test_offer(node_factory, bitcoind): @@ -5329,13 +5329,13 @@ def test_payerkey(node_factory): """payerkey calculation should not change across releases!""" nodes = node_factory.get_nodes(7) - expected_keys = ["294ec1cd3f100947fe859d71a42cb87932e36e7771abf2d50b02a7a92be8e4d5", - "6a4a3b6b0c694da6f14629ca5140713fc703591a6d8aae5c79ba9b5556fc5723", - "defd2b1f3004b0145351f469f34512c6fa4d02fe891a977bafdb34fe7b73ea48", - "eccb00c0a3c760465bb69a6297d7cfa5bcbd989d5a88e435bd8d6e4c723013cd", - "1b4bfa652f0df7498d734b0ca888b4e3b07f59e1a974ec7d4a9d6046e8e5ab92", - "fc91d60b061e517f9182e3e40ea14c27df520c51db204f1409ff50e5cf9a5e4d", - "a3bbda0137722ba62207b9d3e5e6cc2a11e58480f801892093e01383aacb7fb2"] + expected_keys = ["02294ec1cd3f100947fe859d71a42cb87932e36e7771abf2d50b02a7a92be8e4d5", + "026a4a3b6b0c694da6f14629ca5140713fc703591a6d8aae5c79ba9b5556fc5723", + "03defd2b1f3004b0145351f469f34512c6fa4d02fe891a977bafdb34fe7b73ea48", + "03eccb00c0a3c760465bb69a6297d7cfa5bcbd989d5a88e435bd8d6e4c723013cd", + "021b4bfa652f0df7498d734b0ca888b4e3b07f59e1a974ec7d4a9d6046e8e5ab92", + "03fc91d60b061e517f9182e3e40ea14c27df520c51db204f1409ff50e5cf9a5e4d", + "03a3bbda0137722ba62207b9d3e5e6cc2a11e58480f801892093e01383aacb7fb2"] for n, k in zip(nodes, expected_keys): b12 = n.rpc.createinvoicerequest('lnr1qvsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcyyrjjthf4rh99n7equvlrzrlalcacxj4y9hgzxc79yrntrth6mp3nkvssy5mac4pkfq2m3gq4ttajwh097s')['bolt12'] diff --git a/wire/bolt12_exp_wire.csv b/wire/bolt12_exp_wire.csv index 4b0ce8519..440ce32b9 100644 --- a/wire/bolt12_exp_wire.csv +++ b/wire/bolt12_exp_wire.csv @@ -31,7 +31,7 @@ tlvtype,offer,recurrence_base,28 tlvdata,offer,recurrence_base,start_any_period,byte, tlvdata,offer,recurrence_base,basetime,tu64, tlvtype,offer,node_id,30 -tlvdata,offer,node_id,node_id,point32, +tlvdata,offer,node_id,node_id,point, tlvtype,offer,send_invoice,54 tlvtype,offer,refund_for,34 tlvdata,offer,refund_for,refunded_payment_hash,sha256, @@ -57,7 +57,7 @@ tlvdata,invoice_request,recurrence_counter,counter,tu32, tlvtype,invoice_request,recurrence_start,68 tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvtype,invoice_request,payer_key,38 -tlvdata,invoice_request,payer_key,key,point32, +tlvdata,invoice_request,payer_key,key,point, tlvtype,invoice_request,payer_note,39 tlvdata,invoice_request,payer_note,note,utf8,... tlvtype,invoice_request,payer_info,50 @@ -85,20 +85,19 @@ tlvdata,invoice,blinded_capacities,incoming_msat,u64,... tlvtype,invoice,issuer,20 tlvdata,invoice,issuer,issuer,utf8,... tlvtype,invoice,node_id,30 -tlvdata,invoice,node_id,node_id,point32, +tlvdata,invoice,node_id,node_id,point, tlvtype,invoice,quantity,32 tlvdata,invoice,quantity,quantity,tu64, tlvtype,invoice,refund_for,34 tlvdata,invoice,refund_for,refunded_payment_hash,sha256, tlvtype,invoice,recurrence_counter,36 tlvdata,invoice,recurrence_counter,counter,tu32, -tlvtype,invoice,send_invoice,54 tlvtype,invoice,recurrence_start,68 tlvdata,invoice,recurrence_start,period_offset,tu32, tlvtype,invoice,recurrence_basetime,64 tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvtype,invoice,payer_key,38 -tlvdata,invoice,payer_key,key,point32, +tlvdata,invoice,payer_key,key,point, tlvtype,invoice,payer_note,39 tlvdata,invoice,payer_note,note,utf8,... tlvtype,invoice,created_at,40 @@ -115,6 +114,7 @@ tlvtype,invoice,payer_info,50 tlvdata,invoice,payer_info,blob,byte,... tlvtype,invoice,refund_signature,52 tlvdata,invoice,refund_signature,payer_signature,bip340sig, +tlvtype,invoice,send_invoice,54 tlvtype,invoice,replace_invoice,56 tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvtype,invoice,signature,240 @@ -123,6 +123,8 @@ subtype,blinded_payinfo subtypedata,blinded_payinfo,fee_base_msat,u32, subtypedata,blinded_payinfo,fee_proportional_millionths,u32, subtypedata,blinded_payinfo,cltv_expiry_delta,u16, +subtypedata,blinded_payinfo,htlc_minimum_msat,u64, +subtypedata,blinded_payinfo,htlc_maximum_msat,u64, subtypedata,blinded_payinfo,flen,u16, subtypedata,blinded_payinfo,features,byte,flen subtype,fallback_address diff --git a/wire/bolt12_wire.csv b/wire/bolt12_wire.csv index 4b0ce8519..440ce32b9 100644 --- a/wire/bolt12_wire.csv +++ b/wire/bolt12_wire.csv @@ -31,7 +31,7 @@ tlvtype,offer,recurrence_base,28 tlvdata,offer,recurrence_base,start_any_period,byte, tlvdata,offer,recurrence_base,basetime,tu64, tlvtype,offer,node_id,30 -tlvdata,offer,node_id,node_id,point32, +tlvdata,offer,node_id,node_id,point, tlvtype,offer,send_invoice,54 tlvtype,offer,refund_for,34 tlvdata,offer,refund_for,refunded_payment_hash,sha256, @@ -57,7 +57,7 @@ tlvdata,invoice_request,recurrence_counter,counter,tu32, tlvtype,invoice_request,recurrence_start,68 tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvtype,invoice_request,payer_key,38 -tlvdata,invoice_request,payer_key,key,point32, +tlvdata,invoice_request,payer_key,key,point, tlvtype,invoice_request,payer_note,39 tlvdata,invoice_request,payer_note,note,utf8,... tlvtype,invoice_request,payer_info,50 @@ -85,20 +85,19 @@ tlvdata,invoice,blinded_capacities,incoming_msat,u64,... tlvtype,invoice,issuer,20 tlvdata,invoice,issuer,issuer,utf8,... tlvtype,invoice,node_id,30 -tlvdata,invoice,node_id,node_id,point32, +tlvdata,invoice,node_id,node_id,point, tlvtype,invoice,quantity,32 tlvdata,invoice,quantity,quantity,tu64, tlvtype,invoice,refund_for,34 tlvdata,invoice,refund_for,refunded_payment_hash,sha256, tlvtype,invoice,recurrence_counter,36 tlvdata,invoice,recurrence_counter,counter,tu32, -tlvtype,invoice,send_invoice,54 tlvtype,invoice,recurrence_start,68 tlvdata,invoice,recurrence_start,period_offset,tu32, tlvtype,invoice,recurrence_basetime,64 tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvtype,invoice,payer_key,38 -tlvdata,invoice,payer_key,key,point32, +tlvdata,invoice,payer_key,key,point, tlvtype,invoice,payer_note,39 tlvdata,invoice,payer_note,note,utf8,... tlvtype,invoice,created_at,40 @@ -115,6 +114,7 @@ tlvtype,invoice,payer_info,50 tlvdata,invoice,payer_info,blob,byte,... tlvtype,invoice,refund_signature,52 tlvdata,invoice,refund_signature,payer_signature,bip340sig, +tlvtype,invoice,send_invoice,54 tlvtype,invoice,replace_invoice,56 tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvtype,invoice,signature,240 @@ -123,6 +123,8 @@ subtype,blinded_payinfo subtypedata,blinded_payinfo,fee_base_msat,u32, subtypedata,blinded_payinfo,fee_proportional_millionths,u32, subtypedata,blinded_payinfo,cltv_expiry_delta,u16, +subtypedata,blinded_payinfo,htlc_minimum_msat,u64, +subtypedata,blinded_payinfo,htlc_maximum_msat,u64, subtypedata,blinded_payinfo,flen,u16, subtypedata,blinded_payinfo,features,byte,flen subtype,fallback_address diff --git a/wire/extracted_bolt12_01_recurrence.patch b/wire/extracted_bolt12_01_recurrence.patch index 186841e47..f0d524e86 100644 --- a/wire/extracted_bolt12_01_recurrence.patch +++ b/wire/extracted_bolt12_01_recurrence.patch @@ -32,13 +32,12 @@ index 726c3c0a1..a53ca3cdf 100644 tlvtype,invoice_request,payer_key,38 tlvdata,invoice_request,payer_key,key,point32, tlvtype,invoice_request,payer_note,39 -@@ -74,6 +94,13 @@ tlvtype,invoice,quantity,32 +@@ -74,6 +94,12 @@ tlvtype,invoice,quantity,32 tlvdata,invoice,quantity,quantity,tu64, tlvtype,invoice,refund_for,34 tlvdata,invoice,refund_for,refunded_payment_hash,sha256, +tlvtype,invoice,recurrence_counter,36 +tlvdata,invoice,recurrence_counter,counter,tu32, -+tlvtype,invoice,send_invoice,54 +tlvtype,invoice,recurrence_start,68 +tlvdata,invoice,recurrence_start,period_offset,tu32, +tlvtype,invoice,recurrence_basetime,64