offers: use existing copied fields.

We no longer have to refer back to the offer for which we're making
the invoice_request, or to the invoice_request we made for an invoice,
as they are all mirrored (and we check!).

It's clearer to simply look at the object directly.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-11-09 13:02:01 +10:30 committed by Christian Decker
parent bc283cecf2
commit 1d1174c286
2 changed files with 78 additions and 96 deletions

View File

@ -233,24 +233,22 @@ static struct command_result *handle_invreq_response(struct command *cmd,
goto badinv; goto badinv;
} }
/* FIXME-OFFERS: Examine fields in inv directly! */
/* Get the amount we expected: firstly, if that's what we sent, /* Get the amount we expected: firstly, if that's what we sent,
* secondly, if specified in the invoice. */ * secondly, if specified in the invoice. */
if (sent->invreq->invreq_amount) { if (inv->invreq_amount) {
expected_amount = tal_dup(tmpctx, u64, sent->invreq->invreq_amount); expected_amount = tal_dup(tmpctx, u64, inv->invreq_amount);
} else if (sent->offer->offer_amount && !sent->offer->offer_currency) { } else if (inv->offer_amount && !inv->offer_currency) {
expected_amount = tal(tmpctx, u64); expected_amount = tal(tmpctx, u64);
*expected_amount = *sent->offer->offer_amount; *expected_amount = *inv->offer_amount;
if (sent->invreq->invreq_quantity) { if (inv->invreq_quantity) {
/* We should never have sent this! */ /* We should never have sent this! */
if (mul_overflows_u64(*expected_amount, if (mul_overflows_u64(*expected_amount,
*sent->invreq->invreq_quantity)) { *inv->invreq_quantity)) {
badfield = "quantity overflow"; badfield = "quantity overflow";
goto badinv; goto badinv;
} }
*expected_amount *= *sent->invreq->invreq_quantity; *expected_amount *= *inv->invreq_quantity;
} }
} else } else
expected_amount = NULL; expected_amount = NULL;
@ -259,7 +257,7 @@ static struct command_result *handle_invreq_response(struct command *cmd,
* - if the offer contained `recurrence`: * - if the offer contained `recurrence`:
* - MUST reject the invoice if `recurrence_basetime` is not set. * - MUST reject the invoice if `recurrence_basetime` is not set.
*/ */
if (sent->invreq->invreq_recurrence_counter && !inv->invoice_recurrence_basetime) { if (inv->invreq_recurrence_counter && !inv->invoice_recurrence_basetime) {
badfield = "recurrence_basetime"; badfield = "recurrence_basetime";
goto badinv; goto badinv;
} }
@ -280,34 +278,34 @@ static struct command_result *handle_invreq_response(struct command *cmd,
json_object_end(out); json_object_end(out);
/* We tell them about next period at this point, if any. */ /* We tell them about next period at this point, if any. */
if (sent->offer->offer_recurrence) { if (inv->offer_recurrence) {
u64 next_counter, next_period_idx; u64 next_counter, next_period_idx;
u64 paywindow_start, paywindow_end; u64 paywindow_start, paywindow_end;
next_counter = *sent->invreq->invreq_recurrence_counter + 1; next_counter = *inv->invreq_recurrence_counter + 1;
if (sent->invreq->invreq_recurrence_start) if (inv->invreq_recurrence_start)
next_period_idx = *sent->invreq->invreq_recurrence_start next_period_idx = *inv->invreq_recurrence_start
+ next_counter; + next_counter;
else else
next_period_idx = next_counter; next_period_idx = next_counter;
/* If this was the last, don't tell them about a next! */ /* If this was the last, don't tell them about a next! */
if (!sent->offer->offer_recurrence_limit if (!inv->offer_recurrence_limit
|| next_period_idx <= *sent->offer->offer_recurrence_limit) { || next_period_idx <= *inv->offer_recurrence_limit) {
json_object_start(out, "next_period"); json_object_start(out, "next_period");
json_add_u64(out, "counter", next_counter); json_add_u64(out, "counter", next_counter);
json_add_u64(out, "starttime", json_add_u64(out, "starttime",
offer_period_start(*inv->invoice_recurrence_basetime, offer_period_start(*inv->invoice_recurrence_basetime,
next_period_idx, next_period_idx,
sent->offer->offer_recurrence)); inv->offer_recurrence));
json_add_u64(out, "endtime", json_add_u64(out, "endtime",
offer_period_start(*inv->invoice_recurrence_basetime, offer_period_start(*inv->invoice_recurrence_basetime,
next_period_idx + 1, next_period_idx + 1,
sent->offer->offer_recurrence) - 1); inv->offer_recurrence) - 1);
offer_period_paywindow(sent->offer->offer_recurrence, offer_period_paywindow(inv->offer_recurrence,
sent->offer->offer_recurrence_paywindow, inv->offer_recurrence_paywindow,
sent->offer->offer_recurrence_base, inv->offer_recurrence_base,
*inv->invoice_recurrence_basetime, *inv->invoice_recurrence_basetime,
next_period_idx, next_period_idx,
&paywindow_start, &paywindow_end); &paywindow_start, &paywindow_end);
@ -846,13 +844,13 @@ static struct command_result *invreq_done(struct command *cmd,
* - MUST NOT send an `invoice_request` for a period greater * - MUST NOT send an `invoice_request` for a period greater
* than `max_period` * than `max_period`
*/ */
if (sent->offer->offer_recurrence_limit if (sent->invreq->offer_recurrence_limit
&& period_idx > *sent->offer->offer_recurrence_limit) && period_idx > *sent->invreq->offer_recurrence_limit)
return command_fail(cmd, LIGHTNINGD, return command_fail(cmd, LIGHTNINGD,
"Can't send invreq for period %" "Can't send invreq for period %"
PRIu64" (limit %u)", PRIu64" (limit %u)",
period_idx, period_idx,
*sent->offer->offer_recurrence_limit); *sent->invreq->offer_recurrence_limit);
/* BOLT-offers-recurrence #12: /* BOLT-offers-recurrence #12:
* - SHOULD NOT send an `invoice_request` for a period which has * - SHOULD NOT send an `invoice_request` for a period which has
@ -865,8 +863,8 @@ static struct command_result *invreq_done(struct command *cmd,
if (pbtok) { if (pbtok) {
base = tal(tmpctx, u64); base = tal(tmpctx, u64);
json_to_u64(buf, pbtok, base); json_to_u64(buf, pbtok, base);
} else if (sent->offer->offer_recurrence_base) } else if (sent->invreq->offer_recurrence_base)
base = &sent->offer->offer_recurrence_base->basetime; base = &sent->invreq->offer_recurrence_base->basetime;
else { else {
/* happens with *recurrence_base == 0 */ /* happens with *recurrence_base == 0 */
assert(*sent->invreq->invreq_recurrence_counter == 0); assert(*sent->invreq->invreq_recurrence_counter == 0);
@ -875,9 +873,9 @@ static struct command_result *invreq_done(struct command *cmd,
if (base) { if (base) {
u64 period_start, period_end, now = time_now().ts.tv_sec; u64 period_start, period_end, now = time_now().ts.tv_sec;
offer_period_paywindow(sent->offer->offer_recurrence, offer_period_paywindow(sent->invreq->offer_recurrence,
sent->offer->offer_recurrence_paywindow, sent->invreq->offer_recurrence_paywindow,
sent->offer->offer_recurrence_base, sent->invreq->offer_recurrence_base,
*base, period_idx, *base, period_idx,
&period_start, &period_end); &period_start, &period_end);
if (now < period_start) if (now < period_start)
@ -896,9 +894,9 @@ static struct command_result *invreq_done(struct command *cmd,
} }
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin,
sent->offer->offer_node_id); sent->invreq->offer_node_id);
if (!sent->path) if (!sent->path)
return connect_direct(cmd, sent->offer->offer_node_id, return connect_direct(cmd, sent->invreq->offer_node_id,
sendinvreq_after_connect, sent); sendinvreq_after_connect, sent);
return sendinvreq_after_connect(cmd, NULL, NULL, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent);
@ -954,9 +952,9 @@ force_payer_secret(struct command *cmd,
} }
sent->path = path_to_node(sent, cmd->plugin, sent->path = path_to_node(sent, cmd->plugin,
sent->offer->offer_node_id); sent->invreq->offer_node_id);
if (!sent->path) if (!sent->path)
return connect_direct(cmd, sent->offer->offer_node_id, return connect_direct(cmd, sent->invreq->offer_node_id,
sendinvreq_after_connect, sent); sendinvreq_after_connect, sent);
return sendinvreq_after_connect(cmd, NULL, NULL, sent); return sendinvreq_after_connect(cmd, NULL, NULL, sent);
@ -1021,7 +1019,7 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
* amount expected by `offer_amount` (and, if present, * amount expected by `offer_amount` (and, if present,
* `offer_currency` and `invreq_quantity`). * `offer_currency` and `invreq_quantity`).
*/ */
if (sent->offer->offer_amount) { if (invreq->offer_amount) {
/* FIXME: Check after quantity? */ /* FIXME: Check after quantity? */
if (msat) { if (msat) {
invreq->invreq_amount = tal_dup(invreq, u64, invreq->invreq_amount = tal_dup(invreq, u64,
@ -1035,7 +1033,6 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
&msat->millisatoshis); /* Raw: tu64 */ &msat->millisatoshis); /* Raw: tu64 */
} }
/* FIXME-OFFERS: Examine fields in inv directly! */
/* BOLT-offers #12: /* BOLT-offers #12:
* - if `offer_quantity_max` is present: * - if `offer_quantity_max` is present:
* - MUST set `invreq_quantity` * - MUST set `invreq_quantity`
@ -1043,15 +1040,15 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
* - MUST set `invreq_quantity` less than or equal to * - MUST set `invreq_quantity` less than or equal to
* `offer_quantity_max`. * `offer_quantity_max`.
*/ */
if (sent->offer->offer_quantity_max) { if (invreq->offer_quantity_max) {
if (!invreq->invreq_quantity) if (!invreq->invreq_quantity)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"quantity parameter required"); "quantity parameter required");
if (*sent->offer->offer_quantity_max if (*invreq->offer_quantity_max
&& *invreq->invreq_quantity > *sent->offer->offer_quantity_max) && *invreq->invreq_quantity > *invreq->offer_quantity_max)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"quantity must be <= %"PRIu64, "quantity must be <= %"PRIu64,
*sent->offer->offer_quantity_max); *invreq->offer_quantity_max);
} else { } else {
if (invreq->invreq_quantity) if (invreq->invreq_quantity)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
@ -1061,7 +1058,7 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
/* BOLT-offers-recurrence #12: /* BOLT-offers-recurrence #12:
* - if the offer contained `recurrence`: * - if the offer contained `recurrence`:
*/ */
if (sent->offer->offer_recurrence) { if (invreq->offer_recurrence) {
/* BOLT-offers-recurrence #12: /* BOLT-offers-recurrence #12:
* - for the initial request: * - for the initial request:
*... *...
@ -1085,8 +1082,8 @@ static struct command_result *json_fetchinvoice(struct command *cmd,
* - otherwise: * - otherwise:
* - MUST NOT include `recurrence_start` * - MUST NOT include `recurrence_start`
*/ */
if (sent->offer->offer_recurrence_base if (invreq->offer_recurrence_base
&& sent->offer->offer_recurrence_base->start_any_period) { && invreq->offer_recurrence_base->start_any_period) {
if (!invreq->invreq_recurrence_start) if (!invreq->invreq_recurrence_start)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"needs recurrence_start"); "needs recurrence_start");

View File

@ -20,8 +20,6 @@ struct invreq {
struct tlv_invoice_request *invreq; struct tlv_invoice_request *invreq;
struct blinded_path *reply_path; struct blinded_path *reply_path;
/* The offer, once we've looked it up. */
struct tlv_offer *offer;
/* The offer id */ /* The offer id */
struct sha256 offer_id; struct sha256 offer_id;
@ -437,8 +435,8 @@ static struct command_result *check_period(struct command *cmd,
struct command_result *err; struct command_result *err;
/* If we have a recurrence base, that overrides. */ /* If we have a recurrence base, that overrides. */
if (ir->offer->offer_recurrence_base) if (ir->invreq->offer_recurrence_base)
basetime = ir->offer->offer_recurrence_base->basetime; basetime = ir->invreq->offer_recurrence_base->basetime;
/* BOLT-offers-recurrence #12: /* BOLT-offers-recurrence #12:
* - if the invoice corresponds to an offer with `recurrence`: * - if the invoice corresponds to an offer with `recurrence`:
@ -458,8 +456,8 @@ static struct command_result *check_period(struct command *cmd,
* `recurrence_start` field plus the `recurrence_counter` * `recurrence_start` field plus the `recurrence_counter`
* `counter` field. * `counter` field.
*/ */
if (ir->offer->offer_recurrence_base if (ir->invreq->offer_recurrence_base
&& ir->offer->offer_recurrence_base->start_any_period) { && ir->invreq->offer_recurrence_base->start_any_period) {
err = invreq_must_have(cmd, ir, invreq_recurrence_start); err = invreq_must_have(cmd, ir, invreq_recurrence_start);
if (err) if (err)
return err; return err;
@ -490,16 +488,16 @@ static struct command_result *check_period(struct command *cmd,
* - MUST fail the request if the period index is greater than * - MUST fail the request if the period index is greater than
* `max_period`. * `max_period`.
*/ */
if (ir->offer->offer_recurrence_limit if (ir->invreq->offer_recurrence_limit
&& period_idx > *ir->offer->offer_recurrence_limit) { && period_idx > *ir->invreq->offer_recurrence_limit) {
return fail_invreq(cmd, ir, return fail_invreq(cmd, ir,
"period_index %"PRIu64" too great", "period_index %"PRIu64" too great",
period_idx); period_idx);
} }
offer_period_paywindow(ir->offer->offer_recurrence, offer_period_paywindow(ir->invreq->offer_recurrence,
ir->offer->offer_recurrence_paywindow, ir->invreq->offer_recurrence_paywindow,
ir->offer->offer_recurrence_base, ir->invreq->offer_recurrence_base,
basetime, period_idx, basetime, period_idx,
&paywindow_start, &paywindow_end); &paywindow_start, &paywindow_end);
if (*ir->inv->invoice_created_at < paywindow_start) { if (*ir->inv->invoice_created_at < paywindow_start) {
@ -530,12 +528,12 @@ static struct command_result *check_period(struct command *cmd,
* remaining in the period. * remaining in the period.
*/ */
if (*ir->invreq->invreq_recurrence_counter != 0 if (*ir->invreq->invreq_recurrence_counter != 0
&& ir->offer->offer_recurrence_paywindow && ir->invreq->offer_recurrence_paywindow
&& ir->offer->offer_recurrence_paywindow->proportional_amount == 1) { && ir->invreq->offer_recurrence_paywindow->proportional_amount == 1) {
u64 start = offer_period_start(basetime, period_idx, u64 start = offer_period_start(basetime, period_idx,
ir->offer->offer_recurrence); ir->invreq->offer_recurrence);
u64 end = offer_period_start(basetime, period_idx + 1, u64 end = offer_period_start(basetime, period_idx + 1,
ir->offer->offer_recurrence); ir->invreq->offer_recurrence);
if (*ir->inv->invoice_created_at > start) { if (*ir->inv->invoice_created_at > start) {
*ir->inv->invoice_amount *ir->inv->invoice_amount
@ -644,12 +642,12 @@ static struct command_result *invreq_amount_by_quantity(struct command *cmd,
const struct invreq *ir, const struct invreq *ir,
u64 *raw_amt) u64 *raw_amt)
{ {
assert(ir->offer->offer_amount); assert(ir->invreq->offer_amount);
/* BOLT-offers #12: /* BOLT-offers #12:
* - MUST calculate the *base invoice amount* using the offer `amount`: * - MUST calculate the *base invoice amount* using the offer `amount`:
*/ */
*raw_amt = *ir->offer->offer_amount; *raw_amt = *ir->invreq->offer_amount;
/* BOLT-offers #12: /* BOLT-offers #12:
* - if request contains `quantity`, multiply by `quantity`. * - if request contains `quantity`, multiply by `quantity`.
@ -674,9 +672,9 @@ static struct command_result *invreq_base_amount_simple(struct command *cmd,
{ {
struct command_result *err; struct command_result *err;
if (ir->offer->offer_amount) { if (ir->invreq->offer_amount) {
u64 raw_amount; u64 raw_amount;
assert(!ir->offer->offer_currency); assert(!ir->invreq->offer_currency);
err = invreq_amount_by_quantity(cmd, ir, &raw_amount); err = invreq_amount_by_quantity(cmd, ir, &raw_amount);
if (err) if (err)
return err; return err;
@ -711,7 +709,7 @@ static struct command_result *handle_amount_and_recurrence(struct command *cmd,
* - MUST fail the request if its `amount` is less than the * - MUST fail the request if its `amount` is less than the
* *base invoice amount*. * *base invoice amount*.
*/ */
if (ir->offer->offer_amount && ir->invreq->invreq_amount) { if (ir->invreq->offer_amount && ir->invreq->invreq_amount) {
if (amount_msat_less(amount_msat(*ir->invreq->invreq_amount), base_inv_amount)) { if (amount_msat_less(amount_msat(*ir->invreq->invreq_amount), base_inv_amount)) {
return fail_invreq(cmd, ir, "Amount must be at least %s", return fail_invreq(cmd, ir, "Amount must be at least %s",
type_to_string(tmpctx, struct amount_msat, type_to_string(tmpctx, struct amount_msat,
@ -763,16 +761,16 @@ static struct command_result *currency_done(struct command *cmd,
if (!msat) if (!msat)
return fail_internalerr(cmd, ir, return fail_internalerr(cmd, ir,
"Cannot convert currency %.*s: %.*s", "Cannot convert currency %.*s: %.*s",
(int)tal_bytelen(ir->offer->offer_currency), (int)tal_bytelen(ir->invreq->offer_currency),
(const char *)ir->offer->offer_currency, (const char *)ir->invreq->offer_currency,
json_tok_full_len(result), json_tok_full_len(result),
json_tok_full(buf, result)); json_tok_full(buf, result));
if (!json_to_msat(buf, msat, &amount)) if (!json_to_msat(buf, msat, &amount))
return fail_internalerr(cmd, ir, return fail_internalerr(cmd, ir,
"Bad convert for currency %.*s: %.*s", "Bad convert for currency %.*s: %.*s",
(int)tal_bytelen(ir->offer->offer_currency), (int)tal_bytelen(ir->invreq->offer_currency),
(const char *)ir->offer->offer_currency, (const char *)ir->invreq->offer_currency,
json_tok_full_len(msat), json_tok_full_len(msat),
json_tok_full(buf, msat)); json_tok_full(buf, msat));
@ -788,7 +786,7 @@ static struct command_result *convert_currency(struct command *cmd,
struct command_result *err; struct command_result *err;
const struct iso4217_name_and_divisor *iso4217; const struct iso4217_name_and_divisor *iso4217;
assert(ir->offer->offer_currency); assert(ir->invreq->offer_currency);
/* Multiply by quantity *first*, for best precision */ /* Multiply by quantity *first*, for best precision */
err = invreq_amount_by_quantity(cmd, ir, &raw_amount); err = invreq_amount_by_quantity(cmd, ir, &raw_amount);
@ -801,14 +799,14 @@ static struct command_result *convert_currency(struct command *cmd,
* - if offer `currency` is not the invoice currency, convert * - if offer `currency` is not the invoice currency, convert
* to the invoice currency. * to the invoice currency.
*/ */
iso4217 = find_iso4217(ir->offer->offer_currency, iso4217 = find_iso4217(ir->invreq->offer_currency,
tal_bytelen(ir->offer->offer_currency)); tal_bytelen(ir->invreq->offer_currency));
/* We should not create offer with unknown currency! */ /* We should not create offer with unknown currency! */
if (!iso4217) if (!iso4217)
return fail_internalerr(cmd, ir, return fail_internalerr(cmd, ir,
"Unknown offer currency %.*s", "Unknown offer currency %.*s",
(int)tal_bytelen(ir->offer->offer_currency), (int)tal_bytelen(ir->invreq->offer_currency),
ir->offer->offer_currency); ir->invreq->offer_currency);
double_amount = (double)raw_amount; double_amount = (double)raw_amount;
for (size_t i = 0; i < iso4217->minor_unit; i++) for (size_t i = 0; i < iso4217->minor_unit; i++)
double_amount /= 10; double_amount /= 10;
@ -816,8 +814,8 @@ static struct command_result *convert_currency(struct command *cmd,
req = jsonrpc_request_start(cmd->plugin, cmd, "currencyconvert", req = jsonrpc_request_start(cmd->plugin, cmd, "currencyconvert",
currency_done, error, ir); currency_done, error, ir);
json_add_stringn(req->js, "currency", json_add_stringn(req->js, "currency",
(const char *)ir->offer->offer_currency, (const char *)ir->invreq->offer_currency,
tal_bytelen(ir->offer->offer_currency)); tal_bytelen(ir->invreq->offer_currency));
json_add_primitive_fmt(req->js, "amount", "%f", double_amount); json_add_primitive_fmt(req->js, "amount", "%f", double_amount);
return send_outreq(cmd->plugin, req); return send_outreq(cmd->plugin, req);
} }
@ -830,7 +828,6 @@ static struct command_result *listoffers_done(struct command *cmd,
const jsmntok_t *arr = json_get_member(buf, result, "offers"); const jsmntok_t *arr = json_get_member(buf, result, "offers");
const jsmntok_t *offertok, *activetok, *b12tok; const jsmntok_t *offertok, *activetok, *b12tok;
bool active; bool active;
char *fail;
struct command_result *err; struct command_result *err;
struct amount_msat amt; struct amount_msat amt;
@ -855,6 +852,8 @@ static struct command_result *listoffers_done(struct command *cmd,
if (!active) if (!active)
return fail_invreq(cmd, ir, "Offer no longer available"); return fail_invreq(cmd, ir, "Offer no longer available");
/* Now, since we looked up by hash, we know that the entire offer
* is faithfully mirrored in this invreq. */
b12tok = json_get_member(buf, offertok, "bolt12"); b12tok = json_get_member(buf, offertok, "bolt12");
if (!b12tok) { if (!b12tok) {
return fail_internalerr(cmd, ir, return fail_internalerr(cmd, ir,
@ -863,22 +862,8 @@ static struct command_result *listoffers_done(struct command *cmd,
json_tok_full(buf, offertok)); json_tok_full(buf, offertok));
} }
/* FIXME-OFFERS: we have these fields in invreq! */ if (ir->invreq->offer_absolute_expiry
ir->offer = offer_decode(ir, && time_now().ts.tv_sec >= *ir->invreq->offer_absolute_expiry) {
buf + b12tok->start,
b12tok->end - b12tok->start,
plugin_feature_set(cmd->plugin),
chainparams, &fail);
if (!ir->offer) {
return fail_internalerr(cmd, ir,
"Invalid offer: %s (%.*s)",
fail,
json_tok_full_len(offertok),
json_tok_full(buf, offertok));
}
if (ir->offer->offer_absolute_expiry
&& time_now().ts.tv_sec >= *ir->offer->offer_absolute_expiry) {
/* FIXME: do deloffer to disable it */ /* FIXME: do deloffer to disable it */
return fail_invreq(cmd, ir, "Offer expired"); return fail_invreq(cmd, ir, "Offer expired");
} }
@ -892,7 +877,7 @@ static struct command_result *listoffers_done(struct command *cmd,
* - otherwise: * - otherwise:
* - MUST fail the request if there is an `invreq_quantity` field. * - MUST fail the request if there is an `invreq_quantity` field.
*/ */
if (ir->offer->offer_quantity_max) { if (ir->invreq->offer_quantity_max) {
err = invreq_must_have(cmd, ir, invreq_quantity); err = invreq_must_have(cmd, ir, invreq_quantity);
if (err) if (err)
return err; return err;
@ -901,12 +886,12 @@ static struct command_result *listoffers_done(struct command *cmd,
return fail_invreq(cmd, ir, return fail_invreq(cmd, ir,
"quantity zero invalid"); "quantity zero invalid");
if (*ir->offer->offer_quantity_max && if (*ir->invreq->offer_quantity_max &&
*ir->invreq->invreq_quantity > *ir->offer->offer_quantity_max) { *ir->invreq->invreq_quantity > *ir->invreq->offer_quantity_max) {
return fail_invreq(cmd, ir, return fail_invreq(cmd, ir,
"quantity %"PRIu64" > %"PRIu64, "quantity %"PRIu64" > %"PRIu64,
*ir->invreq->invreq_quantity, *ir->invreq->invreq_quantity,
*ir->offer->offer_quantity_max); *ir->invreq->offer_quantity_max);
} }
} else { } else {
err = invreq_must_not_have(cmd, ir, invreq_quantity); err = invreq_must_not_have(cmd, ir, invreq_quantity);
@ -928,7 +913,7 @@ static struct command_result *listoffers_done(struct command *cmd,
return fail_invreq(cmd, ir, "bad signature"); return fail_invreq(cmd, ir, "bad signature");
} }
if (ir->offer->offer_recurrence) { if (ir->invreq->offer_recurrence) {
/* BOLT-offers-recurrence #12: /* BOLT-offers-recurrence #12:
* *
* - if the offer had a `recurrence`: * - if the offer had a `recurrence`:
@ -993,7 +978,7 @@ static struct command_result *listoffers_done(struct command *cmd,
= plugin_feature_set(cmd->plugin)->bits[BOLT12_INVOICE_FEATURE]; = plugin_feature_set(cmd->plugin)->bits[BOLT12_INVOICE_FEATURE];
/* We may require currency lookup; if so, do it now. */ /* We may require currency lookup; if so, do it now. */
if (ir->offer->offer_amount && ir->offer->offer_currency) if (ir->invreq->offer_amount && ir->invreq->offer_currency)
return convert_currency(cmd, ir); return convert_currency(cmd, ir);
err = invreq_base_amount_simple(cmd, ir, &amt); err = invreq_base_amount_simple(cmd, ir, &amt);