invoice: return error string from invoice_check_payment.

Clean these up: they were debug logs, but we want to pass this information
back for self-payments.

Also fixes "Attept" typo which altered tests!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-07-22 20:56:16 +09:30
parent 23fafe98e3
commit 07e00d50c6
4 changed files with 30 additions and 23 deletions

View File

@@ -2,6 +2,7 @@
#include <common/features.h>
#include <common/timeout.h>
#include <common/type_to_string.h>
#include <lightningd/channel.h>
#include <lightningd/htlc_set.h>
#include <lightningd/invoice.h>
#include <lightningd/lightningd.h>
@@ -101,6 +102,7 @@ void htlc_set_add(struct lightningd *ld,
{
struct htlc_set *set;
const struct invoice_details *details;
const char *err;
/* BOLT #4:
* The final node:
@@ -109,8 +111,9 @@ void htlc_set_add(struct lightningd *ld,
* - Note: "amount paid" specified there is the `total_msat` field.
*/
details = invoice_check_payment(tmpctx, ld, &hin->payment_hash,
total_msat, payment_secret);
total_msat, payment_secret, &err);
if (!details) {
log_debug(hin->key.channel->log, "payment failed: %s", err);
local_fail_in_htlc(hin,
take(failmsg_incorrect_or_unknown(NULL, ld, hin)));
return;

View File

@@ -371,7 +371,8 @@ 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)
const struct secret *payment_secret,
const char **err)
{
u64 inv_dbid;
const struct invoice_details *details;
@@ -386,11 +387,12 @@ invoice_check_payment(const tal_t *ctx,
* - MUST return an `incorrect_or_unknown_payment_details` error.
*/
if (!invoices_find_unpaid(ld->wallet->invoices, &inv_dbid, payment_hash)) {
log_debug(ld->log, "Unknown paid invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash));
if (invoices_find_by_rhash(ld->wallet->invoices, &inv_dbid, payment_hash)) {
log_debug(ld->log, "ALREADY paid invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash));
*err = tal_fmt(ctx, "Already paid or expired invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash));
} else {
*err = tal_fmt(ctx, "Unknown invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash));
}
return NULL;
}
@@ -405,8 +407,8 @@ invoice_check_payment(const tal_t *ctx,
*/
if (feature_is_set(details->features, COMPULSORY_FEATURE(OPT_VAR_ONION))
&& !payment_secret) {
log_debug(ld->log, "Attept to pay %s without secret",
type_to_string(tmpctx, struct sha256, &details->rhash));
*err = tal_fmt(ctx, "Attempt to pay %s without secret",
type_to_string(tmpctx, struct sha256, &details->rhash));
return tal_free(details);
}
@@ -418,9 +420,9 @@ invoice_check_payment(const tal_t *ctx,
else
invoice_secret(&details->r, &expected);
if (!secret_eq_consttime(payment_secret, &expected)) {
log_debug(ld->log, "Attept to pay %s with wrong secret",
type_to_string(tmpctx, struct sha256,
&details->rhash));
*err = tal_fmt(ctx, "Attempt to pay %s with wrong secret",
type_to_string(tmpctx, struct sha256,
&details->rhash));
return tal_free(details);
}
}
@@ -436,21 +438,21 @@ invoice_check_payment(const tal_t *ctx,
struct amount_msat twice;
if (amount_msat_less(msat, *details->msat)) {
log_debug(ld->log, "Attept to pay %s with amount %s < %s",
type_to_string(tmpctx, struct sha256,
&details->rhash),
type_to_string(tmpctx, struct amount_msat, &msat),
type_to_string(tmpctx, struct amount_msat, details->msat));
*err = tal_fmt(ctx, "Attempt to pay %s with amount %s < %s",
type_to_string(tmpctx, struct sha256,
&details->rhash),
type_to_string(tmpctx, struct amount_msat, &msat),
type_to_string(tmpctx, struct amount_msat, details->msat));
return tal_free(details);
}
if (amount_msat_add(&twice, *details->msat, *details->msat)
&& amount_msat_greater(msat, twice)) {
log_debug(ld->log, "Attept to pay %s with amount %s > %s",
type_to_string(tmpctx, struct sha256,
&details->rhash),
type_to_string(tmpctx, struct amount_msat, &msat),
type_to_string(tmpctx, struct amount_msat, &twice));
*err = tal_fmt(ctx, "Attempt to pay %s with amount %s > %s",
type_to_string(tmpctx, struct sha256,
&details->rhash),
type_to_string(tmpctx, struct amount_msat, &msat),
type_to_string(tmpctx, struct amount_msat, &twice));
/* BOLT #4:
*
* - if the amount paid is more than twice the amount

View File

@@ -50,6 +50,7 @@ struct invoice_details {
* @payment_hash: hash of preimage they want.
* @msat: amount they offer to pay.
* @payment_secret: they payment secret they sent, if any.
* @err: error string if it returns NULL.
*
* Returns NULL if there's a problem, otherwise returns the invoice details.
*/
@@ -58,7 +59,8 @@ 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);
const struct secret *payment_secret,
const char **err);
/**
* invoice_try_pay - process payment for these incoming payments.

View File

@@ -1916,7 +1916,7 @@ def test_replacement_payload(node_factory):
with pytest.raises(RpcError, match=r"WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS \(reply from remote\)"):
l1.rpc.pay(inv)
assert l2.daemon.wait_for_log("Attept to pay.*with wrong secret")
assert l2.daemon.wait_for_log("Attempt to pay.*with wrong secret")
@pytest.mark.developer("Requires dev_sign_last_tx")