Browse Source

lightningd: split invoice check into separate function.

We now return the same error for various "does not match this
invoice", so it makes sense to encapsulate these checks.  We'll also
want to expose this for multi-part payments.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
committed by Christian Decker
parent
commit
7f629e545e
  1. 95
      lightningd/invoice.c
  2. 18
      lightningd/invoice.h

95
lightningd/invoice.c

@ -233,51 +233,46 @@ REGISTER_PLUGIN_HOOK(invoice_payment,
invoice_payment_serialize, invoice_payment_serialize,
struct invoice_payment_hook_payload *); struct invoice_payment_hook_payload *);
void invoice_try_pay(struct lightningd *ld, const struct invoice_details *
struct htlc_in *hin, invoice_check_payment(const tal_t *ctx,
const struct sha256 *payment_hash, struct lightningd *ld,
const struct amount_msat msat, const struct sha256 *payment_hash,
const struct secret *payment_secret) const struct amount_msat msat,
const struct secret *payment_secret)
{ {
struct invoice invoice; struct invoice invoice;
const struct invoice_details *details; const struct invoice_details *details;
struct invoice_payment_hook_payload *payload;
if (!wallet_invoice_find_unpaid(ld->wallet, &invoice, payment_hash)) { /* BOLT #4:
fail_htlc(hin, WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS); * - if the payment hash has already been paid:
return; * - MAY treat the payment hash as unknown.
} * - MAY succeed in accepting the HTLC.
details = wallet_invoice_details(tmpctx, ld->wallet, invoice); *...
* - if the payment hash is unknown:
* - MUST fail the HTLC.
* - MUST return an `incorrect_or_unknown_payment_details` error.
*/
if (!wallet_invoice_find_unpaid(ld->wallet, &invoice, payment_hash))
return NULL;
log_debug(ld->log, "payment_secret is %s", details = wallet_invoice_details(ctx, ld->wallet, invoice);
payment_secret ? "set": "NULL");
/* BOLT-9441a66faad63edc8cd89860b22fbf24a86f0dcd #4: /* BOLT-9441a66faad63edc8cd89860b22fbf24a86f0dcd #4:
* * - if the `payment_secret` doesn't match the expected value for that
* - if the `payment_secret` doesn't match the expected value for that * `payment_hash`, or the `payment_secret` is required and is not
* `payment_hash`, or the `payment_secret` is required and is not * present:
* present: * - MUST fail the HTLC.
* - MUST fail the HTLC.
* - MUST return an `incorrect_or_unknown_payment_details` error.
*/ */
if (feature_is_set(details->features, COMPULSORY_FEATURE(OPT_VAR_ONION)) if (feature_is_set(details->features, COMPULSORY_FEATURE(OPT_VAR_ONION))
&& !payment_secret) { && !payment_secret)
fail_htlc(hin, WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS); return tal_free(details);
return;
}
if (payment_secret) { if (payment_secret) {
struct secret expected; struct secret expected;
invoice_secret(&details->r, &expected); invoice_secret(&details->r, &expected);
log_debug(ld->log, "payment_secret %s vs %s", if (!secret_eq_consttime(payment_secret, &expected))
type_to_string(tmpctx, struct secret, payment_secret), return tal_free(details);
type_to_string(tmpctx, struct secret, &expected));
if (!secret_eq_consttime(payment_secret, &expected)) {
fail_htlc(hin,
WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS);
return;
}
} }
/* BOLT #4: /* BOLT #4:
@ -290,26 +285,39 @@ void invoice_try_pay(struct lightningd *ld,
if (details->msat != NULL) { if (details->msat != NULL) {
struct amount_msat twice; struct amount_msat twice;
if (amount_msat_less(msat, *details->msat)) { if (amount_msat_less(msat, *details->msat))
fail_htlc(hin, return tal_free(details);
WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS);
return;
}
if (amount_msat_add(&twice, *details->msat, *details->msat) if (amount_msat_add(&twice, *details->msat, *details->msat)
&& amount_msat_greater(msat, twice)) { && amount_msat_greater(msat, twice)) {
/* FIXME: bolt update fixes this quote! */
/* BOLT #4: /* BOLT #4:
* *
* - if the amount paid is more than twice the amount expected: * - if the amount paid is more than twice the amount
* - SHOULD fail the HTLC. * expected:
* - SHOULD return an `incorrect_or_unknown_payment_details` error. * - SHOULD fail the HTLC.
*/ */
fail_htlc(hin, return tal_free(details);
WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS);
return;
} }
} }
return details;
}
void invoice_try_pay(struct lightningd *ld,
struct htlc_in *hin,
const struct sha256 *payment_hash,
const struct amount_msat msat,
const struct secret *payment_secret)
{
const struct invoice_details *details;
struct invoice_payment_hook_payload *payload;
details = invoice_check_payment(tmpctx, ld, payment_hash, msat,
payment_secret);
if (!details) {
fail_htlc(hin, WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS);
return;
}
payload = tal(ld, struct invoice_payment_hook_payload); payload = tal(ld, struct invoice_payment_hook_payload);
payload->ld = ld; payload->ld = ld;
@ -319,7 +327,6 @@ void invoice_try_pay(struct lightningd *ld,
payload->hin = hin; payload->hin = hin;
tal_add_destructor2(hin, invoice_payload_remove_hin, payload); tal_add_destructor2(hin, invoice_payload_remove_hin, payload);
log_debug(ld->log, "Calling hook for invoice '%s'", details->label->s);
plugin_hook_call_invoice_payment(ld, payload, payload); plugin_hook_call_invoice_payment(ld, payload, payload);
} }

18
lightningd/invoice.h

@ -8,6 +8,24 @@ struct htlc_in;
struct lightningd; struct lightningd;
struct sha256; struct sha256;
/**
* invoice_check_payment - check if this payment would be valid
* @ctx: tal context to allocate return off
* @ld: lightningd
* @payment_hash: hash of preimage they want.
* @msat: amount they offer to pay.
* @payment_secret: they payment secret they sent, if any.
*
* Returns NULL if there's a problem, otherwise returns the invoice details.
*/
const struct invoice_details *
invoice_check_payment(const tal_t *ctx,
struct lightningd *ld,
const struct sha256 *payment_hash,
const struct amount_msat msat,
const struct secret *payment_secret);
/** /**
* invoice_try_pay - process payment for this payment_hash, amount msat. * invoice_try_pay - process payment for this payment_hash, amount msat.
* @ld: lightningd * @ld: lightningd

Loading…
Cancel
Save