diff --git a/devtools/bolt12-cli.c b/devtools/bolt12-cli.c index 8822b8546..1b7796a11 100644 --- a/devtools/bolt12-cli.c +++ b/devtools/bolt12-cli.c @@ -545,16 +545,25 @@ int main(int argc, char *argv[]) print_features(invreq->features); if (invreq->quantity) print_quantity(*invreq->quantity); + /* Note: old format didn't include this, so we don't complain! */ + if (invreq->payer_signature) + well_formed &= print_signature("invoice_request", + "payer_signature", + invreq->fields, + invreq->payer_key, + invreq->payer_signature); if (invreq->recurrence_counter) { print_recurrence_counter(invreq->recurrence_counter, invreq->recurrence_start); - if (must_have(invreq, recurrence_signature)) { + /* Old form included recurrence_signature */ + if (invreq->recurrence_signature) well_formed &= print_signature("invoice_request", "recurrence_signature", invreq->fields, invreq->payer_key, invreq->recurrence_signature); - } + else /* New form definitely should have this! */ + must_have(invreq, payer_signature); } else { must_not_have(invreq, recurrence_start); must_not_have(invreq, recurrence_signature); diff --git a/lightningd/offer.c b/lightningd/offer.c index f63531c7b..a87d2ba34 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -403,6 +404,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd, const char *label; struct json_stream *response; u64 *prev_basetime = NULL; + struct sha256 merkle; if (!param(cmd, buffer, params, p_req("bolt12", param_b12_invreq, &invreq), @@ -448,24 +450,24 @@ static struct command_result *json_createinvoicerequest(struct command *cmd, } /* BOLT-offers #12: - * - if the offer contained `recurrence`: - *... - * - MUST set `recurrence_signature` `sig` as detailed in - * [Signature Calculation](#signature-calculation) using the - * `payer_key`. + * - MUST set `payer_signature` `sig` as detailed in + * [Signature Calculation](#signature-calculation) using the `payer_key`. */ - if (invreq->recurrence_counter) { - struct sha256 merkle; + /* This populates the ->fields from our entries */ + invreq->fields = tlv_make_fields(invreq, invoice_request); + merkle_tlv(invreq->fields, &merkle); + invreq->payer_signature = tal(invreq, struct bip340sig); + hsm_sign_b12(cmd->ld, "invoice_request", "payer_signature", + &merkle, invreq->payer_info, invreq->payer_key, + invreq->payer_signature); - /* This populates the ->fields from our entries */ - invreq->fields = tlv_make_fields(invreq, invoice_request); - merkle_tlv(invreq->fields, &merkle); + /* Backwards compat for older version! */ + if (deprecated_apis && invreq->recurrence_counter) { invreq->recurrence_signature = tal(invreq, struct bip340sig); hsm_sign_b12(cmd->ld, "invoice_request", "recurrence_signature", &merkle, invreq->payer_info, invreq->payer_key, invreq->recurrence_signature); } - response = json_stream_success(cmd); json_add_string(response, "bolt12", invrequest_encode(tmpctx, invreq)); if (label) diff --git a/plugins/offers.c b/plugins/offers.c index fd98b2e13..2eec48cf1 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -665,14 +665,31 @@ static void json_add_invoice_request(struct json_stream *js, json_add_hex_talarr(js, "payer_info", invreq->payer_info); /* BOLT-offers #12: - * - if the offer had a `recurrence`: - * - MUST fail the request if there is no `recurrence_counter` field. - * - MUST fail the request if there is no `recurrence_signature` field. - * - MUST fail the request if `recurrence_signature` is not correct. + * - MUST fail the request if there is no `payer_signature` field. + * - MUST fail the request if `payer_signature` is not correct. */ - if (invreq->recurrence_signature) { - json_add_bip340sig(js, "recurrence_signature", - invreq->recurrence_signature); + /* Older spec didn't have this, so we allow omission for now. */ + if (invreq->payer_signature) { + json_add_bip340sig(js, "payer_signature", + invreq->payer_signature); + if (invreq->payer_key + && !bolt12_check_signature(invreq->fields, + "invoice_request", + "payer_signature", + invreq->payer_key, + invreq->payer_signature)) { + json_add_string(js, "warning_invoice_request_invalid_payer_signature", + "Bad payer_signature"); + valid = false; + } + } else { + json_add_string(js, "warning_invoice_request_missing_payer_signature", + "Missing payer_signature"); + if (!deprecated_apis) + valid = false; + } + + if (deprecated_apis && invreq->recurrence_counter) { if (invreq->payer_key && !bolt12_check_signature(invreq->fields, "invoice_request", @@ -680,13 +697,9 @@ static void json_add_invoice_request(struct json_stream *js, invreq->payer_key, invreq->recurrence_signature)) { json_add_string(js, "warning_invoice_request_invalid_recurrence_signature", - "Bad recurrence_signature"); + "Bad recurrence_signature"); valid = false; } - } else if (invreq->recurrence_counter) { - json_add_string(js, "warning_invoice_request_missing_recurrence_signature", - "invoice_request requires recurrence_signature"); - valid = false; } json_add_bool(js, "valid", valid); diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index 996c1a318..accd400b8 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -408,9 +408,7 @@ static struct command_result *check_previous_invoice(struct command *cmd, return send_outreq(cmd->plugin, req); } -/* BOLT-offers #12: - * - MUST fail the request if `recurrence_signature` is not correct. - */ +/* Obsolete recurrence_signature; we still check if present. */ static bool check_recurrence_sig(const struct tlv_invoice_request *invreq, const struct pubkey32 *payer_key, const struct bip340sig *sig) @@ -425,6 +423,23 @@ static bool check_recurrence_sig(const struct tlv_invoice_request *invreq, sighash.u.u8, &payer_key->pubkey) == 1; } +/* BOLT-offers #12: + * - MUST fail the request if `payer_signature` is not correct. + */ +static bool check_payer_sig(const struct tlv_invoice_request *invreq, + const struct pubkey32 *payer_key, + const struct bip340sig *sig) +{ + struct sha256 merkle, sighash; + merkle_tlv(invreq->fields, &merkle); + sighash_from_merkle("invoice_request", "payer_signature", + &merkle, &sighash); + + return secp256k1_schnorrsig_verify(secp256k1_ctx, + sig->u8, + sighash.u.u8, &payer_key->pubkey) == 1; +} + static struct command_result *invreq_amount_by_quantity(struct command *cmd, const struct invreq *ir, u64 *raw_amt) @@ -706,6 +721,19 @@ static struct command_result *listoffers_done(struct command *cmd, return err; } + /* FIXME: payer_signature is now always required, but we let it go + * for now. */ + if (!deprecated_apis) { + err = invreq_must_have(cmd, ir, payer_signature); + if (err) + return err; + if (!check_payer_sig(ir->invreq, + ir->invreq->payer_key, + ir->invreq->payer_signature)) { + return fail_invreq(cmd, ir, "bad payer_signature"); + } + } + if (ir->offer->recurrence) { /* BOLT-offers #12: * @@ -721,30 +749,31 @@ static struct command_result *listoffers_done(struct command *cmd, if (err) return err; - err = invreq_must_have(cmd, ir, recurrence_signature); - if (err) - return err; - - if (!check_recurrence_sig(ir->invreq, - ir->invreq->payer_key, - ir->invreq->recurrence_signature)) { - return fail_invreq(cmd, ir, - "bad recurrence_signature"); + if (deprecated_apis) { + if (ir->invreq->recurrence_signature) { + if (!check_recurrence_sig(ir->invreq, + ir->invreq->payer_key, + ir->invreq->recurrence_signature)) { + return fail_invreq(cmd, ir, + "bad recurrence_signature"); + } + } else { + /* You really do need payer_signature if + * you're using recurrence: we rely on it! */ + err = invreq_must_have(cmd, ir, payer_signature); + if (err) + return err; + } } } else { /* BOLT-offers #12: * - otherwise (the offer had no `recurrence`): * - MUST fail the request if there is a `recurrence_counter` * field. - * - MUST fail the request if there is a `recurrence_signature` - * field. */ err = invreq_must_not_have(cmd, ir, recurrence_counter); if (err) return err; - err = invreq_must_not_have(cmd, ir, recurrence_signature); - if (err) - return err; } ir->inv = tlv_invoice_new(cmd); diff --git a/wire/Makefile b/wire/Makefile index 6a3729bc2..b822b9740 100644 --- a/wire/Makefile +++ b/wire/Makefile @@ -58,14 +58,17 @@ WIRE_BOLT_DEPS := $(BOLT_DEPS) tools/gen/impl_template tools/gen/header_template ALL_PEER_PATCHES := $(sort $(wildcard wire/extracted_peer*.patch)) ALL_ONION_PATCHES := $(sort $(wildcard wire/extracted_onion*.patch)) +ALL_BOLT12_PATCHES := $(sort $(wildcard wire/extracted_bolt12*.patch)) # These are applied to the non-exp csvs to make the exp csvs. PEER_EXP_PATCHES := $(sort $(wildcard wire/extracted_peer_exp*.patch)) ONION_EXP_PATCHES := $(sort $(wildcard wire/extracted_onion_exp*.patch)) +BOLT12_EXP_PATCHES := $(sort $(wildcard wire/extracted_bolt12_exp*.patch)) # These are always applied to the bolts. PEER_PATCHES := $(filter-out $(PEER_EXP_PATCHES),$(ALL_PEER_PATCHES)) ONION_PATCHES := $(filter-out $(ONION_EXP_PATCHES),$(ALL_ONION_PATCHES)) +BOLT12_PATCHES := $(filter-out $(BOLT12_EXP_PATCHES),$(ALL_BOLT12_PATCHES)) # Explicit command to re-extract CSV from BOLTs and patch. # This is not a normal make depencency, since we don't want this diff --git a/wire/bolt12_exp_wire.csv b/wire/bolt12_exp_wire.csv index 17628e9a9..c9d604381 100644 --- a/wire/bolt12_exp_wire.csv +++ b/wire/bolt12_exp_wire.csv @@ -57,9 +57,15 @@ tlvtype,invoice_request,recurrence_start,68 tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvtype,invoice_request,payer_key,38 tlvdata,invoice_request,payer_key,key,pubkey32, +tlvtype,invoice_request,payer_note,39 +tlvdata,invoice_request,payer_note,note,utf8,... tlvtype,invoice_request,payer_info,50 tlvdata,invoice_request,payer_info,blob,byte,... -tlvtype,invoice_request,recurrence_signature,242 +tlvtype,invoice_request,replace_invoice,56 +tlvdata,invoice_request,replace_invoice,payment_hash,sha256, +tlvtype,invoice_request,payer_signature,241 +tlvdata,invoice_request,payer_signature,sig,bip340sig, +tlvtype,invoice_request,recurrence_signature,240 tlvdata,invoice_request,recurrence_signature,sig,bip340sig, tlvtype,invoice,chains,2 tlvdata,invoice,chains,chains,chain_hash,... @@ -75,6 +81,8 @@ tlvtype,invoice,paths,16 tlvdata,invoice,paths,paths,blinded_path,... tlvtype,invoice,blindedpay,18 tlvdata,invoice,blindedpay,payinfo,blinded_payinfo,... +tlvtype,invoice,blinded_capacities,19 +tlvdata,invoice,blinded_capacities,incoming_msat,u64,... tlvtype,invoice,vendor,20 tlvdata,invoice,vendor,vendor,utf8,... tlvtype,invoice,node_id,30 @@ -92,6 +100,8 @@ tlvtype,invoice,recurrence_basetime,64 tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvtype,invoice,payer_key,38 tlvdata,invoice,payer_key,key,pubkey32, +tlvtype,invoice,payer_note,39 +tlvdata,invoice,payer_note,note,utf8,... tlvtype,invoice,payer_info,50 tlvdata,invoice,payer_info,blob,byte,... tlvtype,invoice,timestamp,40 @@ -107,6 +117,8 @@ tlvdata,invoice,fallbacks,num,u8, tlvdata,invoice,fallbacks,fallbacks,fallback_address,num tlvtype,invoice,refund_signature,52 tlvdata,invoice,refund_signature,payer_signature,bip340sig, +tlvtype,invoice,replace_invoice,56 +tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvtype,invoice,signature,240 tlvdata,invoice,signature,sig,bip340sig, subtype,blinded_payinfo diff --git a/wire/bolt12_wire.csv b/wire/bolt12_wire.csv index 17628e9a9..c9d604381 100644 --- a/wire/bolt12_wire.csv +++ b/wire/bolt12_wire.csv @@ -57,9 +57,15 @@ tlvtype,invoice_request,recurrence_start,68 tlvdata,invoice_request,recurrence_start,period_offset,tu32, tlvtype,invoice_request,payer_key,38 tlvdata,invoice_request,payer_key,key,pubkey32, +tlvtype,invoice_request,payer_note,39 +tlvdata,invoice_request,payer_note,note,utf8,... tlvtype,invoice_request,payer_info,50 tlvdata,invoice_request,payer_info,blob,byte,... -tlvtype,invoice_request,recurrence_signature,242 +tlvtype,invoice_request,replace_invoice,56 +tlvdata,invoice_request,replace_invoice,payment_hash,sha256, +tlvtype,invoice_request,payer_signature,241 +tlvdata,invoice_request,payer_signature,sig,bip340sig, +tlvtype,invoice_request,recurrence_signature,240 tlvdata,invoice_request,recurrence_signature,sig,bip340sig, tlvtype,invoice,chains,2 tlvdata,invoice,chains,chains,chain_hash,... @@ -75,6 +81,8 @@ tlvtype,invoice,paths,16 tlvdata,invoice,paths,paths,blinded_path,... tlvtype,invoice,blindedpay,18 tlvdata,invoice,blindedpay,payinfo,blinded_payinfo,... +tlvtype,invoice,blinded_capacities,19 +tlvdata,invoice,blinded_capacities,incoming_msat,u64,... tlvtype,invoice,vendor,20 tlvdata,invoice,vendor,vendor,utf8,... tlvtype,invoice,node_id,30 @@ -92,6 +100,8 @@ tlvtype,invoice,recurrence_basetime,64 tlvdata,invoice,recurrence_basetime,basetime,tu64, tlvtype,invoice,payer_key,38 tlvdata,invoice,payer_key,key,pubkey32, +tlvtype,invoice,payer_note,39 +tlvdata,invoice,payer_note,note,utf8,... tlvtype,invoice,payer_info,50 tlvdata,invoice,payer_info,blob,byte,... tlvtype,invoice,timestamp,40 @@ -107,6 +117,8 @@ tlvdata,invoice,fallbacks,num,u8, tlvdata,invoice,fallbacks,fallbacks,fallback_address,num tlvtype,invoice,refund_signature,52 tlvdata,invoice,refund_signature,payer_signature,bip340sig, +tlvtype,invoice,replace_invoice,56 +tlvdata,invoice,replace_invoice,payment_hash,sha256, tlvtype,invoice,signature,240 tlvdata,invoice,signature,sig,bip340sig, subtype,blinded_payinfo diff --git a/wire/bolt12_wiregen.c b/wire/bolt12_wiregen.c index 22e856078..2547c97a4 100644 --- a/wire/bolt12_wiregen.c +++ b/wire/bolt12_wiregen.c @@ -765,6 +765,28 @@ static void fromwire_tlv_invoice_request_payer_key(const u8 **cursor, size_t *pl fromwire_pubkey32(cursor, plen, &*r->payer_key); } +/* INVOICE_REQUEST MSG: payer_note */ +static u8 *towire_tlv_invoice_request_payer_note(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice_request *r = vrecord; + u8 *ptr; + + if (!r->payer_note) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_utf8_array(&ptr, r->payer_note, tal_count(r->payer_note)); + return ptr; +} +static void fromwire_tlv_invoice_request_payer_note(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice_request *r = vrecord; + + r->payer_note = *plen ? tal_arr(r, utf8, *plen) : NULL; +fromwire_utf8_array(cursor, plen, r->payer_note, *plen); +} /* INVOICE_REQUEST MSG: payer_info */ static u8 *towire_tlv_invoice_request_payer_info(const tal_t *ctx, const void *vrecord) { @@ -787,6 +809,52 @@ static void fromwire_tlv_invoice_request_payer_info(const u8 **cursor, size_t *p r->payer_info = *plen ? tal_arr(r, u8, *plen) : NULL; fromwire_u8_array(cursor, plen, r->payer_info, *plen); } +/* INVOICE_REQUEST MSG: replace_invoice */ +static u8 *towire_tlv_invoice_request_replace_invoice(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice_request *r = vrecord; + u8 *ptr; + + if (!r->replace_invoice) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_sha256(&ptr, r->replace_invoice); + return ptr; +} +static void fromwire_tlv_invoice_request_replace_invoice(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice_request *r = vrecord; + + r->replace_invoice = tal(r, struct sha256); + +fromwire_sha256(cursor, plen, &*r->replace_invoice); +} +/* INVOICE_REQUEST MSG: payer_signature */ +static u8 *towire_tlv_invoice_request_payer_signature(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice_request *r = vrecord; + u8 *ptr; + + if (!r->payer_signature) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_bip340sig(&ptr, r->payer_signature); + return ptr; +} +static void fromwire_tlv_invoice_request_payer_signature(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice_request *r = vrecord; + + r->payer_signature = tal(r, struct bip340sig); + +fromwire_bip340sig(cursor, plen, &*r->payer_signature); +} /* INVOICE_REQUEST MSG: recurrence_signature */ static u8 *towire_tlv_invoice_request_recurrence_signature(const tal_t *ctx, const void *vrecord) { @@ -819,20 +887,23 @@ const struct tlv_record_type tlvs_invoice_request[] = { { 32, towire_tlv_invoice_request_quantity, fromwire_tlv_invoice_request_quantity }, { 36, towire_tlv_invoice_request_recurrence_counter, fromwire_tlv_invoice_request_recurrence_counter }, { 38, towire_tlv_invoice_request_payer_key, fromwire_tlv_invoice_request_payer_key }, + { 39, towire_tlv_invoice_request_payer_note, fromwire_tlv_invoice_request_payer_note }, { 50, towire_tlv_invoice_request_payer_info, fromwire_tlv_invoice_request_payer_info }, + { 56, towire_tlv_invoice_request_replace_invoice, fromwire_tlv_invoice_request_replace_invoice }, { 68, towire_tlv_invoice_request_recurrence_start, fromwire_tlv_invoice_request_recurrence_start }, - { 242, towire_tlv_invoice_request_recurrence_signature, fromwire_tlv_invoice_request_recurrence_signature }, + { 240, towire_tlv_invoice_request_recurrence_signature, fromwire_tlv_invoice_request_recurrence_signature }, + { 241, towire_tlv_invoice_request_payer_signature, fromwire_tlv_invoice_request_payer_signature }, }; void towire_invoice_request(u8 **pptr, const struct tlv_invoice_request *record) { - towire_tlv(pptr, tlvs_invoice_request, 10, record); + towire_tlv(pptr, tlvs_invoice_request, 13, record); } bool fromwire_invoice_request(const u8 **cursor, size_t *max, struct tlv_invoice_request *record) { - return fromwire_tlv(cursor, max, tlvs_invoice_request, 10, record, &record->fields); + return fromwire_tlv(cursor, max, tlvs_invoice_request, 13, record, &record->fields); } bool invoice_request_is_valid(const struct tlv_invoice_request *record, size_t *err_index) @@ -1022,6 +1093,33 @@ static void fromwire_tlv_invoice_blindedpay(const u8 **cursor, size_t *plen, voi tal_arr_expand(&r->blindedpay, tmp); } } +/* INVOICE MSG: blinded_capacities */ +static u8 *towire_tlv_invoice_blinded_capacities(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice *r = vrecord; + u8 *ptr; + + if (!r->blinded_capacities) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + for (size_t i = 0; i < tal_count(r->blinded_capacities); i++) + towire_amount_msat(&ptr, r->blinded_capacities[i]); + return ptr; +} +static void fromwire_tlv_invoice_blinded_capacities(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice *r = vrecord; + + r->blinded_capacities = *plen ? tal_arr(r, struct amount_msat, 0) : NULL; + for (size_t i = 0; *plen != 0; i++) { + struct amount_msat tmp; + tmp = fromwire_amount_msat(cursor, plen); + tal_arr_expand(&r->blinded_capacities, tmp); + } +} /* INVOICE MSG: vendor */ static u8 *towire_tlv_invoice_vendor(const tal_t *ctx, const void *vrecord) { @@ -1224,6 +1322,28 @@ static void fromwire_tlv_invoice_payer_key(const u8 **cursor, size_t *plen, void fromwire_pubkey32(cursor, plen, &*r->payer_key); } +/* INVOICE MSG: payer_note */ +static u8 *towire_tlv_invoice_payer_note(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice *r = vrecord; + u8 *ptr; + + if (!r->payer_note) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_utf8_array(&ptr, r->payer_note, tal_count(r->payer_note)); + return ptr; +} +static void fromwire_tlv_invoice_payer_note(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice *r = vrecord; + + r->payer_note = *plen ? tal_arr(r, utf8, *plen) : NULL; +fromwire_utf8_array(cursor, plen, r->payer_note, *plen); +} /* INVOICE MSG: payer_info */ static u8 *towire_tlv_invoice_payer_info(const tal_t *ctx, const void *vrecord) { @@ -1394,6 +1514,29 @@ static void fromwire_tlv_invoice_refund_signature(const u8 **cursor, size_t *ple fromwire_bip340sig(cursor, plen, &*r->refund_signature); } +/* INVOICE MSG: replace_invoice */ +static u8 *towire_tlv_invoice_replace_invoice(const tal_t *ctx, const void *vrecord) +{ + const struct tlv_invoice *r = vrecord; + u8 *ptr; + + if (!r->replace_invoice) + return NULL; + + + ptr = tal_arr(ctx, u8, 0); + + towire_sha256(&ptr, r->replace_invoice); + return ptr; +} +static void fromwire_tlv_invoice_replace_invoice(const u8 **cursor, size_t *plen, void *vrecord) +{ + struct tlv_invoice *r = vrecord; + + r->replace_invoice = tal(r, struct sha256); + +fromwire_sha256(cursor, plen, &*r->replace_invoice); +} /* INVOICE MSG: signature */ static u8 *towire_tlv_invoice_signature(const tal_t *ctx, const void *vrecord) { @@ -1426,12 +1569,14 @@ static const struct tlv_record_type tlvs_invoice[] = { { 12, towire_tlv_invoice_features, fromwire_tlv_invoice_features }, { 16, towire_tlv_invoice_paths, fromwire_tlv_invoice_paths }, { 18, towire_tlv_invoice_blindedpay, fromwire_tlv_invoice_blindedpay }, + { 19, towire_tlv_invoice_blinded_capacities, fromwire_tlv_invoice_blinded_capacities }, { 20, towire_tlv_invoice_vendor, fromwire_tlv_invoice_vendor }, { 30, towire_tlv_invoice_node_id, fromwire_tlv_invoice_node_id }, { 32, towire_tlv_invoice_quantity, fromwire_tlv_invoice_quantity }, { 34, towire_tlv_invoice_refund_for, fromwire_tlv_invoice_refund_for }, { 36, towire_tlv_invoice_recurrence_counter, fromwire_tlv_invoice_recurrence_counter }, { 38, towire_tlv_invoice_payer_key, fromwire_tlv_invoice_payer_key }, + { 39, towire_tlv_invoice_payer_note, fromwire_tlv_invoice_payer_note }, { 40, towire_tlv_invoice_timestamp, fromwire_tlv_invoice_timestamp }, { 42, towire_tlv_invoice_payment_hash, fromwire_tlv_invoice_payment_hash }, { 44, towire_tlv_invoice_relative_expiry, fromwire_tlv_invoice_relative_expiry }, @@ -1440,6 +1585,7 @@ static const struct tlv_record_type tlvs_invoice[] = { { 50, towire_tlv_invoice_payer_info, fromwire_tlv_invoice_payer_info }, { 52, towire_tlv_invoice_refund_signature, fromwire_tlv_invoice_refund_signature }, { 54, towire_tlv_invoice_send_invoice, fromwire_tlv_invoice_send_invoice }, + { 56, towire_tlv_invoice_replace_invoice, fromwire_tlv_invoice_replace_invoice }, { 64, towire_tlv_invoice_recurrence_basetime, fromwire_tlv_invoice_recurrence_basetime }, { 68, towire_tlv_invoice_recurrence_start, fromwire_tlv_invoice_recurrence_start }, { 240, towire_tlv_invoice_signature, fromwire_tlv_invoice_signature }, @@ -1447,13 +1593,13 @@ static const struct tlv_record_type tlvs_invoice[] = { void towire_invoice(u8 **pptr, const struct tlv_invoice *record) { - towire_tlv(pptr, tlvs_invoice, 24, record); + towire_tlv(pptr, tlvs_invoice, 27, record); } bool fromwire_invoice(const u8 **cursor, size_t *max, struct tlv_invoice *record) { - return fromwire_tlv(cursor, max, tlvs_invoice, 24, record, &record->fields); + return fromwire_tlv(cursor, max, tlvs_invoice, 27, record, &record->fields); } bool invoice_is_valid(const struct tlv_invoice *record, size_t *err_index) @@ -1562,4 +1708,4 @@ bool invoice_error_is_valid(const struct tlv_invoice_error *record, size_t *err_ return tlv_fields_valid(record->fields, NULL, err_index); } -// SHA256STAMP:fecda3c161101b67c3bb235f3fed55e215cc1dc74ac34140925999dae22064ab +// SHA256STAMP:4e69a9a1519146453c234fe466d01c351cd0a21dc2c4e90538f73ed2f37fdc77 diff --git a/wire/bolt12_wiregen.h b/wire/bolt12_wiregen.h index 364f2d783..44b24584e 100644 --- a/wire/bolt12_wiregen.h +++ b/wire/bolt12_wiregen.h @@ -90,7 +90,10 @@ struct tlv_invoice_request { u32 *recurrence_counter; u32 *recurrence_start; struct pubkey32 *payer_key; + utf8 *payer_note; u8 *payer_info; + struct sha256 *replace_invoice; + struct bip340sig *payer_signature; struct bip340sig *recurrence_signature; }; struct tlv_invoice { @@ -106,6 +109,7 @@ struct tlv_invoice { u8 *features; struct blinded_path **paths; struct blinded_payinfo **blindedpay; + struct amount_msat *blinded_capacities; utf8 *vendor; struct pubkey32 *node_id; u64 *quantity; @@ -115,6 +119,7 @@ struct tlv_invoice { u32 *recurrence_start; u64 *recurrence_basetime; struct pubkey32 *payer_key; + utf8 *payer_note; u8 *payer_info; u64 *timestamp; struct sha256 *payment_hash; @@ -122,6 +127,7 @@ struct tlv_invoice { u32 *cltv; struct tlv_invoice_fallbacks *fallbacks; struct bip340sig *refund_signature; + struct sha256 *replace_invoice; struct bip340sig *signature; }; struct tlv_invoice_error { @@ -209,7 +215,7 @@ void towire_invoice_request(u8 **pptr, const struct tlv_invoice_request *record) bool invoice_request_is_valid(const struct tlv_invoice_request *record, size_t *err_index); -#define TLVS_ARRAY_SIZE_invoice_request 10 +#define TLVS_ARRAY_SIZE_invoice_request 13 extern const struct tlv_record_type tlvs_invoice_request[]; @@ -223,9 +229,12 @@ enum invoice_request_types { TLV_INVOICE_REQUEST_QUANTITY = 32, TLV_INVOICE_REQUEST_RECURRENCE_COUNTER = 36, TLV_INVOICE_REQUEST_PAYER_KEY = 38, + TLV_INVOICE_REQUEST_PAYER_NOTE = 39, TLV_INVOICE_REQUEST_PAYER_INFO = 50, + TLV_INVOICE_REQUEST_REPLACE_INVOICE = 56, TLV_INVOICE_REQUEST_RECURRENCE_START = 68, - TLV_INVOICE_REQUEST_RECURRENCE_SIGNATURE = 242, + TLV_INVOICE_REQUEST_RECURRENCE_SIGNATURE = 240, + TLV_INVOICE_REQUEST_PAYER_SIGNATURE = 241, }; struct tlv_invoice *tlv_invoice_new(const tal_t *ctx); @@ -316,4 +325,4 @@ struct fallback_address *fromwire_fallback_address(const tal_t *ctx, const u8 ** #endif /* LIGHTNING_WIRE_BOLT12_WIREGEN_H */ -// SHA256STAMP:fecda3c161101b67c3bb235f3fed55e215cc1dc74ac34140925999dae22064ab +// SHA256STAMP:4e69a9a1519146453c234fe466d01c351cd0a21dc2c4e90538f73ed2f37fdc77 diff --git a/wire/common_wiregen.c b/wire/common_wiregen.c index 54bb509f9..ef9627078 100644 --- a/wire/common_wiregen.c +++ b/wire/common_wiregen.c @@ -100,4 +100,4 @@ bool fromwire_custommsg_out(const tal_t *ctx, const void *p, u8 **msg) fromwire_u8_array(&cursor, &plen, *msg, msg_len); return cursor != NULL; } -// SHA256STAMP:7408471edc4019dfa1eedc9eef712cc85bb140a2ff2ac40b45600679141b6f29 +// SHA256STAMP:20f78b01d36c7db37e7316d8ab52740dd5f39011ea306f0e8b6a5a4a6bbc7c9e diff --git a/wire/common_wiregen.h b/wire/common_wiregen.h index 3e154c107..d837aee8c 100644 --- a/wire/common_wiregen.h +++ b/wire/common_wiregen.h @@ -41,4 +41,4 @@ bool fromwire_custommsg_out(const tal_t *ctx, const void *p, u8 **msg); #endif /* LIGHTNING_WIRE_COMMON_WIREGEN_H */ -// SHA256STAMP:7408471edc4019dfa1eedc9eef712cc85bb140a2ff2ac40b45600679141b6f29 +// SHA256STAMP:20f78b01d36c7db37e7316d8ab52740dd5f39011ea306f0e8b6a5a4a6bbc7c9e diff --git a/wire/extracted_bolt12_01_oldrecurrencesig.patch b/wire/extracted_bolt12_01_oldrecurrencesig.patch new file mode 100644 index 000000000..3810d7e5b --- /dev/null +++ b/wire/extracted_bolt12_01_oldrecurrencesig.patch @@ -0,0 +1,13 @@ +diff --git a/wire/bolt12_wire.csv b/wire/bolt12_wire.csv +index 4c7108b98..7216e6b22 100644 +--- a/wire/bolt12_wire.csv ++++ b/wire/bolt12_wire.csv +@@ -65,6 +65,8 @@ tlvtype,invoice_request,replace_invoice,56 + tlvdata,invoice_request,replace_invoice,payment_hash,sha256, + tlvtype,invoice_request,payer_signature,241 + tlvdata,invoice_request,payer_signature,sig,bip340sig, ++tlvtype,invoice_request,recurrence_signature,240 ++tlvdata,invoice_request,recurrence_signature,sig,bip340sig, + tlvtype,invoice,chains,2 + tlvdata,invoice,chains,chains,chain_hash,... + tlvtype,invoice,offer_id,4 diff --git a/wire/onion_printgen.c b/wire/onion_printgen.c index 7ecdf5d63..7ae73827a 100644 --- a/wire/onion_printgen.c +++ b/wire/onion_printgen.c @@ -859,4 +859,4 @@ void printonion_wire_tlv_message(const char *tlv_name, const u8 *msg) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_encmsg_tlvs, ARRAY_SIZE(print_tlvs_encmsg_tlvs)); } } -// SHA256STAMP:b64074e7469fc3eb617387ecd9381141df9f2fab9200406e73c2120b8e8311a2 +// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f diff --git a/wire/onion_printgen.h b/wire/onion_printgen.h index b84f3f8ed..6b85f97d4 100644 --- a/wire/onion_printgen.h +++ b/wire/onion_printgen.h @@ -58,4 +58,4 @@ void printwire_mpp_timeout(const char *fieldname, const u8 *cursor); void printwire_onionmsg_path(const char *fieldname, const u8 **cursor, size_t *plen); #endif /* LIGHTNING_WIRE_ONION_PRINTGEN_H */ -// SHA256STAMP:b64074e7469fc3eb617387ecd9381141df9f2fab9200406e73c2120b8e8311a2 +// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f diff --git a/wire/onion_wiregen.c b/wire/onion_wiregen.c index 6957fac73..8a25fa28d 100644 --- a/wire/onion_wiregen.c +++ b/wire/onion_wiregen.c @@ -1026,4 +1026,4 @@ bool fromwire_mpp_timeout(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:b64074e7469fc3eb617387ecd9381141df9f2fab9200406e73c2120b8e8311a2 +// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f diff --git a/wire/onion_wiregen.h b/wire/onion_wiregen.h index 8e808a2a3..6107b844e 100644 --- a/wire/onion_wiregen.h +++ b/wire/onion_wiregen.h @@ -317,4 +317,4 @@ bool fromwire_mpp_timeout(const void *p); #endif /* LIGHTNING_WIRE_ONION_WIREGEN_H */ -// SHA256STAMP:b64074e7469fc3eb617387ecd9381141df9f2fab9200406e73c2120b8e8311a2 +// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f diff --git a/wire/peer_printgen.c b/wire/peer_printgen.c index 74baba6a4..1a3e622cd 100644 --- a/wire/peer_printgen.c +++ b/wire/peer_printgen.c @@ -2935,4 +2935,4 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_onion_message_tlvs, ARRAY_SIZE(print_tlvs_onion_message_tlvs)); } } -// SHA256STAMP:d4f6f16581d26f95c512a5a98e962abe529ff37a70a7563bd41f25ac802bdb63 +// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd diff --git a/wire/peer_printgen.h b/wire/peer_printgen.h index a678cadb6..3e60dfc7a 100644 --- a/wire/peer_printgen.h +++ b/wire/peer_printgen.h @@ -96,4 +96,4 @@ void printwire_channel_update_checksums(const char *fieldname, const u8 **cursor void printwire_channel_update_timestamps(const char *fieldname, const u8 **cursor, size_t *plen); void printwire_witness_stack(const char *fieldname, const u8 **cursor, size_t *plen); #endif /* LIGHTNING_WIRE_PEER_PRINTGEN_H */ -// SHA256STAMP:d4f6f16581d26f95c512a5a98e962abe529ff37a70a7563bd41f25ac802bdb63 +// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd diff --git a/wire/peer_wiregen.c b/wire/peer_wiregen.c index a68a87366..44dbac01c 100644 --- a/wire/peer_wiregen.c +++ b/wire/peer_wiregen.c @@ -2330,4 +2330,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec *htlc_maximum_msat = fromwire_amount_msat(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:d4f6f16581d26f95c512a5a98e962abe529ff37a70a7563bd41f25ac802bdb63 +// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd diff --git a/wire/peer_wiregen.h b/wire/peer_wiregen.h index 994b98a0e..7349fcf0a 100644 --- a/wire/peer_wiregen.h +++ b/wire/peer_wiregen.h @@ -859,4 +859,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec #endif /* LIGHTNING_WIRE_PEER_WIREGEN_H */ -// SHA256STAMP:d4f6f16581d26f95c512a5a98e962abe529ff37a70a7563bd41f25ac802bdb63 +// SHA256STAMP:aeea1df56a4d408e222ac2c9f2deb201fda3cd2062f3c65f1b3ca52e11600acd