BOLT 12: update to include replace_invoice options.

We don't support it (yet), but update the spec to include it.

We include the previous field (recurrence_signature) as a shim for the
moment, for compat with existing nodes.  It's ugly, but next release
we'll stop *sending* it, then finally we'll stop accepting it!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-07-02 09:41:35 +09:30
parent f9fe814ea3
commit 18b6aa5e66
20 changed files with 311 additions and 63 deletions

View File

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