Skip to content

BOLT12 recurrence spec update #8398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .msggen.json
Original file line number Diff line number Diff line change
Expand Up @@ -3128,11 +3128,14 @@
"Offer.description": 2,
"Offer.issuer": 3,
"Offer.label": 4,
"Offer.optional_recurrence": 14,
"Offer.proportional_amount": 15,
"Offer.quantity_max": 5,
"Offer.recurrence": 7,
"Offer.recurrence_base": 8,
"Offer.recurrence_limit": 10,
"Offer.recurrence_paywindow": 9,
"Offer.recurrence_proportional": 13,
"Offer.recurrence_start_any_period": 12,
"Offer.single_use": 11
},
Expand Down Expand Up @@ -11268,6 +11271,14 @@
"added": "pre-v0.10.1",
"deprecated": null
},
"Offer.optional_recurrence": {
"added": "v25.09",
"deprecated": null
},
"Offer.proportional_amount": {
"added": "v25.09",
"deprecated": null
},
"Offer.quantity_max": {
"added": "pre-v0.10.1",
"deprecated": null
Expand Down Expand Up @@ -11320,6 +11331,10 @@
"added": "pre-v0.10.1",
"deprecated": null
},
"Offer.recurrence_proportional": {
"added": "v25.09",
"deprecated": null
},
"Offer.recurrence_start_any_period": {
"added": "v24.02",
"deprecated": null
Expand Down
3 changes: 2 additions & 1 deletion cln-grpc/proto/node.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions cln-grpc/src/convert.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions cln-rpc/src/model.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 30 additions & 17 deletions common/bolt12.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,6 @@ static void add_months(struct tm *tm, u32 number)
tm->tm_mon += number;
}

static void add_years(struct tm *tm, u32 number)
{
tm->tm_year += number;
}

static u64 time_change(u64 prevstart, u32 number,
void (*add_time)(struct tm *tm, u32 number),
bool day_const)
Expand Down Expand Up @@ -412,8 +407,7 @@ u64 offer_period_start(u64 basetime, size_t n,
const struct recurrence *recur)
{
/* BOLT-recurrence #12:
* 1. A `time_unit` defining 0 (seconds), 1 (days), 2 (months),
* 3 (years).
* 1. A `time_unit` defining 0 (seconds), 1 (days), 2 (months).
*/
switch (recur->time_unit) {
case 0:
Expand All @@ -422,8 +416,6 @@ u64 offer_period_start(u64 basetime, size_t n,
return time_change(basetime, recur->period * n, add_days, false);
case 2:
return time_change(basetime, recur->period * n, add_months, true);
case 3:
return time_change(basetime, recur->period * n, add_years, true);
default:
/* This is our offer, how did we get here? */
return 0;
Expand All @@ -437,17 +429,17 @@ void offer_period_paywindow(const struct recurrence *recurrence,
u64 *start, u64 *end)
{
/* BOLT-recurrence #12:
* - if the offer contains `recurrence_paywindow`:
* - if `offer_recurrence_paywindow` is present:
*/
if (recurrence_paywindow) {
u64 pstart = offer_period_start(basetime, period_idx,
recurrence);
/* BOLT-recurrence #12:
* - if the offer has a `recurrence_basetime` or the
* - if `recurrence_basetime` is present or
* `recurrence_counter` is non-zero:
* - SHOULD NOT send an `invreq` for a period prior to
* - SHOULD NOT send an `invoice_request` for a period prior to
* `seconds_before` seconds before that period start.
* - SHOULD NOT send an `invreq` for a period later
* - SHOULD NOT send an `invoice_request` for a period later
* than `seconds_after` seconds past that period start.
*/
*start = pstart - recurrence_paywindow->seconds_before;
Expand All @@ -462,9 +454,9 @@ void offer_period_paywindow(const struct recurrence *recurrence,
} else {
/* BOLT-recurrence #12:
* - otherwise:
* - SHOULD NOT send an `invreq` with
* `recurrence_counter` is non-zero for a period whose
* immediate predecessor has not yet begun.
* - SHOULD NOT send an `invoice_request` with
* non-zero `recurrence_counter` for a period
* whose immediate predecessor has not yet begun.
*/
if (period_idx == 0)
*start = 0;
Expand All @@ -473,7 +465,7 @@ void offer_period_paywindow(const struct recurrence *recurrence,
recurrence);

/* BOLT-recurrence #12:
* - SHOULD NOT send an `invreq` for a period which
* - SHOULD NOT send an `invoice_request` for a period which
* has already passed.
*/
*end = offer_period_start(basetime, period_idx+1,
Expand Down Expand Up @@ -815,3 +807,24 @@ bool bolt12_bip353_valid_string(const u8 *str, size_t len)
}
return true;
}

const struct recurrence *offer_recurrence(const struct tlv_offer *offer)
{
if (offer->offer_recurrence_compulsory)
return offer->offer_recurrence_compulsory;
return offer->offer_recurrence_optional;
}

const struct recurrence *invreq_recurrence(const struct tlv_invoice_request *invreq)
{
if (invreq->offer_recurrence_compulsory)
return invreq->offer_recurrence_compulsory;
return invreq->offer_recurrence_optional;
}

const struct recurrence *invoice_recurrence(const struct tlv_invoice *inv)
{
if (inv->offer_recurrence_compulsory)
return inv->offer_recurrence_compulsory;
return inv->offer_recurrence_optional;
}
5 changes: 5 additions & 0 deletions common/bolt12.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,9 @@ const struct tlv_field *any_field_outside_range(const struct tlv_field *fields,
* `A`-`Z`, `-`, `_` or `.`.
*/
bool bolt12_bip353_valid_string(const u8 *str, size_t strlen);

/* Extract either offer_recurrence_compulsory or offer_recurrence_optional */
const struct recurrence *offer_recurrence(const struct tlv_offer *offer);
const struct recurrence *invreq_recurrence(const struct tlv_invoice_request *invreq);
const struct recurrence *invoice_recurrence(const struct tlv_invoice *inv);
#endif /* LIGHTNING_COMMON_BOLT12_H */
4 changes: 2 additions & 2 deletions common/json_param.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ bool param(struct command *cmd, const char *buffer,

/*
* Version which *doesn't* fail if command_check_only(cmd) is true:
* allows you can do extra checks after, but MUST still fail with
* command_param_failed(); if command_check_only(cmd) is true! */
* allows you can do extra checks after, but MUST terminate
* with command_check_done() if command_check_only(cmd) is true! */
bool param_check(struct command *cmd,
const char *buffer,
const jsmntok_t tokens[], ...) LAST_ARG_NULL;
Expand Down
Loading
Loading