diff --git a/common/bolt12.c b/common/bolt12.c index db9408210..5ab64f31e 100644 --- a/common/bolt12.c +++ b/common/bolt12.c @@ -8,11 +8,11 @@ #include #include -bool bolt12_chains_match(const struct bitcoin_blkid *chains, - const struct chainparams *must_be_chain) +/* If chains is NULL, max_num_chains is ignored */ +static bool bolt12_chains_match(const struct bitcoin_blkid *chains, + size_t max_num_chains, + const struct chainparams *must_be_chain) { - size_t num_chains; - /* BOLT-offers #12: * - if the chain for the invoice is not solely bitcoin: * - MUST specify `chains` the offer is valid for. @@ -27,13 +27,12 @@ bool bolt12_chains_match(const struct bitcoin_blkid *chains, * - otherwise: * - MUST fail the request if `chain` is not a supported chain. */ - num_chains = tal_count(chains); - if (num_chains == 0) { - num_chains = 1; + if (!chains) { + max_num_chains = 1; chains = &chainparams_for_network("bitcoin")->genesis_blockhash; } - for (size_t i = 0; i < num_chains; i++) { + for (size_t i = 0; i < max_num_chains; i++) { if (bitcoin_blkid_eq(&chains[i], &must_be_chain->genesis_blockhash)) return true; @@ -43,28 +42,20 @@ bool bolt12_chains_match(const struct bitcoin_blkid *chains, } bool bolt12_chain_matches(const struct bitcoin_blkid *chain, - const struct chainparams *must_be_chain, - const struct bitcoin_blkid *deprecated_chains) + const struct chainparams *must_be_chain) { - /* Obsolete: We used to put an array in here, but we only ever - * used a single value */ - if (deprecated_apis && !chain) - chain = deprecated_chains; - - if (!chain) - chain = &chainparams_for_network("bitcoin")->genesis_blockhash; - - return bitcoin_blkid_eq(chain, &must_be_chain->genesis_blockhash); + return bolt12_chains_match(chain, 1, must_be_chain); } static char *check_features_and_chain(const tal_t *ctx, const struct feature_set *our_features, const struct chainparams *must_be_chain, const u8 *features, - const struct bitcoin_blkid *chains) + const struct bitcoin_blkid *chains, + size_t num_chains) { if (must_be_chain) { - if (!bolt12_chains_match(chains, must_be_chain)) + if (!bolt12_chains_match(chains, num_chains, must_be_chain)) return tal_fmt(ctx, "wrong chain"); } @@ -190,7 +181,8 @@ struct tlv_offer *offer_decode(const tal_t *ctx, *fail = check_features_and_chain(ctx, our_features, must_be_chain, offer->features, - offer->chains); + offer->chains, + tal_count(offer->chains)); if (*fail) return tal_free(offer); @@ -242,9 +234,7 @@ struct tlv_invoice_request *invrequest_decode(const tal_t *ctx, *fail = check_features_and_chain(ctx, our_features, must_be_chain, invrequest->features, - invrequest->chain - ? invrequest->chain - : invrequest->chains); + invrequest->chain, 1); if (*fail) return tal_free(invrequest); @@ -283,8 +273,7 @@ struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx, *fail = check_features_and_chain(ctx, our_features, must_be_chain, invoice->features, - invoice->chain - ? invoice->chain : invoice->chains); + invoice->chain, 1); if (*fail) return tal_free(invoice); diff --git a/common/bolt12.h b/common/bolt12.h index e1b0c00e7..e451c2897 100644 --- a/common/bolt12.h +++ b/common/bolt12.h @@ -99,14 +99,9 @@ bool bolt12_check_signature(const struct tlv_field *fields, const struct point32 *key, const struct bip340sig *sig); -/* Given a tal_arr of chains, does it contain this chain? */ -bool bolt12_chains_match(const struct bitcoin_blkid *chains, - const struct chainparams *must_be_chain); - /* Given a single bolt12 chain, does it match? (NULL == bitcoin) */ bool bolt12_chain_matches(const struct bitcoin_blkid *chain, - const struct chainparams *must_be_chain, - const struct bitcoin_blkid *deprecated_chains); + const struct chainparams *must_be_chain); /* Given a basetime, when does period N start? */ u64 offer_period_start(u64 basetime, size_t n, diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index 1df3dd64c..afc185f0c 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -1383,10 +1383,6 @@ static struct command_result *json_fetchinvoice(struct command *cmd, * - the bitcoin chain is implied as the first and only entry. */ if (!streq(chainparams->network_name, "bitcoin")) { - if (deprecated_apis) { - invreq->chains = tal_arr(invreq, struct bitcoin_blkid, 1); - invreq->chains[0] = chainparams->genesis_blockhash; - } invreq->chain = tal_dup(invreq, struct bitcoin_blkid, &chainparams->genesis_blockhash); } @@ -1780,10 +1776,6 @@ static struct command_result *json_sendinvoice(struct command *cmd, * - the bitcoin chain is implied as the first and only entry. */ if (!streq(chainparams->network_name, "bitcoin")) { - if (deprecated_apis) { - sent->inv->chains = tal_arr(sent->inv, struct bitcoin_blkid, 1); - sent->inv->chains[0] = chainparams->genesis_blockhash; - } sent->inv->chain = tal_dup(sent->inv, struct bitcoin_blkid, &chainparams->genesis_blockhash); } diff --git a/plugins/offers.c b/plugins/offers.c index c4e131971..7e6a933a1 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -539,8 +539,6 @@ static void json_add_b12_invoice(struct json_stream *js, { bool valid = true; - if (invoice->chains) - json_add_chains(js, invoice->chains); if (invoice->chain) json_add_sha256(js, "chain", &invoice->chain->shad.sha); if (invoice->offer_id) @@ -679,7 +677,7 @@ static void json_add_b12_invoice(struct json_stream *js, if (invoice->fallbacks) valid &= json_add_fallbacks(js, - invoice->chain ? invoice->chain : invoice->chains, + invoice->chain, invoice->fallbacks->fallbacks); /* BOLT-offers #12: @@ -726,8 +724,6 @@ static void json_add_invoice_request(struct json_stream *js, { bool valid = true; - if (invreq->chains) - json_add_chains(js, invreq->chains); if (invreq->chain) json_add_sha256(js, "chain", &invreq->chain->shad.sha); diff --git a/plugins/offers_inv_hook.c b/plugins/offers_inv_hook.c index e68b79aa6..765e2da3e 100644 --- a/plugins/offers_inv_hook.c +++ b/plugins/offers_inv_hook.c @@ -359,9 +359,9 @@ struct command_result *handle_invoice(struct command *cmd, * - otherwise: * - MUST fail the request if `chain` is not a supported chain. */ - if (!bolt12_chain_matches(inv->inv->chain, chainparams, inv->inv->chains)) { + if (!bolt12_chain_matches(inv->inv->chain, chainparams)) { return fail_inv(cmd, inv, - "Wrong chains %s", + "Wrong chain %s", tal_hex(tmpctx, inv->inv->chain)); } diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index 84c8f36f5..4562c7d7d 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -754,10 +754,6 @@ static struct command_result *listoffers_done(struct command *cmd, * - MUST specify `chains` the offer is valid for. */ if (!streq(chainparams->network_name, "bitcoin")) { - if (deprecated_apis) { - ir->inv->chains = tal_arr(ir->inv, struct bitcoin_blkid, 1); - ir->inv->chains[0] = chainparams->genesis_blockhash; - } ir->inv->chain = tal_dup(ir->inv, struct bitcoin_blkid, &chainparams->genesis_blockhash); } @@ -875,8 +871,7 @@ struct command_result *handle_invoice_request(struct command *cmd, * - otherwise: * - MUST fail the request if `chain` is not a supported chain. */ - if (!bolt12_chain_matches(ir->invreq->chain, chainparams, - ir->invreq->chains)) { + if (!bolt12_chain_matches(ir->invreq->chain, chainparams)) { return fail_invreq(cmd, ir, "Wrong chain %s", tal_hex(tmpctx, ir->invreq->chain)); diff --git a/wire/bolt12_exp_wire.csv b/wire/bolt12_exp_wire.csv index a53ca3cdf..4077edb8d 100644 --- a/wire/bolt12_exp_wire.csv +++ b/wire/bolt12_exp_wire.csv @@ -42,8 +42,6 @@ subtypedata,blinded_path,first_node_id,point, subtypedata,blinded_path,blinding,point, subtypedata,blinded_path,num_hops,byte, subtypedata,blinded_path,path,onionmsg_path,num_hops -tlvtype,invoice_request,chains,2 -tlvdata,invoice_request,chains,chains,chain_hash,... tlvtype,invoice_request,chain,3 tlvdata,invoice_request,chain,chain,chain_hash, tlvtype,invoice_request,offer_id,4 @@ -68,8 +66,6 @@ tlvtype,invoice_request,replace_invoice,56 tlvdata,invoice_request,replace_invoice,payment_hash,sha256, tlvtype,invoice_request,payer_signature,240 tlvdata,invoice_request,payer_signature,sig,bip340sig, -tlvtype,invoice,chains,2 -tlvdata,invoice,chains,chains,chain_hash,... tlvtype,invoice,chain,3 tlvdata,invoice,chain,chain,chain_hash, tlvtype,invoice,offer_id,4 diff --git a/wire/bolt12_wire.csv b/wire/bolt12_wire.csv index a53ca3cdf..4077edb8d 100644 --- a/wire/bolt12_wire.csv +++ b/wire/bolt12_wire.csv @@ -42,8 +42,6 @@ subtypedata,blinded_path,first_node_id,point, subtypedata,blinded_path,blinding,point, subtypedata,blinded_path,num_hops,byte, subtypedata,blinded_path,path,onionmsg_path,num_hops -tlvtype,invoice_request,chains,2 -tlvdata,invoice_request,chains,chains,chain_hash,... tlvtype,invoice_request,chain,3 tlvdata,invoice_request,chain,chain,chain_hash, tlvtype,invoice_request,offer_id,4 @@ -68,8 +66,6 @@ tlvtype,invoice_request,replace_invoice,56 tlvdata,invoice_request,replace_invoice,payment_hash,sha256, tlvtype,invoice_request,payer_signature,240 tlvdata,invoice_request,payer_signature,sig,bip340sig, -tlvtype,invoice,chains,2 -tlvdata,invoice,chains,chains,chain_hash,... tlvtype,invoice,chain,3 tlvdata,invoice,chain,chain,chain_hash, tlvtype,invoice,offer_id,4 diff --git a/wire/extracted_bolt12_01_recurrence.patch b/wire/extracted_bolt12_01_recurrence.patch new file mode 100644 index 000000000..186841e47 --- /dev/null +++ b/wire/extracted_bolt12_01_recurrence.patch @@ -0,0 +1,48 @@ +diff --git b/wire/bolt12_wire.csv a/wire/bolt12_wire.csv +index 726c3c0a1..a53ca3cdf 100644 +--- b/wire/bolt12_wire.csv ++++ a/wire/bolt12_wire.csv +@@ -18,6 +18,18 @@ tlvtype,offer,quantity_min,22 + tlvdata,offer,quantity_min,min,tu64, + tlvtype,offer,quantity_max,24 + tlvdata,offer,quantity_max,max,tu64, ++tlvtype,offer,recurrence,26 ++tlvdata,offer,recurrence,time_unit,byte, ++tlvdata,offer,recurrence,period,tu32, ++tlvtype,offer,recurrence_paywindow,64 ++tlvdata,offer,recurrence_paywindow,seconds_before,u32, ++tlvdata,offer,recurrence_paywindow,proportional_amount,byte, ++tlvdata,offer,recurrence_paywindow,seconds_after,tu32, ++tlvtype,offer,recurrence_limit,66 ++tlvdata,offer,recurrence_limit,max_period,tu32, ++tlvtype,offer,recurrence_base,28 ++tlvdata,offer,recurrence_base,start_any_period,byte, ++tlvdata,offer,recurrence_base,basetime,tu64, + tlvtype,offer,node_id,30 + tlvdata,offer,node_id,node_id,point32, + tlvtype,offer,send_invoice,54 +@@ -40,6 +54,10 @@ tlvtype,invoice_request,features,12 + tlvdata,invoice_request,features,features,byte,... + tlvtype,invoice_request,quantity,32 + tlvdata,invoice_request,quantity,quantity,tu64, ++tlvtype,invoice_request,recurrence_counter,36 ++tlvdata,invoice_request,recurrence_counter,counter,tu32, ++tlvtype,invoice_request,recurrence_start,68 ++tlvdata,invoice_request,recurrence_start,period_offset,tu32, + tlvtype,invoice_request,payer_key,38 + tlvdata,invoice_request,payer_key,key,point32, + tlvtype,invoice_request,payer_note,39 +@@ -74,6 +94,13 @@ tlvtype,invoice,quantity,32 + tlvdata,invoice,quantity,quantity,tu64, + tlvtype,invoice,refund_for,34 + tlvdata,invoice,refund_for,refunded_payment_hash,sha256, ++tlvtype,invoice,recurrence_counter,36 ++tlvdata,invoice,recurrence_counter,counter,tu32, ++tlvtype,invoice,send_invoice,54 ++tlvtype,invoice,recurrence_start,68 ++tlvdata,invoice,recurrence_start,period_offset,tu32, ++tlvtype,invoice,recurrence_basetime,64 ++tlvdata,invoice,recurrence_basetime,basetime,tu64, + tlvtype,invoice,payer_key,38 + tlvdata,invoice,payer_key,key,point32, + tlvtype,invoice,payer_note,39