BOLT12: remove -offers from bolt12 quotes, update them.

Typo fixes and wording changes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2025-02-11 10:21:42 +10:30 committed by Alex Myers
parent c22cc11af5
commit c3362b057c
20 changed files with 242 additions and 234 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -3,10 +3,10 @@
#include "config.h"
#include <wire/wire.h>
/* 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 {

View file

@ -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:

View file

@ -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");

View file

@ -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.

View file

@ -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);

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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`.
*/

View file

@ -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`

View file

@ -584,7 +584,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`.
*/
@ -595,7 +595,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.
*/
@ -613,7 +613,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) {
@ -681,7 +681,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.
@ -792,7 +792,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.
*/
@ -821,8 +821,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",
@ -933,7 +933,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.
@ -1007,8 +1007,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",
@ -1016,8 +1016,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`.
*/
@ -1097,7 +1097,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`.
@ -1128,7 +1128,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
@ -1150,7 +1150,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)
@ -1178,7 +1178,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.

View file

@ -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`:

View file

@ -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);

View file

@ -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 <amount>[.<amount>]<ISO-4712>");
"should be 'any', msatoshis or <amount>[.<amount>]<ISO-4217>");
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 <ISO-4712><amount>[.<amount>]");
"should be 'any', msatoshis or <ISO-4217><amount>[.<amount>]");
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.
*/

View file

@ -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

View file

@ -1312,7 +1312,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.
*/
@ -1335,7 +1335,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.

View file

@ -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.