diff --git a/lightningd/invoice.c b/lightningd/invoice.c index a828f5020..4fbae7d20 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -250,11 +250,17 @@ invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS) return; } + /* Paid or expired in the meantime. */ + if (!wallet_invoice_resolve(ld->wallet, invoice, payload->msat)) { + htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown( + NULL, ld, payload->set->htlcs[0]))); + return; + } + log_info(ld->log, "Resolved invoice '%s' with amount %s in %zu htlcs", payload->label->s, type_to_string(tmpctx, struct amount_msat, &payload->msat), tal_count(payload->set->htlcs)); - wallet_invoice_resolve(ld->wallet, invoice, payload->msat); htlc_set_fulfill(payload->set, &payload->preimage); } diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index d1931eac6..3decafda8 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -643,7 +643,7 @@ const struct invoice_details *wallet_invoice_iterator_deref(const tal_t *ctx UNN const struct invoice_iterator *it UNNEEDED) { fprintf(stderr, "wallet_invoice_iterator_deref called!\n"); abort(); } /* Generated stub for wallet_invoice_resolve */ -void wallet_invoice_resolve(struct wallet *wallet UNNEEDED, +bool wallet_invoice_resolve(struct wallet *wallet UNNEEDED, struct invoice invoice UNNEEDED, struct amount_msat received UNNEEDED) { fprintf(stderr, "wallet_invoice_resolve called!\n"); abort(); } diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index 3078165f9..4a0be8b9a 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -1690,4 +1690,4 @@ struct db_query db_postgres_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:a61b8b6ea86287e22c696530a9b5cd35ccef271280b8ac34d2665dc5aff42fce +// SHA256STAMP:fac2fa6846e0deadf6f24fc9deb6efb0bac04b5947c254ae39300663366178af diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index ba6043ced..cac0dfeb2 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -1690,4 +1690,4 @@ struct db_query db_sqlite3_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:a61b8b6ea86287e22c696530a9b5cd35ccef271280b8ac34d2665dc5aff42fce +// SHA256STAMP:fac2fa6846e0deadf6f24fc9deb6efb0bac04b5947c254ae39300663366178af diff --git a/wallet/invoices.c b/wallet/invoices.c index d465b4bfd..e88668ddd 100644 --- a/wallet/invoices.c +++ b/wallet/invoices.c @@ -496,7 +496,7 @@ static enum invoice_status invoice_get_status(struct invoices *invoices, struct return state; } -void invoices_resolve(struct invoices *invoices, +bool invoices_resolve(struct invoices *invoices, struct invoice invoice, struct amount_msat received) { @@ -505,7 +505,8 @@ void invoices_resolve(struct invoices *invoices, u64 paid_timestamp; enum invoice_status state = invoice_get_status(invoices, invoice); - assert(state == UNPAID); + if (state != UNPAID) + return false; /* Assign a pay-index. */ pay_index = get_next_pay_index(invoices->db); @@ -527,6 +528,7 @@ void invoices_resolve(struct invoices *invoices, /* Tell all the waiters about the paid invoice. */ trigger_invoice_waiter_resolve(invoices, invoice.id, &invoice); + return true; } /* Called when an invoice waiter is destructed. */ diff --git a/wallet/invoices.h b/wallet/invoices.h index 6577cffdb..303b9a1dc 100644 --- a/wallet/invoices.h +++ b/wallet/invoices.h @@ -174,10 +174,9 @@ const struct invoice_details *invoices_iterator_deref( * @invoice - the invoice to mark as paid. * @received - the actual amount received. * - * Precondition: the invoice must not yet be expired (invoices - * does not check). + * If the invoice is not UNPAID, returns false. */ -void invoices_resolve(struct invoices *invoices, +bool invoices_resolve(struct invoices *invoices, struct invoice invoice, struct amount_msat received); diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index 65a4da937..aa8b4f9ca 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -666,15 +666,15 @@ msgstr "" msgid "SELECT state FROM invoices WHERE id = ?;" msgstr "" -#: wallet/invoices.c:515 +#: wallet/invoices.c:516 msgid "UPDATE invoices SET state=? , pay_index=? , msatoshi_received=? , paid_timestamp=? WHERE id=?;" msgstr "" -#: wallet/invoices.c:571 +#: wallet/invoices.c:573 msgid "SELECT id FROM invoices WHERE pay_index IS NOT NULL AND pay_index > ? ORDER BY pay_index ASC LIMIT 1;" msgstr "" -#: wallet/invoices.c:620 +#: wallet/invoices.c:622 msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features FROM invoices WHERE id = ?;" msgstr "" @@ -1113,4 +1113,4 @@ msgstr "" #: wallet/test/run-wallet.c:1376 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:a63bd31a3977b161d8245ffddf5de3a03c972a60436eb8cbc1bb23f0ffb03405 +# SHA256STAMP:8f226711a58166b481aaa7b8c0593c7159711bee623737e3b4750f6c154d4f65 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 81be48722..805051e4a 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -220,7 +220,7 @@ struct invoices *invoices_new(const tal_t *ctx UNNEEDED, struct timers *timers UNNEEDED) { fprintf(stderr, "invoices_new called!\n"); abort(); } /* Generated stub for invoices_resolve */ -void invoices_resolve(struct invoices *invoices UNNEEDED, +bool invoices_resolve(struct invoices *invoices UNNEEDED, struct invoice invoice UNNEEDED, struct amount_msat received UNNEEDED) { fprintf(stderr, "invoices_resolve called!\n"); abort(); } diff --git a/wallet/wallet.c b/wallet/wallet.c index 169454243..a5187871a 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -2337,11 +2337,11 @@ wallet_invoice_iterator_deref(const tal_t *ctx, struct wallet *wallet, { return invoices_iterator_deref(ctx, wallet->invoices, it); } -void wallet_invoice_resolve(struct wallet *wallet, +bool wallet_invoice_resolve(struct wallet *wallet, struct invoice invoice, struct amount_msat msatoshi_received) { - invoices_resolve(wallet->invoices, invoice, msatoshi_received); + return invoices_resolve(wallet->invoices, invoice, msatoshi_received); } void wallet_invoice_waitany(const tal_t *ctx, struct wallet *wallet, diff --git a/wallet/wallet.h b/wallet/wallet.h index 383081fe4..1a6782eaf 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -883,10 +883,9 @@ const struct invoice_details *wallet_invoice_iterator_deref(const tal_t *ctx, * @invoice - the invoice to mark as paid. * @received - the actual amount received. * - * Precondition: the invoice must not yet be expired (wallet - * does not check!). + * If the invoice is not UNPAID, returns false. */ -void wallet_invoice_resolve(struct wallet *wallet, +bool wallet_invoice_resolve(struct wallet *wallet, struct invoice invoice, struct amount_msat received);