diff --git a/common/bolt12.c b/common/bolt12.c index a783958121ff..a0c8c9f084c5 100644 --- a/common/bolt12.c +++ b/common/bolt12.c @@ -18,13 +18,13 @@ bool bolt12_chains_match(const struct bitcoin_blkid *chains, size_t max_num_chains, const struct chainparams *must_be_chain) { - /* BOLT-offers #12: + /* BOLT #12: * - if the chain for the invoice is not solely bitcoin: * - MUST specify `offer_chains` the offer is valid for. * - otherwise: - * - MAY omit `offer_chains`, implying that bitcoin is only chain. + * - SHOULD omit `offer_chains`, implying that bitcoin is only chain. */ - /* BOLT-offers #12: + /* BOLT #12: * A reader of an offer: *... * - if `offer_chains` is not set: @@ -194,7 +194,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx, if (*fail) return tal_free(offer); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an offer: * - if the offer contains any TLV fields outside the inclusive ranges: 1 to 79 and 1000000000 to 1999999999: * - MUST NOT respond to the offer. @@ -214,7 +214,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx, return tal_free(offer); } - /* BOLT-offers #12: + /* BOLT #12: * * - if `offer_amount` is set and `offer_description` is not set: * - MUST NOT respond to the offer. @@ -224,7 +224,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx, return tal_free(offer); } - /* BOLT-offers #12: + /* BOLT #12: * * - if neither `offer_issuer_id` nor `offer_paths` are set: * - MUST NOT respond to the offer. @@ -234,7 +234,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx, return tal_free(offer); } - /* BOLT-offers #12: + /* BOLT #12: * - if `num_hops` is 0 in any `blinded_path` in `offer_paths`: * - MUST NOT respond to the offer. */ @@ -287,10 +287,10 @@ struct tlv_invoice_request *invrequest_decode(const tal_t *ctx, if (*fail) return tal_free(invrequest); - /* BOLT-offers #12: + /* BOLT #12: * The reader: *... - * - MUST fail the request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 + * - MUST reject the invoice request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 */ badf = any_field_outside_range(invrequest->fields, true, 0, 159, @@ -302,9 +302,9 @@ struct tlv_invoice_request *invrequest_decode(const tal_t *ctx, return tal_free(invrequest); } - /* BOLT-offers #12: + /* BOLT #12: * - if `num_hops` is 0 in any `blinded_path` in `invreq_paths`: - * - MUST fail the request. + * - MUST reject the invoice request. */ for (size_t i = 0; i < tal_count(invrequest->invreq_paths); i++) { if (tal_count(invrequest->invreq_paths[i]->path) == 0) { @@ -346,12 +346,11 @@ struct tlv_invoice *invoice_decode_minimal(const tal_t *ctx, return NULL; } - /* BOLT-offers #12: + /* BOLT #12: * - if `invreq_chain` is not present: - * - MUST fail the request if bitcoin is not a supported chain. - * - otherwise: - * - MUST fail the request if `invreq_chain`.`chain` is not a - * supported chain. + * - MUST reject the invoice if bitcoin is not a supported chain. + * - otherwise: + * - MUST reject the invoice if `invreq_chain`.`chain` is not a supported chain. * - if `invoice_features` contains unknown _odd_ bits that are non-zero: * - MUST ignore the bit. * - if `invoice_features` contains unknown _even_ bits that are non-zero: @@ -412,7 +411,7 @@ static u64 time_change(u64 prevstart, u32 number, u64 offer_period_start(u64 basetime, size_t n, const struct recurrence *recur) { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * 1. A `time_unit` defining 0 (seconds), 1 (days), 2 (months), * 3 (years). */ @@ -437,13 +436,13 @@ void offer_period_paywindow(const struct recurrence *recurrence, u64 basetime, u64 period_idx, u64 *start, u64 *end) { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contains `recurrence_paywindow`: */ if (recurrence_paywindow) { u64 pstart = offer_period_start(basetime, period_idx, recurrence); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer has a `recurrence_basetime` or the * `recurrence_counter` is non-zero: * - SHOULD NOT send an `invreq` for a period prior to @@ -461,7 +460,7 @@ void offer_period_paywindow(const struct recurrence *recurrence, && recurrence_paywindow->seconds_after < 60) *end = pstart + 60; } else { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - otherwise: * - SHOULD NOT send an `invreq` with * `recurrence_counter` is non-zero for a period whose @@ -473,7 +472,7 @@ void offer_period_paywindow(const struct recurrence *recurrence, *start = offer_period_start(basetime, period_idx-1, recurrence); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - SHOULD NOT send an `invreq` for a period which * has already passed. */ @@ -502,7 +501,7 @@ struct tlv_invoice *invoice_decode(const tal_t *ctx, if (*fail) return tal_free(invoice); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: * - MUST reject the invoice if `invoice_amount` is not present. * - MUST reject the invoice if `invoice_created_at` is not present. @@ -526,7 +525,7 @@ struct tlv_invoice *invoice_decode(const tal_t *ctx, return tal_free(invoice); } - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `invoice_paths` is not present or is * empty. */ if (tal_count(invoice->invoice_paths) == 0) { @@ -534,7 +533,7 @@ struct tlv_invoice *invoice_decode(const tal_t *ctx, return tal_free(invoice); } - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `num_hops` is 0 in any * `blinded_path` in `invoice_paths`. */ @@ -546,7 +545,7 @@ struct tlv_invoice *invoice_decode(const tal_t *ctx, return tal_free(invoice); } - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `invoice_blindedpay` is not present. * - MUST reject the invoice if `invoice_blindedpay` does not contain exactly one `blinded_payinfo` per `invoice_paths`.`blinded_path`. */ @@ -565,7 +564,7 @@ u64 invoice_expiry(const struct tlv_invoice *invoice) { u64 expiry; - /* BOLT-offers #12: + /* BOLT #12: * - if `invoice_relative_expiry` is present: * - MUST reject the invoice if the current time since 1970-01-01 UTC * is greater than `invoice_created_at` plus `seconds_from_creation`. @@ -639,7 +638,7 @@ static void calc_offer(const u8 *tlvstream, struct sha256 *id) size_t start1, len1, start2, len2; struct sha256_ctx ctx; - /* BOLT-offers #12: + /* BOLT #12: * A writer of an offer: * - MUST NOT set any TLV fields outside the inclusive ranges: 1 to 79 and 1000000000 to 1999999999. */ @@ -681,7 +680,7 @@ static void calc_invreq(const u8 *tlvstream, struct sha256 *id) size_t start1, len1, start2, len2; struct sha256_ctx ctx; - /* BOLT-offers #12: + /* BOLT #12: * The writer: *... * - MUST NOT set any non-signature TLV fields outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 @@ -712,7 +711,7 @@ void invoice_invreq_id(const struct tlv_invoice *invoice, struct sha256 *id) } -/* BOLT-offers #12: +/* BOLT #12: * ## Requirements for Invoice Requests * * The writer: @@ -744,11 +743,11 @@ struct tlv_invoice *invoice_for_invreq(const tal_t *ctx, towire_tlv_invoice_request(&wire, invreq); - /* BOLT-offers #12: + /* BOLT #12: * A writer of an invoice: *... * - if the invoice is in response to an `invoice_request`: - * - MUST copy all non-signature fields from the `invoice_request` (including + * - MUST copy all non-signature fields from the invoice request (including * unknown fields). */ len1 = tlv_span(wire, 0, 159, &start1); @@ -765,7 +764,7 @@ struct tlv_invoice *invoice_for_invreq(const tal_t *ctx, bool is_bolt12_signature_field(u64 typenum) { - /* BOLT-offers #12: + /* BOLT #12: * Each form is signed using one or more *signature TLV elements*: TLV * types 240 through 1000 (inclusive). */ return typenum >= 240 && typenum <= 1000; diff --git a/common/bolt12.h b/common/bolt12.h index 73d1da3e7b8c..0ad354649c00 100644 --- a/common/bolt12.h +++ b/common/bolt12.h @@ -5,7 +5,7 @@ struct feature_set; -/* BOLT-offers #12: +/* BOLT #12: * - if `invoice_relative_expiry` is present: * - MUST reject the invoice if the current time since 1970-01-01 UTC * is greater than `invoice_created_at` plus `seconds_from_creation`. @@ -161,7 +161,7 @@ struct tlv_invoice_request *invoice_request_for_offer(const tal_t *ctx, struct tlv_invoice *invoice_for_invreq(const tal_t *ctx, const struct tlv_invoice_request *invreq); -/* BOLT-offers #12: +/* BOLT #12: * Each form is signed using one or more *signature TLV elements*: TLV * types 240 through 1000 (inclusive). */ bool is_bolt12_signature_field(u64 typenum); diff --git a/common/bolt12_merkle.c b/common/bolt12_merkle.c index c4e01bc4b23e..6ca21896a29d 100644 --- a/common/bolt12_merkle.c +++ b/common/bolt12_merkle.c @@ -10,7 +10,7 @@ #define SUPERVERBOSE(...) #endif -/* BOLT-offers #12: +/* BOLT #12: * Each form is signed using one or more *signature TLV elements*: TLV * types 240 through 1000 (inclusive). */ @@ -39,7 +39,7 @@ static void sha256_update_tlvfield(struct sha256_ctx *ctx, sha256_update(ctx, field->value, field->length); } -/* BOLT-offers #12: +/* BOLT #12: * Thus we define H(`tag`,`msg`) as SHA256(SHA256(`tag`) || SHA256(`tag`) || `msg`)*/ /* Create a sha256_ctx which has the tag part done. */ static void h_simpletag_ctx(struct sha256_ctx *sctx, const char *tag) @@ -55,7 +55,7 @@ static void h_simpletag_ctx(struct sha256_ctx *sctx, const char *tag) } -/* BOLT-offers #12: +/* BOLT #12: * The Merkle tree's leaves are, in TLV-ascending order for each tlv: * 1. The H("LnLeaf",tlv). * 2. The H("LnNonce"||first-tlv,tlv-type) where first-tlv is the numerically-first TLV entry in the stream, and tlv-type is the "type" field (1-9 bytes) of the current tlv. @@ -108,7 +108,7 @@ static void calc_lnleaf(const struct tlv_field *field, struct sha256 *hash) SUPERVERBOSE(") -> %s\n", fmt_sha256(tmpctx, hash)); } -/* BOLT-offers #12: +/* BOLT #12: * The Merkle tree inner nodes are H("LnBranch", lesser-SHA256||greater-SHA256) */ static struct sha256 *merkle_pair(const tal_t *ctx, @@ -193,7 +193,7 @@ void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle) tal_free(arr); } -/* BOLT-offers #12: +/* BOLT #12: * All signatures are created as per * [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) * and tagged as recommended there. Thus we define H(`tag`,`msg`) as diff --git a/common/iso4217.h b/common/iso4217.h index 96f34221de5e..e57c5baae054 100644 --- a/common/iso4217.h +++ b/common/iso4217.h @@ -3,10 +3,10 @@ #include "config.h" #include -/* BOLT-offers #12: +/* BOLT #12: * - * - MUST specify `offer_currency` `iso4217` as an ISO 4712 three-letter code. - * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4712 + * - MUST specify `offer_currency` `iso4217` as an ISO 4217 three-letter code. + * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4217 * exponent (e.g. USD cents). */ struct iso4217_name_and_divisor { diff --git a/common/onion_message_parse.c b/common/onion_message_parse.c index 847a58d1e5df..9becf60d136c 100644 --- a/common/onion_message_parse.c +++ b/common/onion_message_parse.c @@ -57,7 +57,7 @@ static bool decrypt_forwarding_onionmsg(const struct pubkey *path_key, if (encmsg->path_id) return false; - /* BOLT-offers #4: + /* BOLT #4: * - if it is not the final node according to the onion encryption: *... * - if `next_node_id` is present: diff --git a/common/test/run-bolt12-encode-test.c b/common/test/run-bolt12-encode-test.c index c471dd386926..e7de25fdd381 100644 --- a/common/test/run-bolt12-encode-test.c +++ b/common/test/run-bolt12-encode-test.c @@ -245,9 +245,8 @@ int main(int argc, char *argv[]) print_valid_offer(offer, "with blinded path via Bob (0x424242...), path_key 020202...", "path is [id=02020202..., enc=0x00*16], [id=02020202..., enc=0x11*8]", NULL); - /* BOLT-offers #12: + /* BOLT #12: * - if it includes `offer_paths`: - * - SHOULD ignore any invoice_request which does not use the path. * - MAY set `offer_issuer_id`. * - otherwise: * - MUST set `offer_issuer_id` to the node's public key to request the invoice from. @@ -386,7 +385,7 @@ int main(int argc, char *argv[]) "Malformed: invalid offer_issuer_id"); /* Now these are simply invalid, not bad encodings */ - /* BOLT-offers #12: + /* BOLT #12: * A reader of an offer: * - if the offer contains any TLV fields outside the inclusive ranges: 1 to 79 and 1000000000 to 1999999999: * - MUST NOT respond to the offer. @@ -416,7 +415,7 @@ int main(int argc, char *argv[]) offer->offer_features = tal_arr(offer, u8, 0); set_feature_bit(&offer->offer_features, 22); - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_features` contains unknown _even_ bits that are non-zero: * - MUST NOT respond to the offer. * - SHOULD indicate the unknown bit to the user. @@ -424,9 +423,11 @@ int main(int argc, char *argv[]) print_invalid_offer(offer, "Contains unknown feature 22"); offer->offer_features = NULL; - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_amount` is set and `offer_description` is not set: * - MUST NOT respond to the offer. + * - if `offer_currency` is set and `offer_amount` is not set: + * - MUST NOT respond to the offer. * - if neither `offer_issuer_id` nor `offer_paths` are set: * - MUST NOT respond to the offer. */ @@ -434,6 +435,10 @@ int main(int argc, char *argv[]) print_invalid_offer(offer, "Missing offer_description and offer_amount"); offer->offer_description = tal_utf8(tmpctx, "Test vectors"); + offer->offer_currency = tal_utf8(offer, "USD"); + print_invalid_offer(offer, "Missing offer_amount with offer_currency"); + offer->offer_currency = NULL; + offer->offer_issuer_id = NULL; print_invalid_offer(offer, "Missing offer_issuer_id and no offer_path"); diff --git a/common/test/run-bolt12-format-string-test.c b/common/test/run-bolt12-format-string-test.c index 4f325d9637af..dc8384750a09 100644 --- a/common/test/run-bolt12-format-string-test.c +++ b/common/test/run-bolt12-format-string-test.c @@ -115,21 +115,21 @@ int main(int argc, char *argv[]) common_setup(argv[0]); offer = tlv_offer_new(tmpctx); - /* BOLT-offers #12: + /* BOLT #12: * A writer of an offer: * - MUST NOT set any TLV fields outside the inclusive ranges: 1 to 79 and 1000000000 to 1999999999. * - if the chain for the invoice is not solely bitcoin: * - MUST specify `offer_chains` the offer is valid for. * - otherwise: - * - MAY omit `offer_chains`, implying that bitcoin is only chain. + * - SHOULD omit `offer_chains`, implying that bitcoin is only chain. * - if a specific minimum `offer_amount` is required for successful payment: * - MUST set `offer_amount` to the amount expected (per item). * - if the currency for `offer_amount` is that of all entries in `chains`: - * - MUST specify `amount` in multiples of the minimum lightning-payable unit + * - MUST specify `offer_amount` in multiples of the minimum lightning-payable unit * (e.g. milli-satoshis for bitcoin). * - otherwise: - * - MUST specify `offer_currency` `iso4217` as an ISO 4712 three-letter code. - * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4712 + * - MUST specify `offer_currency` `iso4217` as an ISO 4217 three-letter code. + * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4217 * exponent (e.g. USD cents). * - MUST set `offer_description` to a complete description of the purpose * of the payment. @@ -150,7 +150,6 @@ int main(int argc, char *argv[]) * - otherwise: * - MAY include `offer_paths`. * - if it includes `offer_paths`: - * - SHOULD ignore any invoice_request which does not use the path. * - MAY set `offer_issuer_id`. * - otherwise: * - MUST set `offer_issuer_id` to the node's public key to request the invoice from. diff --git a/common/test/run-bolt12_merkle.c b/common/test/run-bolt12_merkle.c index 36c31627b246..43265ef4d74f 100644 --- a/common/test/run-bolt12_merkle.c +++ b/common/test/run-bolt12_merkle.c @@ -97,7 +97,7 @@ static u8 *tlv(u64 type, const void *contents, size_t len) return ret; } -/* BOLT-offers #12: +/* BOLT #12: * Thus we define H(`tag`,`msg`) as SHA256(SHA256(`tag`) || * SHA256(`tag`) || `msg`) */ @@ -329,7 +329,7 @@ int main(int argc, char *argv[]) tlv_update_fields(invreq, tlv_invoice_request, &invreq->fields); merkle_tlv(invreq->fields, &test_m); - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `signature`.`sig` as detailed in [Signature Calculation](#signature-calculation) using the `invreq_payer_id`. */ invreq->signature = tal(invreq, struct bip340sig); diff --git a/connectd/onion_message.c b/connectd/onion_message.c index cd11aa0bcfc2..09940e855b59 100644 --- a/connectd/onion_message.c +++ b/connectd/onion_message.c @@ -84,7 +84,7 @@ static const char *handle_onion(const tal_t *ctx, assert(next_onion_msg); - /* BOLT-offers #4: + /* BOLT #4: * - if it is not the final node according to the onion encryption: *... * - if `next_node_id` is present: diff --git a/devtools/bolt12-cli.c b/devtools/bolt12-cli.c index a4b7b39fa858..69f6a67cad01 100644 --- a/devtools/bolt12-cli.c +++ b/devtools/bolt12-cli.c @@ -94,15 +94,15 @@ static bool print_offer_amount(const struct bitcoin_blkid *chains, unsigned int minor_unit; bool ok = true; - /* BOLT-offers #12: + /* BOLT #12: * - if a specific minimum `offer_amount` is required for successful payment: * - MUST set `offer_amount` to the amount expected (per item). * - if the currency for `offer_amount` is that of all entries in `chains`: - * - MUST specify `amount` in multiples of the minimum lightning-payable unit + * - MUST specify `offer_amount` in multiples of the minimum lightning-payable unit * (e.g. milli-satoshis for bitcoin). * - otherwise: - * - MUST specify `offer_currency` `iso4217` as an ISO 4712 three-letter code. - * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4712 + * - MUST specify `offer_currency` `iso4217` as an ISO 4217 three-letter code. + * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4217 * exponent (e.g. USD cents). * - MUST set `offer_description` to a complete description of the purpose * of the payment. @@ -183,7 +183,7 @@ static bool print_recurrance(const struct recurrence *recurrence, const char *unit; bool ok = true; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * Thus, each offer containing a recurring payment has: * 1. A `time_unit` defining 0 (seconds), 1 (days), 2 (months), * 3 (years). @@ -363,7 +363,7 @@ static void print_relative_expiry(u64 *created_at, u32 *relative) if (!created_at) return; - /* BOLT-offers #12: + /* BOLT #12: * - if `invoice_relative_expiry` is present: * - MUST reject the invoice if the current time since 1970-01-01 UTC * is greater than `invoice_created_at` plus `seconds_from_creation`. @@ -453,7 +453,7 @@ static u64 get_offer_type(const char *name) const char *name; u64 val; } map[] = { - /* BOLT-offers #12: + /* BOLT #12: * 1. `tlv_stream`: `offer` * 2. types: * 1. type: 2 (`offer_chains`) @@ -501,7 +501,7 @@ static u64 get_offer_type(const char *name) { "offer_issuer", 18 }, { "offer_quantity_max", 20 }, { "offer_issuer_id", 22 }, - /* BOLT-offers #12: + /* BOLT #12: * 1. `tlv_stream`: `invoice_request` * 2. types: * 1. type: 0 (`invreq_metadata`) @@ -581,7 +581,7 @@ static u64 get_offer_type(const char *name) { "invreq_paths", 90 }, { "invreq_bip_353_name", 91 }, { "signature", 240 }, - /* BOLT-offers #12: + /* BOLT #12: * 1. `tlv_stream`: `invoice` * 2. types: * 1. type: 0 (`invreq_metadata`) @@ -833,7 +833,7 @@ int main(int argc, char *argv[]) *offer->offer_amount); if (offer->offer_description) well_formed &= print_utf8("offer_description", offer->offer_description); - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_amount` is set and `offer_description` is not set: * - MUST NOT respond to the offer. */ @@ -853,7 +853,7 @@ int main(int argc, char *argv[]) print_u64("offer_quantity_max", *offer->offer_quantity_max); if (offer->offer_issuer_id) print_node_id("offer_issuer_id", offer->offer_issuer_id); - /* BOLT-offers #12: + /* BOLT #12: * * - if neither `offer_issuer_id` nor `offer_paths` are set: * - MUST NOT respond to the offer. diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 22a2af43f90e..18ef0b5ee669 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -1647,7 +1647,7 @@ static void add_stub_blindedpath(const tal_t *ctx, inv->invoice_paths = tal_arr(inv, struct blinded_path *, 1); inv->invoice_paths[0] = tal_steal(inv->invoice_paths, path); - /* BOLT-offers #12: + /* BOLT #12: * - MUST include `invoice_paths` containing one or more paths to the node. * - MUST specify `invoice_paths` in order of most-preferred to least-preferred if it has a preference. * - MUST include `invoice_blindedpay` with exactly one `blinded_payinfo` for each `blinded_path` in `paths`, in order. @@ -1745,7 +1745,7 @@ static struct command_result *json_createinvoice(struct command *cmd, "Unparsable invoice '%s': %s", invstring, fail); - /* BOLT-offers #12: + /* BOLT #12: * A writer of an invoice: *... * - MUST include `invoice_paths` containing one or more paths @@ -1777,7 +1777,7 @@ static struct command_result *json_createinvoice(struct command *cmd, } else local_offer_id = NULL; - /* BOLT-offers #12: + /* BOLT #12: * A writer of an invoice: *... * - MUST set `invoice_amount` to the minimum amount it will diff --git a/lightningd/offer.c b/lightningd/offer.c index 4f66401ebb83..e15a591fa92d 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -314,7 +314,7 @@ static struct command_result *prev_payment(struct command *cmd, if (!inv->invreq_recurrence_counter) continue; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence_base` with * `start_any_period` non-zero: * - MUST include `recurrence_start` @@ -500,7 +500,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd, if (command_check_only(cmd)) return command_check_done(cmd); - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `signature`.`sig` as detailed in * [Signature Calculation](#signature-calculation) using the `invreq_payer_id`. */ diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index 85f05f5f3fe6..fd912a6a18fe 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -139,9 +139,9 @@ static struct command_result *handle_error(struct command *cmd, return command_hook_success(cmd); } -/* BOLT-offers #12: +/* BOLT #12: * - if the invoice is a response to an `invoice_request`: - * - MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the `invoice_request`. + * - MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the invoice request. */ static bool invoice_matches_request(struct command *cmd, const u8 *invbin, @@ -210,18 +210,18 @@ static struct command_result *handle_invreq_response(struct command *cmd, return command_hook_success(cmd); } - /* BOLT-offers #12: + /* BOLT #12: * - if the invoice is a response to an `invoice_request`: * - MUST reject the invoice if all fields in ranges 0 to 159 and * 1000000000 to 2999999999 (inclusive) do not exactly match the - * `invoice_request`. + * invoice request. */ if (!invoice_matches_request(cmd, invbin, sent->invreq)) { badfield = "invoice_request match"; goto badinv; } - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: * - MUST reject the invoice if `invoice_amount` is not present. * - MUST reject the invoice if `invoice_created_at` is not present. @@ -244,12 +244,12 @@ static struct command_result *handle_invreq_response(struct command *cmd, badfield = "invoice_node_id"; goto badinv; } - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_issuer_id` is present (invoice_request for an offer): * - MUST reject the invoice if `invoice_node_id` is not equal to `offer_issuer_id` * - otherwise, if `offer_paths` is present (invoice_request for an offer without id): * - MUST reject the invoice if `invoice_node_id` is not equal to the final - * `blinded_node_id` it sent the `invoice_request` to. + * `blinded_node_id` it sent the invoice request to. */ /* Either way, we save the expected id in issuer_key */ if (!pubkey_eq(inv->invoice_node_id, sent->issuer_key)) { @@ -257,7 +257,7 @@ static struct command_result *handle_invreq_response(struct command *cmd, goto badinv; } - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `signature` is not a valid signature * using `invoice_node_id` as described in [Signature Calculation] */ @@ -290,7 +290,7 @@ static struct command_result *handle_invreq_response(struct command *cmd, } else expected_amount = NULL; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence`: * - MUST reject the invoice if `recurrence_basetime` is not set. */ @@ -302,7 +302,7 @@ static struct command_result *handle_invreq_response(struct command *cmd, out = jsonrpc_stream_success(sent->cmd); json_add_string(out, "invoice", invoice_encode(tmpctx, inv)); json_object_start(out, "changes"); - /* BOLT-offers #12: + /* BOLT #12: * - SHOULD confirm authorization if `invoice_amount`.`msat` is not within * the amount range authorized. */ @@ -586,11 +586,11 @@ static struct command_result *try_establish(struct command *cmd, if (!gossmap_scidd_pubkey(get_gossmap(cmd->plugin), &first)) return establish_path_fail(cmd, "Cannot resolve scidd", epaths); target = first.pubkey; - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_issuer_id` is present (invoice_request for an offer): * - MUST reject the invoice if `invoice_node_id` is not equal to `offer_issuer_id` * - otherwise, if `offer_paths` is present (invoice_request for an offer without id): - * - MUST reject the invoice if `invoice_node_id` is not equal to the final `blinded_node_id` it sent the `invoice_request` to. + * - MUST reject the invoice if `invoice_node_id` is not equal to the final `blinded_node_id` it sent the invoice request to. */ if (epaths->sent->offer && !epaths->sent->offer->offer_issuer_id) epaths->sent->issuer_key = &bpath->path[tal_count(bpath->path)-1]->blinded_node_id; @@ -699,7 +699,7 @@ static struct command_result *invreq_done(struct command *cmd, if (sent->invreq->invreq_recurrence_start) period_idx += *sent->invreq->invreq_recurrence_start; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence_limit`: * - MUST NOT send an `invoice_request` for a period greater * than `max_period` @@ -712,7 +712,7 @@ static struct command_result *invreq_done(struct command *cmd, period_idx, *sent->invreq->offer_recurrence_limit); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - SHOULD NOT send an `invoice_request` for a period which has * already passed. */ @@ -854,15 +854,15 @@ struct command_result *json_fetchinvoice(struct command *cmd, /* This is NULL if offer_issuer_id is missing, and set by try_establish */ sent->issuer_key = sent->offer->offer_issuer_id; - /* BOLT-offers #12: - * - SHOULD not respond to an offer if the current time is after - * `offer_absolute_expiry`. + /* BOLT #12: + * - if the current time is after `offer_absolute_expiry`: + * - MUST NOT respond to the offer. */ if (sent->offer->offer_absolute_expiry && time_now().ts.tv_sec > *sent->offer->offer_absolute_expiry) return command_fail(cmd, OFFER_EXPIRED, "Offer expired"); - /* BOLT-offers #12: + /* BOLT #12: * The writer: * - if it is responding to an offer: * - MUST copy all fields from the offer (including unknown fields). @@ -872,7 +872,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, invreq->invreq_recurrence_start = tal_steal(invreq, recurrence_start); invreq->invreq_quantity = tal_steal(invreq, quantity); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if `offer_amount` is not present: * - MUST specify `invreq_amount`. * - otherwise: @@ -896,7 +896,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, &msat->millisatoshis); /* Raw: tu64 */ } - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_quantity_max` is present: * - MUST set `invreq_quantity` to greater than zero. * - if `offer_quantity_max` is non-zero: @@ -921,19 +921,19 @@ struct command_result *json_fetchinvoice(struct command *cmd, "quantity parameter unnecessary"); } - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence`: */ if (invreq->offer_recurrence) { struct sha256 offer_id, tweak; u8 *tweak_input; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - for the initial request: *... * - MUST set `recurrence_counter` `counter` to 0. */ - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - for any successive requests: *... * - MUST set `recurrence_counter` `counter` to one greater @@ -947,7 +947,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Cannot set payer_metadata for recurring offers"); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence_base` with * `start_any_period` non-zero: * - MUST include `recurrence_start` @@ -972,7 +972,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "needs recurrence_label"); - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invreq_metadata` to an unpredictable series of * bytes. */ @@ -995,7 +995,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, invreq->invreq_metadata = (u8 *)tal_dup(invreq, struct sha256, &tweak); } else { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - otherwise: * - MUST NOT set `recurrence_counter`. * - MUST NOT set `recurrence_start` @@ -1011,7 +1011,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, if (payer_metadata) { invreq->invreq_metadata = tal_steal(invreq, payer_metadata); } else { - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invreq_metadata` to an unpredictable series of * bytes. */ @@ -1062,11 +1062,11 @@ struct command_result *json_fetchinvoice(struct command *cmd, "Invalid tweak for payer_id"); } - /* BOLT-offers #12: + /* BOLT #12: * * - if `offer_chains` is set: * - MUST set `invreq_chain` to one of `offer_chains` unless that - * chain is bitcoin, in which case it MAY omit `invreq_chain`. + * chain is bitcoin, in which case it SHOULD omit `invreq_chain`. * - otherwise: * - if it sets `invreq_chain` it MUST set it to bitcoin. */ @@ -1076,7 +1076,7 @@ struct command_result *json_fetchinvoice(struct command *cmd, &chainparams->genesis_blockhash); } - /* BOLT-offers #12: + /* BOLT #12: * - if it supports bolt12 invoice request features: * - MUST set `invreq_features`.`features` to the bitmap of features. */ @@ -1183,7 +1183,7 @@ static struct command_result *createinvoice_done(struct command *cmd, "Bad createinvoice response %s", fail); } - /* BOLT-offers #12: + /* BOLT #12: * - if it sends an invoice in response: * - MUST use `invreq_paths` if present, otherwise MUST use * `invreq_payer_id` as the node id to send to. @@ -1228,11 +1228,15 @@ static struct command_result *param_invreq(struct command *cmd, int badf; struct sha256 merkle, sighash; - /* BOLT-offers #12: + /* FIXME: quote is garbled, see: https://github.com/lightning/bolts/pull/1222 */ + /* BOLT #12: * - if `invreq_chain` is not present: - * - MUST fail the request if bitcoin is not a supported chain. + * - MUST reject the invoice request if bitcoin is not a supported chain. + * - if `invreq_bip_353_name` is present: + * - MUST reject the invoice request if `name` or `domain` contain any bytes which are not + * `0`-`9`, `a`-`z`, `A`-`Z`, `-`, `_` or `.`. * - otherwise: - * - MUST fail the request if `invreq_chain`.`chain` is not a + * - MUST reject the invoice request if `invreq_chain`.`chain` is not a * supported chain. */ *invreq = invrequest_decode(cmd, @@ -1245,17 +1249,17 @@ static struct command_result *param_invreq(struct command *cmd, tal_fmt(cmd, "Unparsable invoice_request: %s", fail)); - /* BOLT-offers #12: + /* BOLT #12: * The reader: - * - MUST fail the request if `invreq_payer_id` or `invreq_metadata` + * - MUST reject the invoice request if `invreq_payer_id` or `invreq_metadata` * are not present. - * - MUST fail the request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 + * - MUST reject the invoice request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 * - if `invreq_features` contains unknown _odd_ bits that are * non-zero: * - MUST ignore the bit. * - if `invreq_features` contains unknown _even_ bits that are * non-zero: - * - MUST fail the request. + * - MUST reject the invoice request. */ if (!(*invreq)->invreq_payer_id) return command_fail_badparam(cmd, name, buffer, tok, @@ -1282,8 +1286,8 @@ static struct command_result *param_invreq(struct command *cmd, badf)); } - /* BOLT-offers #12: - * - MUST fail the request if `signature` is not correct as detailed in [Signature + /* BOLT #12: + * - MUST reject the invoice request if `signature` is not correct as detailed in [Signature * Calculation](#signature-calculation) using the `invreq_payer_id`. */ merkle_tlv((*invreq)->fields, &merkle); @@ -1305,11 +1309,11 @@ static struct command_result *param_invreq(struct command *cmd, "This is based on an offer?"); } - /* BOLT-offers #12: + /* BOLT #12: * - otherwise (no `offer_issuer_id` or `offer_paths`, not a response to our offer): - * - MUST fail the request if any of the following are present: + * - MUST reject the invoice request if any of the following are present: * - `offer_chains`, `offer_features` or `offer_quantity_max`. - * - MUST fail the request if `invreq_amount` is not present. + * - MUST reject the invoice request if `invreq_amount` is not present. */ if ((*invreq)->offer_chains) return command_fail_badparam(cmd, name, buffer, tok, @@ -1324,7 +1328,7 @@ static struct command_result *param_invreq(struct command *cmd, return command_fail_badparam(cmd, name, buffer, tok, "Missing invreq_amount"); - /* BOLT-offers #12: + /* BOLT #12: * - otherwise (no `offer_issuer_id` or `offer_paths`, not a response to our offer): *... * - MAY use `offer_amount` (or `offer_currency`) for informational display to user. @@ -1366,9 +1370,9 @@ struct command_result *json_sendinvoice(struct command *cmd, sent->their_paths = sent->invreq->offer_paths; sent->direct_dest = sent->invreq->invreq_payer_id; - /* BOLT-offers #12: + /* BOLT #12: * - if the invoice is in response to an `invoice_request`: - * - MUST copy all non-signature fields from the `invoice_request` + * - MUST copy all non-signature fields from the invoice request * (including unknown fields). */ sent->inv = invoice_for_invreq(sent, sent->invreq); @@ -1376,7 +1380,7 @@ struct command_result *json_sendinvoice(struct command *cmd, /* This is how long we'll wait for a reply for. */ sent->wait_timeout = *timeout; - /* BOLT-offers #12: + /* BOLT #12: * - if `invreq_amount` is present: * - MUST set `invoice_amount` to `invreq_amount` * - otherwise: @@ -1389,7 +1393,7 @@ struct command_result *json_sendinvoice(struct command *cmd, sent->inv->invoice_amount = tal_dup(sent->inv, u64, &msat->millisatoshis); /* Raw: tlv */ - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invoice_created_at` to the number of seconds since Midnight 1 * January 1970, UTC when the invoice was created. * - MUST set `invoice_amount` to the minimum amount it will accept, in units of @@ -1401,7 +1405,7 @@ struct command_result *json_sendinvoice(struct command *cmd, /* FIXME: Support blinded paths, in which case use fake nodeid */ - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invoice_payment_hash` to the SHA256 hash of the * `payment_preimage` that will be given in return for payment. */ @@ -1410,19 +1414,16 @@ struct command_result *json_sendinvoice(struct command *cmd, sha256(sent->inv->invoice_payment_hash, &sent->inv_preimage, sizeof(sent->inv_preimage)); - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_issuer_id` is present: * - MUST set `invoice_node_id` to the `offer_issuer_id` * - otherwise, if `offer_paths` is present: - * - MUST set `invoice_node_id` to the final `blinded_node_id` on the path it received the `invoice_request` - * - otherwise: - * - MUST set `invoice_node_id` to a valid public key. + * - MUST set `invoice_node_id` to the final `blinded_node_id` on the path it received the invoice request */ - /* FIXME: Use transitory id! */ sent->inv->invoice_node_id = tal(sent->inv, struct pubkey); sent->inv->invoice_node_id->pubkey = id.pubkey; - /* BOLT-offers #12: + /* BOLT #12: * - if the expiry for accepting payment is not 7200 seconds * after `invoice_created_at`: * - MUST set `invoice_relative_expiry`.`seconds_from_creation` diff --git a/plugins/offers.c b/plugins/offers.c index 493fcf0aa95c..84d77522ddd9 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -588,7 +588,7 @@ static bool json_add_blinded_paths(struct command *cmd, } json_array_end(js); - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `invoice_blindedpay` does not contain * exactly one `blinded_payinfo` per `invoice_paths`.`blinded_path`. */ @@ -599,7 +599,7 @@ static bool json_add_blinded_paths(struct command *cmd, return false; } - /* BOLT-offers #12: + /* BOLT #12: * - if `num_hops` is 0 in any `blinded_path` in `offer_paths`: * - MUST NOT respond to the offer. */ @@ -617,7 +617,7 @@ static bool json_add_blinded_paths(struct command *cmd, static const char *recurrence_time_unit_name(u8 time_unit) { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * `time_unit` defining 0 (seconds), 1 (days), 2 (months), 3 (years). */ switch (time_unit) { @@ -685,7 +685,7 @@ static bool json_add_offer_fields(struct command *cmd, } else if (offer_amount) json_add_amount_msat(js, "offer_amount_msat", amount_msat(*offer_amount)); - /* BOLT-offers #12: + /* BOLT #12: * * - if `offer_amount` is set and `offer_description` is not set: * - MUST NOT respond to the offer. @@ -796,7 +796,7 @@ static void json_add_offer(struct command *cmd, struct json_stream *js, const st offer->offer_recurrence_paywindow, offer->offer_recurrence_limit, offer->offer_recurrence_base); - /* BOLT-offers #12: + /* BOLT #12: * - if neither `offer_issuer_id` nor `offer_paths` are set: * - MUST NOT respond to the offer. */ @@ -825,8 +825,8 @@ static bool json_add_invreq_fields(struct command *cmd, { bool valid = true; - /* BOLT-offers #12: - * - MUST fail the request if `invreq_payer_id` or `invreq_metadata` are not present. + /* BOLT #12: + * - MUST reject the invoice request if `invreq_payer_id` or `invreq_metadata` are not present. */ if (invreq_metadata) json_add_hex_talarr(js, "invreq_metadata", @@ -937,7 +937,7 @@ static bool json_add_fallbacks(struct json_stream *js, json_add_u32(js, "version", fallbacks[i]->version); json_add_hex_talarr(js, "hex", fallbacks[i]->address); - /* BOLT-offers #12: + /* BOLT #12: * - for the bitcoin chain, if the invoice specifies `invoice_fallbacks`: * - MUST ignore any `fallback_address` for which `version` is * greater than 16. @@ -1011,8 +1011,8 @@ static void json_add_invoice_request(struct command *cmd, invreq->invreq_recurrence_counter, invreq->invreq_recurrence_start); - /* BOLT-offers #12: - * - MUST fail the request if `invreq_payer_id` or `invreq_metadata` are not present. + /* BOLT #12: + * - MUST reject the invoice request if `invreq_payer_id` or `invreq_metadata` are not present. */ if (!invreq->invreq_payer_id) { json_add_string(js, "warning_missing_invreq_payer_id", @@ -1020,8 +1020,8 @@ static void json_add_invoice_request(struct command *cmd, valid = false; } - /* BOLT-offers #12: - * - MUST fail the request if `signature` is not correct as detailed + /* BOLT #12: + * - MUST reject the invoice request if `signature` is not correct as detailed * in [Signature Calculation](#signature-calculation) using the * `invreq_payer_id`. */ @@ -1101,7 +1101,7 @@ static void json_add_b12_invoice(struct command *cmd, invoice->invreq_recurrence_counter, invoice->invreq_recurrence_start); - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `invoice_paths` is not present * or is empty. * - MUST reject the invoice if `num_hops` is 0 in any `blinded_path` in `invoice_paths`. @@ -1132,7 +1132,7 @@ static void json_add_b12_invoice(struct command *cmd, valid = false; } - /* BOLT-offers #12: + /* BOLT #12: * * - if `invoice_relative_expiry` is present: * - MUST reject the invoice if the current time since 1970-01-01 UTC @@ -1154,7 +1154,7 @@ static void json_add_b12_invoice(struct command *cmd, valid = false; } - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `invoice_amount` is not present. */ if (invoice->invoice_amount) @@ -1182,7 +1182,7 @@ static void json_add_b12_invoice(struct command *cmd, valid = false; } - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer contained `recurrence`: * - MUST reject the invoice if `recurrence_basetime` is not * set. diff --git a/plugins/offers_inv_hook.c b/plugins/offers_inv_hook.c index 67fda233b28b..07bc1a7ed6b6 100644 --- a/plugins/offers_inv_hook.c +++ b/plugins/offers_inv_hook.c @@ -133,15 +133,15 @@ static struct command_result *listinvreqs_done(struct command *cmd, struct out_req *req; struct sha256 merkle, sighash; - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: *... * - if the invoice is a response to an `invoice_request`: - * - MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the `invoice_request`. + * - MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the invoice request. * - if `offer_issuer_id` is present (invoice_request for an offer): * - MUST reject the invoice if `invoice_node_id` is not equal to `offer_issuer_id` * - otherwise, if `offer_paths` is present (invoice_request for an offer without id): - * - MUST reject the invoice if `invoice_node_id` is not equal to the final `blinded_node_id` it sent the `invoice_request` to. + * - MUST reject the invoice if `invoice_node_id` is not equal to the final `blinded_node_id` it sent the invoice request to. * - otherwise (invoice_request without an offer): * - MAY reject the invoice if it cannot confirm that `invoice_node_id` is correct, out-of-band. */ @@ -165,7 +165,7 @@ static struct command_result *listinvreqs_done(struct command *cmd, /* We only save ones without offers to the db! */ assert(!inv->inv->offer_issuer_id && !inv->inv->offer_paths); - /* BOLT-offers #12: + /* BOLT #12: * - MUST reject the invoice if `signature` is not a valid signature * using `invoice_node_id` as described in [Signature * Calculation](#signature-calculation). @@ -178,7 +178,7 @@ static struct command_result *listinvreqs_done(struct command *cmd, if (!check_schnorr_sig(&sighash, &inv->inv->invoice_node_id->pubkey, inv->inv->signature)) return fail_inv(cmd, inv, "invalid invoice signature"); - /* BOLT-offers #12: + /* BOLT #12: * - SHOULD confirm authorization if `invoice_amount`.`msat` is not * within the amount range authorized. */ @@ -267,7 +267,7 @@ struct command_result *handle_invoice(struct command *cmd, invoice_invreq_id(inv->inv, &inv->invreq_id); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: * - MUST reject the invoice if `invoice_amount` is not present. * - MUST reject the invoice if `invoice_created_at` is not present. @@ -283,7 +283,7 @@ struct command_result *handle_invoice(struct command *cmd, if (!inv->inv->invoice_node_id) return fail_inv(cmd, inv, "Missing invoice_node_id"); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: *... * - if `invoice_features` contains unknown _odd_ bits that are non-zero: @@ -300,7 +300,7 @@ struct command_result *handle_invoice(struct command *cmd, bad_feature); } - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: *... * - if `invoice_relative_expiry` is present: @@ -315,7 +315,7 @@ struct command_result *handle_invoice(struct command *cmd, if (time_now().ts.tv_sec > invexpiry) return fail_inv(cmd, inv, "Expired invoice"); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: *... * - MUST reject the invoice if `invoice_paths` is not present or is empty. @@ -336,7 +336,7 @@ struct command_result *handle_invoice(struct command *cmd, return fail_inv(cmd, inv, "Mismatch between invoice_blindedpay and invoice_paths"); - /* BOLT-offers #12: + /* BOLT #12: * A reader of an invoice: *... * - For each `invoice_blindedpay`.`payinfo`: diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index 5ba04819378d..85763ea7e01d 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -121,7 +121,7 @@ test_field(struct command *cmd, return NULL; } -/* BOLT-offers-recurrence #12: +/* BOLT-recurrence #12: * - if the invoice corresponds to an offer with `recurrence`: * ... * - if it sets `relative_expiry`: @@ -247,7 +247,7 @@ static struct command_result *found_best_peer(struct command *cmd, const struct chaninfo *best, struct invreq *ir) { - /* BOLT-offers #12: + /* BOLT #12: * - MUST include `invoice_paths` containing one or more paths to the node. * - MUST specify `invoice_paths` in order of most-preferred to * least-preferred if it has a preference. @@ -287,7 +287,7 @@ static struct command_result *found_best_peer(struct command *cmd, etlvs[0]->payment_relay->fee_base_msat = best->feebase; etlvs[0]->payment_relay->fee_proportional_millionths = best->feeppm; - /* BOLT-offers #12: + /* BOLT #12: * - if the expiry for accepting payment is not 7200 seconds * after `invoice_created_at`: * - MUST set `invoice_relative_expiry` @@ -375,7 +375,7 @@ static struct command_result *check_period(struct command *cmd, if (ir->invreq->offer_recurrence_base) basetime = ir->invreq->offer_recurrence_base->basetime; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the invoice corresponds to an offer with `recurrence`: * - MUST set `recurrence_basetime` to the start of period #0 as * calculated by [Period Calculation](#offer-period-calculation). @@ -384,7 +384,7 @@ static struct command_result *check_period(struct command *cmd, period_idx = *ir->invreq->invreq_recurrence_counter; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer had `recurrence_base` and `start_any_period` * was 1: * - MUST fail the request if there is no `recurrence_start` @@ -400,14 +400,14 @@ static struct command_result *check_period(struct command *cmd, return err; period_idx += *ir->invreq->invreq_recurrence_start; - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - MUST set (or not set) `recurrence_start` exactly as the * invreq did. */ ir->inv->invreq_recurrence_start = tal_dup(ir->inv, u32, ir->invreq->invreq_recurrence_start); } else { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * * - otherwise: * - MUST fail the request if there is a `recurrence_start` @@ -420,7 +420,7 @@ static struct command_result *check_period(struct command *cmd, return err; } - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - if the offer has a `recurrence_limit`: * - MUST fail the request if the period index is greater than * `max_period`. @@ -454,7 +454,7 @@ static struct command_result *check_period(struct command *cmd, set_recurring_inv_expiry(ir->inv, paywindow_end); - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * * - if `recurrence_counter` is non-zero: *... @@ -561,9 +561,9 @@ static struct command_result *check_previous_invoice(struct command *cmd, return send_outreq(req); } -/* BOLT-offers #12: +/* BOLT #12: - * - MUST fail the request if `signature` is not correct as detailed in + * - MUST reject the invoice request if `signature` is not correct as detailed in * [Signature Calculation](#signature-calculation) using the * `invreq_payer_id`. *... @@ -588,12 +588,12 @@ static struct command_result *invreq_amount_by_quantity(struct command *cmd, { assert(ir->invreq->offer_amount); - /* BOLT-offers #12: + /* BOLT #12: * - MUST calculate the *expected amount* using the `offer_amount`: */ *raw_amt = *ir->invreq->offer_amount; - /* BOLT-offers #12: + /* BOLT #12: * - if `invreq_quantity` is present, multiply by `invreq_quantity`.`quantity`. */ if (ir->invreq->invreq_quantity) { @@ -625,12 +625,12 @@ static struct command_result *invreq_base_amount_simple(struct command *cmd, *amt = amount_msat(raw_amount); } else { - /* BOLT-offers #12: + /* BOLT #12: * * The reader: *... * - otherwise (no `offer_amount`): - * - MUST fail the request if it does not contain + * - MUST reject the invoice request if it does not contain * `invreq_amount`. */ err = invreq_must_have(cmd, ir, invreq_amount); @@ -646,9 +646,9 @@ static struct command_result *handle_amount_and_recurrence(struct command *cmd, struct invreq *ir, struct amount_msat base_inv_amount) { - /* BOLT-offers #12: + /* BOLT #12: * - if `invreq_amount` is present: - * - MUST fail the request if `invreq_amount`.`msat` is less than the + * - MUST reject the invoice request if `invreq_amount`.`msat` is less than the * *expected amount*. */ if (ir->invreq->offer_amount && ir->invreq->invreq_amount) { @@ -657,8 +657,8 @@ static struct command_result *handle_amount_and_recurrence(struct command *cmd, fmt_amount_msat(tmpctx, base_inv_amount)); } - /* BOLT-offers #12: - * - MAY fail the request if `invreq_amount`.`msat` greatly exceeds + /* BOLT #12: + * - MAY reject the invoice request if `invreq_amount`.`msat` greatly exceeds * the *expected amount*. */ /* Much == 5? Easier to divide and compare, than multiply. */ @@ -671,7 +671,7 @@ static struct command_result *handle_amount_and_recurrence(struct command *cmd, base_inv_amount = amount_msat(*ir->invreq->invreq_amount); } - /* BOLT-offers #12: + /* BOLT #12: * - if `invreq_amount` is present: * - MUST set `invoice_amount` to `invreq_amount` * - otherwise: @@ -738,7 +738,7 @@ static struct command_result *convert_currency(struct command *cmd, if (err) return err; - /* BOLT-offers #12: + /* BOLT #12: * - MUST calculate the *expected amount* using the `offer_amount`: * - if `offer_currency` is not the `invreq_chain` currency, convert to the * `invreq_chain` currency. @@ -776,9 +776,9 @@ static struct command_result *listoffers_done(struct command *cmd, struct command_result *err; struct amount_msat amt; - /* BOLT-offers #12: + /* BOLT #12: * - * - MUST fail the request if the offer fields do not exactly match a + * - MUST reject the invoice request if the offer fields do not exactly match a * valid, unexpired offer. */ if (arr->size == 0) @@ -787,12 +787,12 @@ static struct command_result *listoffers_done(struct command *cmd, /* Now, since we looked up by hash, we know that the entire offer * is faithfully mirrored in this invreq. */ - /* BOLT-offers #4: + /* BOLT #4: * - * The final recipient: + * If it is the final recipient: *... * - MUST ignore the message if the `path_id` does not match - * the blinded route it created + * the blinded route it created for this purpose */ offertok = arr + 1; if (ir->secret) { @@ -853,14 +853,14 @@ static struct command_result *listoffers_done(struct command *cmd, return fail_invreq(cmd, ir, "Offer expired"); } - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_quantity_max` is present: - * - MUST fail the request if there is no `invreq_quantity` field. + * - MUST reject the invoice request if there is no `invreq_quantity` field. * - if `offer_quantity_max` is non-zero: - * - MUST fail the request if `invreq_quantity` is zero, OR greater than + * - MUST reject the invoice request if `invreq_quantity` is zero, OR greater than * `offer_quantity_max`. * - otherwise: - * - MUST fail the request if there is an `invreq_quantity` field. + * - MUST reject the invoice request if there is an `invreq_quantity` field. */ if (ir->invreq->offer_quantity_max) { err = invreq_must_have(cmd, ir, invreq_quantity); @@ -884,8 +884,8 @@ static struct command_result *listoffers_done(struct command *cmd, return err; } - /* BOLT-offers #12: - * - MUST fail the request if `signature` is not correct as + /* BOLT #12: + * - MUST reject the invoice request if `signature` is not correct as * detailed in [Signature Calculation](#signature-calculation) using * the `invreq_payer_id`. */ @@ -899,21 +899,21 @@ static struct command_result *listoffers_done(struct command *cmd, } if (ir->invreq->offer_recurrence) { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * * - if the offer had a `recurrence`: - * - MUST fail the request if there is no `recurrence_counter` + * - MUST reject the invoice request if there is no `recurrence_counter` * field. */ err = invreq_must_have(cmd, ir, invreq_recurrence_counter); if (err) return err; } else { - /* BOLT-offers-recurrence #12: + /* BOLT-recurrence #12: * - otherwise (the offer had no `recurrence`): - * - MUST fail the request if there is a `recurrence_counter` + * - MUST reject the invoice request if there is a `recurrence_counter` * field. - * - MUST fail the request if there is a `recurrence_start` + * - MUST reject the invoice request if there is a `recurrence_start` * field. */ err = invreq_must_not_have(cmd, ir, invreq_recurrence_counter); @@ -924,31 +924,31 @@ static struct command_result *listoffers_done(struct command *cmd, return err; } - /* BOLT-offers #12: + /* BOLT #12: * A writer of an invoice: *... * - if the invoice is in response to an `invoice_request`: - * - MUST copy all non-signature fields from the `invoice_request` (including + * - MUST copy all non-signature fields from the invoice request (including * unknown fields). */ ir->inv = invoice_for_invreq(cmd, ir->invreq); assert(ir->inv->invreq_payer_id); - /* BOLT-offers #12: + /* BOLT #12: * - if `offer_issuer_id` is present: * - MUST set `invoice_node_id` to the `offer_issuer_id` */ /* FIXME: We always provide an offer_issuer_id! */ ir->inv->invoice_node_id = ir->inv->offer_issuer_id; - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invoice_created_at` to the number of seconds since * Midnight 1 January 1970, UTC when the invoice was created. */ ir->inv->invoice_created_at = tal(ir->inv, u64); *ir->inv->invoice_created_at = time_now().ts.tv_sec; - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invoice_payment_hash` to the SHA256 hash of the * `payment_preimage` that will be given in return for payment. */ @@ -957,7 +957,7 @@ static struct command_result *listoffers_done(struct command *cmd, sha256(ir->inv->invoice_payment_hash, &ir->preimage, sizeof(ir->preimage)); - /* BOLT-offers #12: + /* BOLT #12: * - or if it allows multiple parts to pay the invoice: * - MUST set `invoice_features`.`features` bit `MPP/optional` */ @@ -993,12 +993,12 @@ struct command_result *handle_invoice_request(struct command *cmd, return fail_invreq(cmd, ir, "Invalid invreq"); } - /* BOLT-offers #12: + /* BOLT #12: * The reader: * ... - * - MUST fail the request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 + * - MUST reject the invoice request if any non-signature TLV fields are outside the inclusive ranges: 0 to 159 and 1000000000 to 2999999999 */ - /* BOLT-offers #12: + /* BOLT #12: * Each form is signed using one or more *signature TLV elements*: * TLV types 240 through 1000 (inclusive) */ @@ -1008,10 +1008,10 @@ struct command_result *handle_invoice_request(struct command *cmd, return fail_invreq(cmd, ir, "Invalid high fields"); } - /* BOLT-offers #12: + /* BOLT #12: * * The reader: - * - MUST fail the request if `invreq_payer_id` or `invreq_metadata` + * - MUST reject the invoice request if `invreq_payer_id` or `invreq_metadata` * are not present. */ if (!ir->invreq->invreq_payer_id) @@ -1019,12 +1019,12 @@ struct command_result *handle_invoice_request(struct command *cmd, if (!ir->invreq->invreq_metadata) return fail_invreq(cmd, ir, "Missing invreq_metadata"); - /* BOLT-offers #12: + /* BOLT #12: * * The reader: *... * - if `invreq_features` contains unknown _even_ bits that are non-zero: - * - MUST fail the request. + * - MUST reject the invoice request. */ bad_feature = features_unsupported(plugin_feature_set(cmd->plugin), ir->invreq->invreq_features, @@ -1050,14 +1050,18 @@ struct command_result *handle_invoice_request(struct command *cmd, } } - /* BOLT-offers #12: + /* FIXME: quote is garbled, see: https://github.com/lightning/bolts/pull/1222 */ + /* BOLT #12: * * The reader: *... * - if `invreq_chain` is not present: - * - MUST fail the request if bitcoin is not a supported chain. + * - MUST reject the invoice request if bitcoin is not a supported chain. + * - if `invreq_bip_353_name` is present: + * - MUST reject the invoice request if `name` or `domain` contain any bytes which are not + * `0`-`9`, `a`-`z`, `A`-`Z`, `-`, `_` or `.`. * - otherwise: - * - MUST fail the request if `invreq_chain`.`chain` is not a + * - MUST reject the invoice request if `invreq_chain`.`chain` is not a * supported chain. */ if (!bolt12_chain_matches(ir->invreq->invreq_chain, chainparams)) { @@ -1066,7 +1070,7 @@ struct command_result *handle_invoice_request(struct command *cmd, tal_hex(tmpctx, ir->invreq->invreq_chain)); } - /* BOLT-offers #12: + /* BOLT #12: * * - otherwise (no `offer_issuer_id` or `offer_paths`, not a response to our offer): */ @@ -1075,10 +1079,10 @@ struct command_result *handle_invoice_request(struct command *cmd, return fail_invreq(cmd, ir, "Not based on an offer"); } - /* BOLT-offers #12: + /* BOLT #12: * * - if `offer_issuer_id` or `offer_paths` are present (response to an offer): - * - MUST fail the request if the offer fields do not exactly match a + * - MUST reject the invoice request if the offer fields do not exactly match a * valid, unexpired offer. */ invreq_offer_id(ir->invreq, &ir->offer_id); diff --git a/plugins/offers_offer.c b/plugins/offers_offer.c index 72ddcda970c1..ac2684615789 100644 --- a/plugins/offers_offer.c +++ b/plugins/offers_offer.c @@ -46,15 +46,15 @@ static struct command_result *param_amount(struct command *cmd, offer->offer_amount = tal(offer, u64); - /* BOLT-offers #12: + /* BOLT #12: * - * - MUST specify `offer_currency` `iso4217` as an ISO 4712 three-letter code. - * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4712 + * - MUST specify `offer_currency` `iso4217` as an ISO 4217 three-letter code. + * - MUST specify `offer_amount` in the currency unit adjusted by the ISO 4217 * exponent (e.g. USD cents). */ if (tok->end - tok->start < ISO4217_NAMELEN) return command_fail_badparam(cmd, name, buffer, tok, - "should be 'any', msatoshis or [.]"); + "should be 'any', msatoshis or [.]"); isocode = find_iso4217(buffer + tok->end - ISO4217_NAMELEN, ISO4217_NAMELEN); if (!isocode) @@ -84,7 +84,7 @@ static struct command_result *param_amount(struct command *cmd, if (!json_to_u64(buffer, &whole, offer->offer_amount)) return command_fail_badparam(cmd, name, buffer, tok, - "should be 'any', msatoshis or [.]"); + "should be 'any', msatoshis or [.]"); for (size_t i = 0; i < isocode->minor_unit; i++) { if (mul_overflows_u64(*offer->offer_amount, 10)) @@ -282,7 +282,7 @@ static struct command_result *found_best_peer(struct command *cmd, const struct chaninfo *best, struct offer_info *offinfo) { - /* BOLT-offers #12: + /* BOLT #12: * - if it is connected only by private channels: * - MUST include `offer_paths` containing one or more paths to the node from * publicly reachable nodes. @@ -323,7 +323,7 @@ static struct command_result *found_best_peer(struct command *cmd, static struct command_result *maybe_add_path(struct command *cmd, struct offer_info *offinfo) { - /* BOLT-offers #12: + /* BOLT #12: * - if it is connected only by private channels: * - MUST include `offer_paths` containing one or more paths to the node from * publicly reachable nodes. @@ -475,12 +475,12 @@ struct command_result *json_offer(struct command *cmd, return command_fail_badparam(cmd, "quantity_max", buffer, params, "must be 0 or > 1"); - /* BOLT-offers #12: + /* BOLT #12: * * - if the chain for the invoice is not solely bitcoin: * - MUST specify `offer_chains` the offer is valid for. * - otherwise: - * - MAY omit `offer_chains`, implying that bitcoin is only chain. + * - SHOULD omit `offer_chains`, implying that bitcoin is only chain. */ if (!streq(chainparams->network_name, "bitcoin")) { offer->offer_chains = tal_arr(offer, struct bitcoin_blkid, 1); @@ -506,7 +506,7 @@ struct command_result *json_offer(struct command *cmd, offer->offer_description = tal_dup_arr(offer, char, desc, strlen(desc), 0); - /* BOLT-offers #12: + /* BOLT #12: * * - if `offer_amount` is set and `offer_description` is not set: * - MUST NOT respond to the offer. @@ -515,7 +515,7 @@ struct command_result *json_offer(struct command *cmd, return command_fail_badparam(cmd, "description", buffer, params, "description is required for the user to know what it was they paid for"); - /* BOLT-offers #12: + /* BOLT #12: * - if it sets `offer_issuer`: * - SHOULD set it to identify the issuer of the invoice clearly. * - if it includes a domain name: @@ -527,7 +527,7 @@ struct command_result *json_offer(struct command *cmd, = tal_dup_arr(offer, char, issuer, strlen(issuer), 0); } - /* BOLT-offers #12: + /* BOLT #12: * - if it includes `offer_paths`: *... * - otherwise: @@ -615,10 +615,10 @@ static struct command_result *found_best_peer_invrequest(struct command *cmd, struct secret blinding_path_secret; struct sha256 invreq_id; - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invreq_paths` as it would set (or not set) `offer_paths` for an offer. */ - /* BOLT-offers #12: + /* BOLT #12: * * - if it is connected only by private channels: * - MUST include `offer_paths` containing one or more paths to the node from @@ -676,7 +676,7 @@ struct command_result *json_invoicerequest(struct command *cmd, NULL)) return command_param_failed(); - /* BOLT-offers #12: + /* BOLT #12: * - otherwise (not responding to an offer): * - MUST set `offer_description` to a complete description of the purpose of the payment. * - MUST set (or not set) `offer_absolute_expiry` and `offer_issuer` as it would for an offer. @@ -702,7 +702,7 @@ struct command_result *json_invoicerequest(struct command *cmd, = tal_dup(invreq, struct bitcoin_blkid, &chainparams->genesis_blockhash); } - /* BOLT-offers #12: + /* BOLT #12: * - if it sets `invreq_amount`: * - MUST set `msat` in multiples of the minimum lightning-payable unit * (e.g. milli-satoshis for bitcoin) for `invreq_chain` (or for bitcoin, if there is no `invreq_chain`). @@ -710,14 +710,14 @@ struct command_result *json_invoicerequest(struct command *cmd, invreq->invreq_amount = tal_dup(invreq, u64, &msat->millisatoshis); /* Raw: wire */ - /* BOLT-offers #12: + /* BOLT #12: * - MUST set `invreq_metadata` to an unpredictable series of bytes. */ invreq->invreq_metadata = tal_arr(invreq, u8, 16); randombytes_buf(invreq->invreq_metadata, tal_bytelen(invreq->invreq_metadata)); - /* BOLT-offers #12: + /* BOLT #12: * - otherwise (not responding to an offer): *... * - MUST set `invreq_payer_id` (as it would set `offer_issuer_id` for an offer). @@ -725,7 +725,7 @@ struct command_result *json_invoicerequest(struct command *cmd, /* FIXME: Allow invoicerequests using aliases! */ invreq->invreq_payer_id = tal_dup(invreq, struct pubkey, &id); - /* BOLT-offers #12: + /* BOLT #12: * - if it supports bolt12 invoice request features: * - MUST set `invreq_features`.`features` to the bitmap of features. */ diff --git a/plugins/pay.c b/plugins/pay.c index b4d119c36ec4..7deaf85bc518 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1404,7 +1404,7 @@ static struct command_result *json_pay(struct command *cmd, node_id_from_pubkey(p->route_destination, &p->blindedpath->first_node_id.pubkey); p->payment_metadata = NULL; p->routes = NULL; - /* BOLT-offers #12: + /* BOLT #12: * - if `invoice_relative_expiry` is present: * - MUST reject the invoice if the current time since * 1970-01-01 UTC is greater than `invoice_created_at` plus diff --git a/plugins/xpay/xpay.c b/plugins/xpay/xpay.c index 59ee75df4ca0..a97a4036e147 100644 --- a/plugins/xpay/xpay.c +++ b/plugins/xpay/xpay.c @@ -1305,7 +1305,7 @@ static char *add_blindedpath(const tal_t *ctx, struct short_channel_id scid; struct node_id src, dst; - /* BOLT-offers #12: + /* BOLT #12: * - SHOULD prefer to use earlier `invoice_paths` over later ones if * it has no other reason for preference. */ @@ -1328,7 +1328,7 @@ static char *add_blindedpath(const tal_t *ctx, assert(path->first_node_id.is_pubkey); - /* BOLT-offers #12: + /* BOLT #12: * - For each `invoice_blindedpay`.`payinfo`: * - MUST NOT use the corresponding `invoice_paths`.`path` * if `payinfo`.`features` has any unknown even bits set. diff --git a/tests/test_pay.py b/tests/test_pay.py index 8a63ab235083..a17f336c79cf 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -5261,7 +5261,7 @@ def test_payerkey(node_factory): # Now we are supposed to put invreq_payer_id inside invreq, and lightningd # checks the derivation as a courtesy. Fortunately, invreq_payer_id is last for n, k in zip(nodes, expected_keys): - # BOLT-offers #12: + # BOLT #12: # 1. type: 88 (`invreq_payer_id`) # 2. data: # * [`point`:`key`] @@ -5929,7 +5929,7 @@ def test_fetch_no_description_with_amount(node_factory): l1, l2 = node_factory.line_graph(2, opts={'allow-deprecated-apis': True}) # Deprecated fields make schema checker upset. - # BOLT-offers #12: + # BOLT #12: # # - if offer_amount is set and offer_description is not set: # - MUST NOT respond to the offer.