wallet/invoice: remove indirection.

We can expose the dbid, rather than pretending we have some "struct
invoice" which is actually just the dbid.  And don't have a pile of
"wallet_" wrappers for redirection.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-07-12 05:12:17 +09:30
parent c7026e56a4
commit c814cd0142
8 changed files with 269 additions and 635 deletions

View File

@@ -26,6 +26,7 @@
#include <lightningd/plugin_hook.h> #include <lightningd/plugin_hook.h>
#include <lightningd/routehint.h> #include <lightningd/routehint.h>
#include <sodium/randombytes.h> #include <sodium/randombytes.h>
#include <wallet/invoices.h>
#include <wire/wire_sync.h> #include <wire/wire_sync.h>
const char *invoice_status_str(enum invoice_status state) const char *invoice_status_str(enum invoice_status state)
@@ -89,13 +90,12 @@ static void json_add_invoice(struct json_stream *response,
json_object_end(response); json_object_end(response);
} }
static struct command_result *tell_waiter(struct command *cmd, static struct command_result *tell_waiter(struct command *cmd, u64 inv_dbid)
const struct invoice *inv)
{ {
struct json_stream *response; struct json_stream *response;
const struct invoice_details *details; const struct invoice_details *details;
details = wallet_invoice_details(cmd, cmd->ld->wallet, *inv); details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);
if (details->state == PAID) { if (details->state == PAID) {
response = json_stream_success(cmd); response = json_stream_success(cmd);
json_add_invoice_fields(response, details); json_add_invoice_fields(response, details);
@@ -114,10 +114,10 @@ static void tell_waiter_deleted(struct command *cmd)
was_pending(command_fail(cmd, LIGHTNINGD, was_pending(command_fail(cmd, LIGHTNINGD,
"Invoice deleted during wait")); "Invoice deleted during wait"));
} }
static void wait_on_invoice(const struct invoice *invoice, void *cmd) static void wait_on_invoice(const u64 *inv_dbid, void *cmd)
{ {
if (invoice) if (inv_dbid)
tell_waiter((struct command *) cmd, invoice); tell_waiter((struct command *) cmd, *inv_dbid);
else else
tell_waiter_deleted((struct command *) cmd); tell_waiter_deleted((struct command *) cmd);
} }
@@ -299,7 +299,7 @@ static const u8 *hook_gives_failmsg(const tal_t *ctx,
static void static void
invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS) invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS)
{ {
struct invoice invoice; u64 inv_dbid;
struct lightningd *ld = payload->ld; struct lightningd *ld = payload->ld;
tal_del_destructor2(payload->set, invoice_payload_remove_set, payload); tal_del_destructor2(payload->set, invoice_payload_remove_set, payload);
@@ -308,14 +308,14 @@ invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS)
/* If invoice gets paid meanwhile (plugin responds out-of-order?) then /* If invoice gets paid meanwhile (plugin responds out-of-order?) then
* we can also fail */ * we can also fail */
if (!wallet_invoice_find_by_label(ld->wallet, &invoice, payload->label)) { if (!invoices_find_by_label(ld->wallet->invoices, &inv_dbid, payload->label)) {
htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown( htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown(
NULL, ld, payload->set->htlcs[0]))); NULL, ld, payload->set->htlcs[0])));
return; return;
} }
/* Paid or expired in the meantime. */ /* Paid or expired in the meantime. */
if (!wallet_invoice_resolve(ld->wallet, invoice, payload->msat)) { if (!invoices_resolve(ld->wallet->invoices, inv_dbid, payload->msat)) {
htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown( htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown(
NULL, ld, payload->set->htlcs[0]))); NULL, ld, payload->set->htlcs[0])));
return; return;
@@ -369,7 +369,7 @@ invoice_check_payment(const tal_t *ctx,
const struct amount_msat msat, const struct amount_msat msat,
const struct secret *payment_secret) const struct secret *payment_secret)
{ {
struct invoice invoice; u64 inv_dbid;
const struct invoice_details *details; const struct invoice_details *details;
/* BOLT #4: /* BOLT #4:
@@ -381,17 +381,17 @@ invoice_check_payment(const tal_t *ctx,
* - MUST fail the HTLC. * - MUST fail the HTLC.
* - MUST return an `incorrect_or_unknown_payment_details` error. * - MUST return an `incorrect_or_unknown_payment_details` error.
*/ */
if (!wallet_invoice_find_unpaid(ld->wallet, &invoice, payment_hash)) { if (!invoices_find_unpaid(ld->wallet->invoices, &inv_dbid, payment_hash)) {
log_debug(ld->log, "Unknown paid invoice %s", log_debug(ld->log, "Unknown paid invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash)); type_to_string(tmpctx, struct sha256, payment_hash));
if (wallet_invoice_find_by_rhash(ld->wallet, &invoice, payment_hash)) { if (invoices_find_by_rhash(ld->wallet->invoices, &inv_dbid, payment_hash)) {
log_debug(ld->log, "ALREADY paid invoice %s", log_debug(ld->log, "ALREADY paid invoice %s",
type_to_string(tmpctx, struct sha256, payment_hash)); type_to_string(tmpctx, struct sha256, payment_hash));
} }
return NULL; return NULL;
} }
details = wallet_invoice_details(ctx, ld->wallet, invoice); details = invoices_get_details(ctx, ld->wallet->invoices, inv_dbid);
/* BOLT #4: /* BOLT #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
@@ -839,7 +839,7 @@ invoice_complete(struct invoice_info *info,
bool warning_private_unused) bool warning_private_unused)
{ {
struct json_stream *response; struct json_stream *response;
struct invoice invoice; u64 inv_dbid;
char *b11enc; char *b11enc;
const struct invoice_details *details; const struct invoice_details *details;
struct secret payment_secret; struct secret payment_secret;
@@ -849,31 +849,31 @@ invoice_complete(struct invoice_info *info,
hsm_sign_b11, info->cmd->ld); hsm_sign_b11, info->cmd->ld);
/* Check duplicate preimage (unlikely unless they specified it!) */ /* Check duplicate preimage (unlikely unless they specified it!) */
if (wallet_invoice_find_by_rhash(wallet, if (invoices_find_by_rhash(wallet->invoices,
&invoice, &info->b11->payment_hash)) { &inv_dbid, &info->b11->payment_hash)) {
return command_fail(info->cmd, return command_fail(info->cmd,
INVOICE_PREIMAGE_ALREADY_EXISTS, INVOICE_PREIMAGE_ALREADY_EXISTS,
"preimage already used"); "preimage already used");
} }
if (!wallet_invoice_create(wallet, if (!invoices_create(wallet->invoices,
&invoice, &inv_dbid,
info->b11->msat, info->b11->msat,
info->label, info->label,
info->b11->expiry, info->b11->expiry,
b11enc, b11enc,
info->b11->description, info->b11->description,
info->b11->features, info->b11->features,
&info->payment_preimage, &info->payment_preimage,
&info->b11->payment_hash, &info->b11->payment_hash,
NULL)) { NULL)) {
return command_fail(info->cmd, INVOICE_LABEL_ALREADY_EXISTS, return command_fail(info->cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label '%s'", "Duplicate label '%s'",
info->label->s); info->label->s);
} }
/* Get details */ /* Get details */
details = wallet_invoice_details(info, wallet, invoice); details = invoices_get_details(info, wallet->invoices, inv_dbid);
response = json_stream_success(info->cmd); response = json_stream_success(info->cmd);
json_add_sha256(response, "payment_hash", &details->rhash); json_add_sha256(response, "payment_hash", &details->rhash);
@@ -1090,6 +1090,7 @@ static struct command_result *json_invoice(struct command *cmd,
struct jsonrpc_request *req; struct jsonrpc_request *req;
struct plugin *plugin; struct plugin *plugin;
bool *hashonly; bool *hashonly;
const size_t inv_max_label_len = 128;
#if DEVELOPER #if DEVELOPER
const jsmntok_t *routes; const jsmntok_t *routes;
#endif #endif
@@ -1115,10 +1116,9 @@ static struct command_result *json_invoice(struct command *cmd,
NULL)) NULL))
return command_param_failed(); return command_param_failed();
if (strlen(info->label->s) > INVOICE_MAX_LABEL_LEN) { if (strlen(info->label->s) > inv_max_label_len) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Label '%s' over %u bytes", info->label->s, "Label '%s' over %zu bytes", info->label->s, inv_max_label_len);
INVOICE_MAX_LABEL_LEN);
} }
if (strlen(desc_val) > BOLT11_FIELD_BYTE_LIMIT && !*hashonly) { if (strlen(desc_val) > BOLT11_FIELD_BYTE_LIMIT && !*hashonly) {
@@ -1225,27 +1225,27 @@ static void json_add_invoices(struct json_stream *response,
{ {
struct invoice_iterator it; struct invoice_iterator it;
const struct invoice_details *details; const struct invoice_details *details;
struct invoice invoice; u64 inv_dbid;
/* Don't iterate entire db if we're just after one. */ /* Don't iterate entire db if we're just after one. */
if (label) { if (label) {
if (wallet_invoice_find_by_label(wallet, &invoice, label)) { if (invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
details = details =
wallet_invoice_details(tmpctx, wallet, invoice); invoices_get_details(tmpctx, wallet->invoices, inv_dbid);
json_add_invoice(response, NULL, details); json_add_invoice(response, NULL, details);
} }
} else if (payment_hash != NULL) { } else if (payment_hash != NULL) {
if (wallet_invoice_find_by_rhash(wallet, &invoice, if (invoices_find_by_rhash(wallet->invoices, &inv_dbid,
payment_hash)) { payment_hash)) {
details = details =
wallet_invoice_details(tmpctx, wallet, invoice); invoices_get_details(tmpctx, wallet->invoices, inv_dbid);
json_add_invoice(response, NULL, details); json_add_invoice(response, NULL, details);
} }
} else { } else {
memset(&it, 0, sizeof(it)); memset(&it, 0, sizeof(it));
while (wallet_invoice_iterate(wallet, &it)) { while (invoices_iterate(wallet->invoices, &it)) {
details = wallet_invoice_iterator_deref(response, details = invoices_iterator_deref(response,
wallet, &it); wallet->invoices, &it);
/* FIXME: db can filter this better! */ /* FIXME: db can filter this better! */
if (local_offer_id) { if (local_offer_id) {
if (!details->local_offer_id if (!details->local_offer_id
@@ -1328,7 +1328,7 @@ static struct command_result *json_delinvoice(struct command *cmd,
const jsmntok_t *obj UNNEEDED, const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params) const jsmntok_t *params)
{ {
struct invoice i; u64 inv_dbid;
struct invoice_details *details; struct invoice_details *details;
struct json_stream *response; struct json_stream *response;
const char *status, *actual_status; const char *status, *actual_status;
@@ -1343,11 +1343,11 @@ static struct command_result *json_delinvoice(struct command *cmd,
NULL)) NULL))
return command_param_failed(); return command_param_failed();
if (!wallet_invoice_find_by_label(wallet, &i, label)) { if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
return command_fail(cmd, INVOICE_NOT_FOUND, "Unknown invoice"); return command_fail(cmd, INVOICE_NOT_FOUND, "Unknown invoice");
} }
details = wallet_invoice_details(cmd, cmd->ld->wallet, i); details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);
/* This is time-sensitive, so only call once; otherwise error msg /* This is time-sensitive, so only call once; otherwise error msg
* might not make sense if it changed! */ * might not make sense if it changed! */
@@ -1369,19 +1369,19 @@ static struct command_result *json_delinvoice(struct command *cmd,
return command_fail(cmd, INVOICE_NO_DESCRIPTION, return command_fail(cmd, INVOICE_NO_DESCRIPTION,
"Invoice description already removed"); "Invoice description already removed");
if (!wallet_invoice_delete_description(wallet, i)) { if (!invoices_delete_description(wallet->invoices, inv_dbid)) {
log_broken(cmd->ld->log, log_broken(cmd->ld->log,
"Error attempting to delete description of invoice %"PRIu64, "Error attempting to delete description of invoice %"PRIu64,
i.id); inv_dbid);
/* FIXME: allocate a generic DATABASE_ERROR code. */ /* FIXME: allocate a generic DATABASE_ERROR code. */
return command_fail(cmd, LIGHTNINGD, "Database error"); return command_fail(cmd, LIGHTNINGD, "Database error");
} }
details->description = tal_free(details->description); details->description = tal_free(details->description);
} else { } else {
if (!wallet_invoice_delete(wallet, i)) { if (!invoices_delete(wallet->invoices, inv_dbid)) {
log_broken(cmd->ld->log, log_broken(cmd->ld->log,
"Error attempting to remove invoice %"PRIu64, "Error attempting to remove invoice %"PRIu64,
i.id); inv_dbid);
/* FIXME: allocate a generic DATABASE_ERROR code. */ /* FIXME: allocate a generic DATABASE_ERROR code. */
return command_fail(cmd, LIGHTNINGD, "Database error"); return command_fail(cmd, LIGHTNINGD, "Database error");
} }
@@ -1413,7 +1413,7 @@ static struct command_result *json_delexpiredinvoice(struct command *cmd,
NULL)) NULL))
return command_param_failed(); return command_param_failed();
wallet_invoice_delete_expired(cmd->ld->wallet, *maxexpirytime); invoices_delete_expired(cmd->ld->wallet->invoices, *maxexpirytime);
return command_success(cmd, json_stream_success(cmd)); return command_success(cmd, json_stream_success(cmd));
} }
@@ -1457,8 +1457,8 @@ static struct command_result *json_waitanyinvoice(struct command *cmd,
fixme_ignore(command_still_pending(cmd)); fixme_ignore(command_still_pending(cmd));
/* Find next paid invoice. */ /* Find next paid invoice. */
wallet_invoice_waitany(cmd, wallet, *pay_index, invoices_waitany(cmd, wallet->invoices, *pay_index,
&wait_on_invoice, (void*) cmd); &wait_on_invoice, (void*) cmd);
return command_its_complicated("wallet_invoice_waitany might complete" return command_its_complicated("wallet_invoice_waitany might complete"
" immediately, but we also call it as a" " immediately, but we also call it as a"
@@ -1486,7 +1486,7 @@ static struct command_result *json_waitinvoice(struct command *cmd,
const jsmntok_t *obj UNNEEDED, const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params) const jsmntok_t *params)
{ {
struct invoice i; u64 inv_dbid;
const struct invoice_details *details; const struct invoice_details *details;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
struct json_escape *label; struct json_escape *label;
@@ -1496,19 +1496,19 @@ static struct command_result *json_waitinvoice(struct command *cmd,
NULL)) NULL))
return command_param_failed(); return command_param_failed();
if (!wallet_invoice_find_by_label(wallet, &i, label)) { if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label)) {
return command_fail(cmd, LIGHTNINGD, "Label not found"); return command_fail(cmd, LIGHTNINGD, "Label not found");
} }
details = wallet_invoice_details(cmd, cmd->ld->wallet, i); details = invoices_get_details(cmd, cmd->ld->wallet->invoices, inv_dbid);
/* If paid or expired return immediately */ /* If paid or expired return immediately */
if (details->state == PAID || details->state == EXPIRED) { if (details->state == PAID || details->state == EXPIRED) {
return tell_waiter(cmd, &i); return tell_waiter(cmd, inv_dbid);
} else { } else {
/* There is an unpaid one matching, let's wait... */ /* There is an unpaid one matching, let's wait... */
fixme_ignore(command_still_pending(cmd)); fixme_ignore(command_still_pending(cmd));
wallet_invoice_waitone(cmd, wallet, i, invoices_waitone(cmd, wallet->invoices, inv_dbid,
&wait_on_invoice, (void *) cmd); &wait_on_invoice, (void *) cmd);
return command_its_complicated("wallet_invoice_waitone might" return command_its_complicated("wallet_invoice_waitone might"
" complete immediately"); " complete immediately");
} }
@@ -1563,17 +1563,17 @@ static struct command_result *fail_exists(struct command *cmd,
const struct json_escape *label) const struct json_escape *label)
{ {
struct json_stream *data; struct json_stream *data;
struct invoice invoice; u64 inv_dbid;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
data = json_stream_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS, data = json_stream_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS,
"Duplicate label"); "Duplicate label");
if (!wallet_invoice_find_by_label(wallet, &invoice, label)) if (!invoices_find_by_label(wallet->invoices, &inv_dbid, label))
fatal("Duplicate invoice %s not found any more?", fatal("Duplicate invoice %s not found any more?",
label->s); label->s);
json_add_invoice_fields(data, json_add_invoice_fields(data,
wallet_invoice_details(cmd, wallet, invoice)); invoices_get_details(cmd, wallet->invoices, inv_dbid));
json_object_end(data); json_object_end(data);
return command_failed(cmd, data); return command_failed(cmd, data);
@@ -1644,7 +1644,7 @@ static struct command_result *json_createinvoice(struct command *cmd,
const char *invstring; const char *invstring;
struct json_escape *label; struct json_escape *label;
struct preimage *preimage; struct preimage *preimage;
struct invoice invoice; u64 inv_dbid;
struct sha256 payment_hash; struct sha256 payment_hash;
struct json_stream *response; struct json_stream *response;
struct bolt11 *b11; struct bolt11 *b11;
@@ -1681,17 +1681,17 @@ static struct command_result *json_createinvoice(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Incorrect preimage"); "Incorrect preimage");
if (!wallet_invoice_create(cmd->ld->wallet, if (!invoices_create(cmd->ld->wallet->invoices,
&invoice, &inv_dbid,
b11->msat, b11->msat,
label, label,
b11->expiry, b11->expiry,
b11enc, b11enc,
b11->description, b11->description,
b11->features, b11->features,
preimage, preimage,
&payment_hash, &payment_hash,
NULL)) NULL))
return fail_exists(cmd, label); return fail_exists(cmd, label);
notify_invoice_creation(cmd->ld, b11->msat, *preimage, label); notify_invoice_creation(cmd->ld, b11->msat, *preimage, label);
@@ -1775,17 +1775,17 @@ static struct command_result *json_createinvoice(struct command *cmd,
inv->offer_description, inv->offer_description,
tal_bytelen(inv->offer_description)); tal_bytelen(inv->offer_description));
if (!wallet_invoice_create(cmd->ld->wallet, if (!invoices_create(cmd->ld->wallet->invoices,
&invoice, &inv_dbid,
&msat, &msat,
label, label,
expiry, expiry,
b12enc, b12enc,
desc, desc,
inv->invoice_features, inv->invoice_features,
preimage, preimage,
&payment_hash, &payment_hash,
local_offer_id)) local_offer_id))
return fail_exists(cmd, label); return fail_exists(cmd, label);
notify_invoice_creation(cmd->ld, &msat, *preimage, label); notify_invoice_creation(cmd->ld, &msat, *preimage, label);
@@ -1793,8 +1793,8 @@ static struct command_result *json_createinvoice(struct command *cmd,
response = json_stream_success(cmd); response = json_stream_success(cmd);
json_add_invoice_fields(response, json_add_invoice_fields(response,
wallet_invoice_details(cmd, cmd->ld->wallet, invoices_get_details(cmd, cmd->ld->wallet->invoices,
invoice)); inv_dbid));
return command_success(cmd, response); return command_success(cmd, response);
} }

View File

@@ -9,6 +9,36 @@ struct htlc_set;
struct lightningd; struct lightningd;
struct sha256; struct sha256;
/* The information about an invoice */
struct invoice_details {
/* Current invoice state */
enum invoice_status state;
/* Preimage for this invoice */
struct preimage r;
/* Hash of preimage r */
struct sha256 rhash;
/* Label assigned by user */
const struct json_escape *label;
/* NULL if they specified "any" */
struct amount_msat *msat;
/* Absolute UNIX epoch time this will expire */
u64 expiry_time;
/* Set if state == PAID; order to be returned by waitanyinvoice */
u64 pay_index;
/* Set if state == PAID; amount received */
struct amount_msat received;
/* Set if state == PAID; time paid */
u64 paid_timestamp;
/* BOLT11 or BOLT12 encoding for this invoice */
const char *invstring;
/* The description of the payment. */
char *description;
/* The features, if any (tal_arr) */
u8 *features;
/* The offer this refers to, if any. */
struct sha256 *local_offer_id;
};
/** /**
* invoice_check_payment - check if this payment would be valid * invoice_check_payment - check if this payment would be valid

View File

@@ -354,6 +354,78 @@ u8 *invoice_path_id(const tal_t *ctx UNNEEDED,
const struct secret *base_secret UNNEEDED, const struct secret *base_secret UNNEEDED,
const struct sha256 *payment_hash UNNEEDED) const struct sha256 *payment_hash UNNEEDED)
{ fprintf(stderr, "invoice_path_id called!\n"); abort(); } { fprintf(stderr, "invoice_path_id called!\n"); abort(); }
/* Generated stub for invoices_create */
bool invoices_create(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escape *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,
const char *description UNNEEDED,
const u8 *features UNNEEDED,
const struct preimage *r UNNEEDED,
const struct sha256 *rhash UNNEEDED,
const struct sha256 *local_offer_id UNNEEDED)
{ fprintf(stderr, "invoices_create called!\n"); abort(); }
/* Generated stub for invoices_delete */
bool invoices_delete(struct invoices *invoices UNNEEDED, u64 inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_delete called!\n"); abort(); }
/* Generated stub for invoices_delete_description */
bool invoices_delete_description(struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_delete_description called!\n"); abort(); }
/* Generated stub for invoices_delete_expired */
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
u64 max_expiry_time UNNEEDED)
{ fprintf(stderr, "invoices_delete_expired called!\n"); abort(); }
/* Generated stub for invoices_find_by_label */
bool invoices_find_by_label(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const struct json_escape *label UNNEEDED)
{ fprintf(stderr, "invoices_find_by_label called!\n"); abort(); }
/* Generated stub for invoices_find_by_rhash */
bool invoices_find_by_rhash(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_by_rhash called!\n"); abort(); }
/* Generated stub for invoices_find_unpaid */
bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
/* Generated stub for invoices_get_details */
struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
/* Generated stub for invoices_iterate */
bool invoices_iterate(struct invoices *invoices UNNEEDED,
struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterate called!\n"); abort(); }
/* Generated stub for invoices_iterator_deref */
const struct invoice_details *invoices_iterator_deref(
const tal_t *ctx UNNEEDED, struct invoices *invoices UNNEEDED,
const struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterator_deref called!\n"); abort(); }
/* Generated stub for invoices_resolve */
bool invoices_resolve(struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED,
struct amount_msat received UNNEEDED)
{ fprintf(stderr, "invoices_resolve called!\n"); abort(); }
/* Generated stub for invoices_waitany */
void invoices_waitany(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 lastpay_index UNNEEDED,
void (*cb)(const u64 * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitany called!\n"); abort(); }
/* Generated stub for invoices_waitone */
void invoices_waitone(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED,
void (*cb)(const u64 * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitone called!\n"); abort(); }
/* Generated stub for json_add_address */ /* Generated stub for json_add_address */
void json_add_address(struct json_stream *response UNNEEDED, const char *fieldname UNNEEDED, void json_add_address(struct json_stream *response UNNEEDED, const char *fieldname UNNEEDED,
const struct wireaddr *addr UNNEEDED) const struct wireaddr *addr UNNEEDED)
@@ -864,79 +936,6 @@ bool wallet_htlcs_load_out_for_channel(struct wallet *wallet UNNEEDED,
/* Generated stub for wallet_init_channels */ /* Generated stub for wallet_init_channels */
bool wallet_init_channels(struct wallet *w UNNEEDED) bool wallet_init_channels(struct wallet *w UNNEEDED)
{ fprintf(stderr, "wallet_init_channels called!\n"); abort(); } { fprintf(stderr, "wallet_init_channels called!\n"); abort(); }
/* Generated stub for wallet_invoice_create */
bool wallet_invoice_create(struct wallet *wallet UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escape *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,
const char *description UNNEEDED,
const u8 *features UNNEEDED,
const struct preimage *r UNNEEDED,
const struct sha256 *rhash UNNEEDED,
const struct sha256 *local_offer_id UNNEEDED)
{ fprintf(stderr, "wallet_invoice_create called!\n"); abort(); }
/* Generated stub for wallet_invoice_delete */
bool wallet_invoice_delete(struct wallet *wallet UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "wallet_invoice_delete called!\n"); abort(); }
/* Generated stub for wallet_invoice_delete_description */
bool wallet_invoice_delete_description(struct wallet *wallet UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "wallet_invoice_delete_description called!\n"); abort(); }
/* Generated stub for wallet_invoice_delete_expired */
void wallet_invoice_delete_expired(struct wallet *wallet UNNEEDED,
u64 max_expiry_time UNNEEDED)
{ fprintf(stderr, "wallet_invoice_delete_expired called!\n"); abort(); }
/* Generated stub for wallet_invoice_details */
struct invoice_details *wallet_invoice_details(const tal_t *ctx UNNEEDED,
struct wallet *wallet UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "wallet_invoice_details called!\n"); abort(); }
/* Generated stub for wallet_invoice_find_by_label */
bool wallet_invoice_find_by_label(struct wallet *wallet UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct json_escape *label UNNEEDED)
{ fprintf(stderr, "wallet_invoice_find_by_label called!\n"); abort(); }
/* Generated stub for wallet_invoice_find_by_rhash */
bool wallet_invoice_find_by_rhash(struct wallet *wallet UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "wallet_invoice_find_by_rhash called!\n"); abort(); }
/* Generated stub for wallet_invoice_find_unpaid */
bool wallet_invoice_find_unpaid(struct wallet *wallet UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "wallet_invoice_find_unpaid called!\n"); abort(); }
/* Generated stub for wallet_invoice_iterate */
bool wallet_invoice_iterate(struct wallet *wallet UNNEEDED,
struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "wallet_invoice_iterate called!\n"); abort(); }
/* Generated stub for wallet_invoice_iterator_deref */
const struct invoice_details *wallet_invoice_iterator_deref(const tal_t *ctx UNNEEDED,
struct wallet *wallet UNNEEDED,
const struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "wallet_invoice_iterator_deref called!\n"); abort(); }
/* Generated stub for wallet_invoice_resolve */
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(); }
/* Generated stub for wallet_invoice_waitany */
void wallet_invoice_waitany(const tal_t *ctx UNNEEDED,
struct wallet *wallet UNNEEDED,
u64 lastpay_index UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "wallet_invoice_waitany called!\n"); abort(); }
/* Generated stub for wallet_invoice_waitone */
void wallet_invoice_waitone(const tal_t *ctx UNNEEDED,
struct wallet *wallet UNNEEDED,
struct invoice invoice UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "wallet_invoice_waitone called!\n"); abort(); }
/* Generated stub for wallet_offer_find */ /* Generated stub for wallet_offer_find */
char *wallet_offer_find(const tal_t *ctx UNNEEDED, char *wallet_offer_find(const tal_t *ctx UNNEEDED,
struct wallet *w UNNEEDED, struct wallet *w UNNEEDED,

View File

@@ -5,6 +5,7 @@
#include <db/common.h> #include <db/common.h>
#include <db/exec.h> #include <db/exec.h>
#include <db/utils.h> #include <db/utils.h>
#include <lightningd/invoice.h>
#include <wallet/invoices.h> #include <wallet/invoices.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
@@ -14,12 +15,12 @@ struct invoice_waiter {
/* Is this waiting for any invoice to resolve? */ /* Is this waiting for any invoice to resolve? */
bool any; bool any;
/* If !any, the specific invoice this is waiting on */ /* If !any, the specific invoice this is waiting on */
u64 id; u64 inv_dbid;
struct list_node list; struct list_node list;
/* The callback to use */ /* The callback to use */
void (*cb)(const struct invoice *, void*); void (*cb)(const u64 *inv_dbid, void*);
void *cbarg; void *cbarg;
}; };
@@ -37,41 +38,41 @@ struct invoices {
}; };
static void trigger_invoice_waiter(struct invoice_waiter *w, static void trigger_invoice_waiter(struct invoice_waiter *w,
const struct invoice *invoice) const u64 *inv_dbid)
{ {
w->triggered = true; w->triggered = true;
w->cb(invoice, w->cbarg); w->cb(inv_dbid, w->cbarg);
} }
static void trigger_invoice_waiter_resolve(struct invoices *invoices, static void trigger_invoice_waiter_resolve(struct invoices *invoices,
u64 id, u64 inv_dbid)
const struct invoice *invoice)
{ {
struct invoice_waiter *w; struct invoice_waiter *w;
struct invoice_waiter *n; struct invoice_waiter *n;
list_for_each_safe(&invoices->waiters, w, n, list) { list_for_each_safe(&invoices->waiters, w, n, list) {
if (!w->any && w->id != id) if (!w->any && w->inv_dbid != inv_dbid)
continue; continue;
list_del_from(&invoices->waiters, &w->list); list_del_from(&invoices->waiters, &w->list);
tal_steal(tmpctx, w); tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice); trigger_invoice_waiter(w, &inv_dbid);
} }
} }
static void static void
trigger_invoice_waiter_expire_or_delete(struct invoices *invoices, trigger_invoice_waiter_expire_or_delete(struct invoices *invoices,
u64 id, u64 inv_dbid,
const struct invoice *invoice) bool deleted)
{ {
struct invoice_waiter *w; struct invoice_waiter *w;
struct invoice_waiter *n; struct invoice_waiter *n;
list_for_each_safe(&invoices->waiters, w, n, list) { list_for_each_safe(&invoices->waiters, w, n, list) {
if (w->any || w->id != id) if (w->any || w->inv_dbid != inv_dbid)
continue; continue;
list_del_from(&invoices->waiters, &w->list); list_del_from(&invoices->waiters, &w->list);
tal_steal(tmpctx, w); tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice); trigger_invoice_waiter(w, deleted ? NULL : &inv_dbid);
} }
} }
@@ -150,7 +151,7 @@ struct invoices *invoices_new(const tal_t *ctx,
struct invoice_id_node { struct invoice_id_node {
struct list_node list; struct list_node list;
u64 id; u64 inv_dbid;
}; };
static void trigger_expiration(struct invoices *invoices) static void trigger_expiration(struct invoices *invoices)
@@ -159,7 +160,6 @@ static void trigger_expiration(struct invoices *invoices)
struct invoice_id_node *idn; struct invoice_id_node *idn;
u64 now = time_now().ts.tv_sec; u64 now = time_now().ts.tv_sec;
struct db_stmt *stmt; struct db_stmt *stmt;
struct invoice i;
/* Free current expiration timer */ /* Free current expiration timer */
invoices->expiration_timer = tal_free(invoices->expiration_timer); invoices->expiration_timer = tal_free(invoices->expiration_timer);
@@ -177,7 +177,7 @@ static void trigger_expiration(struct invoices *invoices)
while (db_step(stmt)) { while (db_step(stmt)) {
idn = tal(tmpctx, struct invoice_id_node); idn = tal(tmpctx, struct invoice_id_node);
list_add_tail(&idlist, &idn->list); list_add_tail(&idlist, &idn->list);
idn->id = db_col_u64(stmt, "id"); idn->inv_dbid = db_col_u64(stmt, "id");
} }
tal_free(stmt); tal_free(stmt);
@@ -187,8 +187,7 @@ static void trigger_expiration(struct invoices *invoices)
/* Trigger expirations */ /* Trigger expirations */
list_for_each(&idlist, idn, list) { list_for_each(&idlist, idn, list) {
/* Trigger expiration */ /* Trigger expiration */
i.id = idn->id; trigger_invoice_waiter_expire_or_delete(invoices, idn->inv_dbid, false);
trigger_invoice_waiter_expire_or_delete(invoices, idn->id, &i);
} }
install_expiration_timer(invoices); install_expiration_timer(invoices);
@@ -248,7 +247,7 @@ done:
} }
bool invoices_create(struct invoices *invoices, bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct amount_msat *msat TAKES, const struct amount_msat *msat TAKES,
const struct json_escape *label TAKES, const struct json_escape *label TAKES,
u64 expiry, u64 expiry,
@@ -260,11 +259,10 @@ bool invoices_create(struct invoices *invoices,
const struct sha256 *local_offer_id) const struct sha256 *local_offer_id)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
struct invoice dummy;
u64 expiry_time; u64 expiry_time;
u64 now = time_now().ts.tv_sec; u64 now = time_now().ts.tv_sec;
if (invoices_find_by_label(invoices, &dummy, label)) { if (invoices_find_by_label(invoices, inv_dbid, label)) {
if (taken(msat)) if (taken(msat))
tal_free(msat); tal_free(msat);
if (taken(label)) if (taken(label))
@@ -310,7 +308,7 @@ bool invoices_create(struct invoices *invoices,
db_exec_prepared_v2(stmt); db_exec_prepared_v2(stmt);
pinvoice->id = db_last_insert_id_v2(take(stmt)); *inv_dbid = db_last_insert_id_v2(take(stmt));
/* Install expiration trigger. */ /* Install expiration trigger. */
if (!invoices->expiration_timer || if (!invoices->expiration_timer ||
@@ -327,9 +325,8 @@ bool invoices_create(struct invoices *invoices,
return true; return true;
} }
bool invoices_find_by_label(struct invoices *invoices, bool invoices_find_by_label(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct json_escape *label) const struct json_escape *label)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
@@ -344,13 +341,13 @@ bool invoices_find_by_label(struct invoices *invoices,
return false; return false;
} }
pinvoice->id = db_col_u64(stmt, "id"); *inv_dbid = db_col_u64(stmt, "id");
tal_free(stmt); tal_free(stmt);
return true; return true;
} }
bool invoices_find_by_rhash(struct invoices *invoices, bool invoices_find_by_rhash(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct sha256 *rhash) const struct sha256 *rhash)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
@@ -365,14 +362,14 @@ bool invoices_find_by_rhash(struct invoices *invoices,
tal_free(stmt); tal_free(stmt);
return false; return false;
} else { } else {
pinvoice->id = db_col_u64(stmt, "id"); *inv_dbid = db_col_u64(stmt, "id");
tal_free(stmt); tal_free(stmt);
return true; return true;
} }
} }
bool invoices_find_unpaid(struct invoices *invoices, bool invoices_find_unpaid(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct sha256 *rhash) const struct sha256 *rhash)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
@@ -388,20 +385,20 @@ bool invoices_find_unpaid(struct invoices *invoices,
tal_free(stmt); tal_free(stmt);
return false; return false;
} else { } else {
pinvoice->id = db_col_u64(stmt, "id"); *inv_dbid = db_col_u64(stmt, "id");
tal_free(stmt); tal_free(stmt);
return true; return true;
} }
} }
bool invoices_delete(struct invoices *invoices, struct invoice invoice) bool invoices_delete(struct invoices *invoices, u64 inv_dbid)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
int changes; int changes;
/* Delete from database. */ /* Delete from database. */
stmt = db_prepare_v2(invoices->wallet->db, stmt = db_prepare_v2(invoices->wallet->db,
SQL("DELETE FROM invoices WHERE id=?;")); SQL("DELETE FROM invoices WHERE id=?;"));
db_bind_u64(stmt, 0, invoice.id); db_bind_u64(stmt, 0, inv_dbid);
db_exec_prepared_v2(stmt); db_exec_prepared_v2(stmt);
changes = db_count_changes(stmt); changes = db_count_changes(stmt);
@@ -411,11 +408,11 @@ bool invoices_delete(struct invoices *invoices, struct invoice invoice)
return false; return false;
} }
/* Tell all the waiters about the fact that it was deleted. */ /* Tell all the waiters about the fact that it was deleted. */
trigger_invoice_waiter_expire_or_delete(invoices, invoice.id, NULL); trigger_invoice_waiter_expire_or_delete(invoices, inv_dbid, true);
return true; return true;
} }
bool invoices_delete_description(struct invoices *invoices, struct invoice invoice) bool invoices_delete_description(struct invoices *invoices, u64 inv_dbid)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
int changes; int changes;
@@ -423,7 +420,7 @@ bool invoices_delete_description(struct invoices *invoices, struct invoice invoi
stmt = db_prepare_v2(invoices->wallet->db, SQL("UPDATE invoices" stmt = db_prepare_v2(invoices->wallet->db, SQL("UPDATE invoices"
" SET description = NULL" " SET description = NULL"
" WHERE ID = ?;")); " WHERE ID = ?;"));
db_bind_u64(stmt, 0, invoice.id); db_bind_u64(stmt, 0, inv_dbid);
db_exec_prepared_v2(stmt); db_exec_prepared_v2(stmt);
changes = db_count_changes(stmt); changes = db_count_changes(stmt);
@@ -502,7 +499,8 @@ static s64 get_next_pay_index(struct db *db)
return next_pay_index; return next_pay_index;
} }
static enum invoice_status invoice_get_status(struct invoices *invoices, struct invoice invoice) static enum invoice_status invoice_get_status(struct invoices *invoices,
u64 inv_dbid)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
enum invoice_status state; enum invoice_status state;
@@ -510,7 +508,7 @@ static enum invoice_status invoice_get_status(struct invoices *invoices, struct
stmt = db_prepare_v2( stmt = db_prepare_v2(
invoices->wallet->db, SQL("SELECT state FROM invoices WHERE id = ?;")); invoices->wallet->db, SQL("SELECT state FROM invoices WHERE id = ?;"));
db_bind_u64(stmt, 0, invoice.id); db_bind_u64(stmt, 0, inv_dbid);
db_query_prepared(stmt); db_query_prepared(stmt);
res = db_step(stmt); res = db_step(stmt);
@@ -521,14 +519,14 @@ static enum invoice_status invoice_get_status(struct invoices *invoices, struct
} }
/* If there's an associated offer, mark it used. */ /* If there's an associated offer, mark it used. */
static void maybe_mark_offer_used(struct db *db, struct invoice invoice) static void maybe_mark_offer_used(struct db *db, u64 inv_dbid)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
struct sha256 local_offer_id; struct sha256 local_offer_id;
stmt = db_prepare_v2( stmt = db_prepare_v2(
db, SQL("SELECT local_offer_id FROM invoices WHERE id = ?;")); db, SQL("SELECT local_offer_id FROM invoices WHERE id = ?;"));
db_bind_u64(stmt, 0, invoice.id); db_bind_u64(stmt, 0, inv_dbid);
db_query_prepared(stmt); db_query_prepared(stmt);
db_step(stmt); db_step(stmt);
@@ -543,13 +541,13 @@ static void maybe_mark_offer_used(struct db *db, struct invoice invoice)
} }
bool invoices_resolve(struct invoices *invoices, bool invoices_resolve(struct invoices *invoices,
struct invoice invoice, u64 inv_dbid,
struct amount_msat received) struct amount_msat received)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
s64 pay_index; s64 pay_index;
u64 paid_timestamp; u64 paid_timestamp;
enum invoice_status state = invoice_get_status(invoices, invoice); enum invoice_status state = invoice_get_status(invoices, inv_dbid);
if (state != UNPAID) if (state != UNPAID)
return false; return false;
@@ -569,13 +567,13 @@ bool invoices_resolve(struct invoices *invoices,
db_bind_u64(stmt, 1, pay_index); db_bind_u64(stmt, 1, pay_index);
db_bind_amount_msat(stmt, 2, &received); db_bind_amount_msat(stmt, 2, &received);
db_bind_u64(stmt, 3, paid_timestamp); db_bind_u64(stmt, 3, paid_timestamp);
db_bind_u64(stmt, 4, invoice.id); db_bind_u64(stmt, 4, inv_dbid);
db_exec_prepared_v2(take(stmt)); db_exec_prepared_v2(take(stmt));
maybe_mark_offer_used(invoices->wallet->db, invoice); maybe_mark_offer_used(invoices->wallet->db, inv_dbid);
/* Tell all the waiters about the paid invoice. */ /* Tell all the waiters about the paid invoice. */
trigger_invoice_waiter_resolve(invoices, invoice.id, &invoice); trigger_invoice_waiter_resolve(invoices, inv_dbid);
return true; return true;
} }
@@ -592,14 +590,14 @@ static void destroy_invoice_waiter(struct invoice_waiter *w)
static void add_invoice_waiter(const tal_t *ctx, static void add_invoice_waiter(const tal_t *ctx,
struct list_head *waiters, struct list_head *waiters,
bool any, bool any,
u64 id, u64 inv_dbid,
void (*cb)(const struct invoice *, void*), void (*cb)(const u64 *, void*),
void* cbarg) void* cbarg)
{ {
struct invoice_waiter *w = tal(ctx, struct invoice_waiter); struct invoice_waiter *w = tal(ctx, struct invoice_waiter);
w->triggered = false; w->triggered = false;
w->any = any; w->any = any;
w->id = id; w->inv_dbid = inv_dbid;
list_add_tail(waiters, &w->list); list_add_tail(waiters, &w->list);
w->cb = cb; w->cb = cb;
w->cbarg = cbarg; w->cbarg = cbarg;
@@ -610,11 +608,10 @@ static void add_invoice_waiter(const tal_t *ctx,
void invoices_waitany(const tal_t *ctx, void invoices_waitany(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
u64 lastpay_index, u64 lastpay_index,
void (*cb)(const struct invoice *, void*), void (*cb)(const u64 *, void*),
void *cbarg) void *cbarg)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
struct invoice invoice;
/* Look for an already-paid invoice. */ /* Look for an already-paid invoice. */
stmt = db_prepare_v2(invoices->wallet->db, stmt = db_prepare_v2(invoices->wallet->db,
@@ -627,9 +624,9 @@ void invoices_waitany(const tal_t *ctx,
db_query_prepared(stmt); db_query_prepared(stmt);
if (db_step(stmt)) { if (db_step(stmt)) {
invoice.id = db_col_u64(stmt, "id"); u64 inv_dbid = db_col_u64(stmt, "id");
cb(&invoice, cbarg); cb(&inv_dbid, cbarg);
} else { } else {
/* None found. */ /* None found. */
add_invoice_waiter(ctx, &invoices->waiters, add_invoice_waiter(ctx, &invoices->waiters,
@@ -641,27 +638,27 @@ void invoices_waitany(const tal_t *ctx,
void invoices_waitone(const tal_t *ctx, void invoices_waitone(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
struct invoice invoice, u64 inv_dbid,
void (*cb)(const struct invoice *, void*), void (*cb)(const u64 *, void*),
void *cbarg) void *cbarg)
{ {
enum invoice_status state; enum invoice_status state;
state = invoice_get_status(invoices, invoice); state = invoice_get_status(invoices, inv_dbid);
if (state == PAID || state == EXPIRED) { if (state == PAID || state == EXPIRED) {
cb(&invoice, cbarg); cb(&inv_dbid, cbarg);
return; return;
} }
/* Not yet paid. */ /* Not yet paid. */
add_invoice_waiter(ctx, &invoices->waiters, add_invoice_waiter(ctx, &invoices->waiters,
false, invoice.id, cb, cbarg); false, inv_dbid, cb, cbarg);
} }
struct invoice_details *invoices_get_details(const tal_t *ctx, struct invoice_details *invoices_get_details(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
struct invoice invoice) u64 inv_dbid)
{ {
struct db_stmt *stmt; struct db_stmt *stmt;
bool res; bool res;
@@ -683,7 +680,7 @@ struct invoice_details *invoices_get_details(const tal_t *ctx,
", local_offer_id" ", local_offer_id"
" FROM invoices" " FROM invoices"
" WHERE id = ?;")); " WHERE id = ?;"));
db_bind_u64(stmt, 0, invoice.id); db_bind_u64(stmt, 0, inv_dbid);
db_query_prepared(stmt); db_query_prepared(stmt);
res = db_step(stmt); res = db_step(stmt);
assert(res); assert(res);

View File

@@ -30,7 +30,7 @@ struct invoices *invoices_new(const tal_t *ctx,
* invoices_create - Create a new invoice. * invoices_create - Create a new invoice.
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @pinvoice - pointer to location to load new invoice in. * @inv_dbid - pointer to location to put the invoice dbid in
* @msat - the amount the invoice should have, or * @msat - the amount the invoice should have, or
* NULL for any-amount invoices. * NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be * @label - the unique label for this invoice. Must be
@@ -43,7 +43,7 @@ struct invoices *invoices_new(const tal_t *ctx,
* FIXME: Fallback addresses * FIXME: Fallback addresses
*/ */
bool invoices_create(struct invoices *invoices, bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct amount_msat *msat TAKES, const struct amount_msat *msat TAKES,
const struct json_escape *label TAKES, const struct json_escape *label TAKES,
u64 expiry, u64 expiry,
@@ -58,14 +58,14 @@ bool invoices_create(struct invoices *invoices,
* invoices_find_by_label - Search for an invoice by label * invoices_find_by_label - Search for an invoice by label
* *
* @param invoices - the invoice handler. * @param invoices - the invoice handler.
* @param pinvoice - pointer to location to load found invoice in. * @param inv_dbid - pointer to location to put the found dbid in
* @param label - the label to search for. * @param label - the label to search for.
* *
* Returns false if no invoice with that label exists. * Returns false if no invoice with that label exists.
* Returns true if found. * Returns true if found.
*/ */
bool invoices_find_by_label(struct invoices *invoices, bool invoices_find_by_label(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct json_escape *label); const struct json_escape *label);
/** /**
@@ -73,14 +73,14 @@ bool invoices_find_by_label(struct invoices *invoices,
* payment_hash * payment_hash
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @pinvoice - pointer to location to load found invoice in. * @inv_dbid - pointer to location to put the found dbid in
* @rhash - the payment_hash to search for. * @rhash - the payment_hash to search for.
* *
* Returns false if no invoice with that rhash exists. * Returns false if no invoice with that rhash exists.
* Returns true if found. * Returns true if found.
*/ */
bool invoices_find_by_rhash(struct invoices *invoices, bool invoices_find_by_rhash(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct sha256 *rhash); const struct sha256 *rhash);
/** /**
@@ -88,37 +88,36 @@ bool invoices_find_by_rhash(struct invoices *invoices,
* payment_hash * payment_hash
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @pinvoice - pointer to location to load found invoice in. * @inv_dbid - pointer to location to load found invoice dbid in.
* @rhash - the payment_hash to search for. * @rhash - the payment_hash to search for.
* *
* Returns false if no unpaid invoice with that rhash exists. * Returns false if no unpaid invoice with that rhash exists.
* Returns true if found. * Returns true if found.
*/ */
bool invoices_find_unpaid(struct invoices *invoices, bool invoices_find_unpaid(struct invoices *invoices,
struct invoice *pinvoice, u64 *inv_dbid,
const struct sha256 *rhash); const struct sha256 *rhash);
/** /**
* invoices_delete - Delete an invoice * invoices_delete - Delete an invoice
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @invoice - the invoice to delete. * @inv_dbid - the invoice to delete.
* *
* Return false on failure. * Return false on failure.
*/ */
bool invoices_delete(struct invoices *invoices, bool invoices_delete(struct invoices *invoices, u64 inv_dbid);
struct invoice invoice);
/** /**
* invoices_delete_description - Remove description from an invoice * invoices_delete_description - Remove description from an invoice
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @invoice - the invoice to remove description from. * @inv_dbid - the invoice to remove description from.
* *
* Return false on failure. * Return false on failure.
*/ */
bool invoices_delete_description(struct invoices *invoices, bool invoices_delete_description(struct invoices *invoices,
struct invoice invoice); u64 inv_dbid);
/** /**
* invoices_delete_expired - Delete all expired invoices * invoices_delete_expired - Delete all expired invoices
@@ -166,13 +165,13 @@ const struct invoice_details *invoices_iterator_deref(
* invoices_resolve - Mark an invoice as paid * invoices_resolve - Mark an invoice as paid
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @invoice - the invoice to mark as paid. * @inv_dbid - the invoice to mark as paid.
* @received - the actual amount received. * @received - the actual amount received.
* *
* If the invoice is not UNPAID, returns false. * If the invoice is not UNPAID, returns false.
*/ */
bool invoices_resolve(struct invoices *invoices, bool invoices_resolve(struct invoices *invoices,
struct invoice invoice, u64 inv_dbid,
struct amount_msat received); struct amount_msat received);
/** /**
@@ -187,12 +186,14 @@ bool invoices_resolve(struct invoices *invoices,
* paid with pay_index greater than lastpay_index, this * paid with pay_index greater than lastpay_index, this
* is called immediately, otherwise it is called during * is called immediately, otherwise it is called during
* an invoices_resolve call. * an invoices_resolve call.
* If the invoice was deleted, the callback is given a NULL
* first argument.
* @cbarg - the callback data. * @cbarg - the callback data.
*/ */
void invoices_waitany(const tal_t *ctx, void invoices_waitany(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
u64 lastpay_index, u64 lastpay_index,
void (*cb)(const struct invoice *, void*), void (*cb)(const u64 *, void*),
void *cbarg); void *cbarg);
/** /**
@@ -202,19 +203,19 @@ void invoices_waitany(const tal_t *ctx,
* @ctx - the owner of the callback. If the owner is freed, * @ctx - the owner of the callback. If the owner is freed,
* the callback is cancelled. * the callback is cancelled.
* @invoices - the invoice handler, * @invoices - the invoice handler,
* @invoice - the invoice to wait on. * @inv_dbid - the invoice to wait on.
* @cb - the callback to invoice. If invoice is already paid * @cb - the callback to invoice. If invoice is already paid
* or expired, this is called immediately, otherwise it is * or expired, this is called immediately, otherwise it is
* called during an invoices_resolve or invoices_delete call. * called during an invoices_resolve or invoices_delete call.
* If the invoice was deleted, the callback is given a NULL * If the invoice was deleted, the callback is given a NULL
* invoice. * first argument (inv_dbid).
* @cbarg - the callback data. * @cbarg - the callback data.
* *
*/ */
void invoices_waitone(const tal_t *ctx, void invoices_waitone(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
struct invoice invoice, u64 inv_dbid,
void (*cb)(const struct invoice *, void*), void (*cb)(const u64 *, void*),
void *cbarg); void *cbarg);
/** /**
@@ -222,11 +223,11 @@ void invoices_waitone(const tal_t *ctx,
* *
* @ctx - the owner of the label and msatoshi fields returned. * @ctx - the owner of the label and msatoshi fields returned.
* @invoices - the invoice handler, * @invoices - the invoice handler,
* @invoice - the invoice to get details on. * @inv_dbid - the invoice to get details on.
* @return pointer to the invoice details allocated off of `ctx`. * @return pointer to the invoice details allocated off of `ctx`.
*/ */
struct invoice_details *invoices_get_details(const tal_t *ctx, struct invoice_details *invoices_get_details(const tal_t *ctx,
struct invoices *invoices, struct invoices *invoices,
struct invoice invoice); u64 inv_dbid);
#endif /* LIGHTNING_WALLET_INVOICES_H */ #endif /* LIGHTNING_WALLET_INVOICES_H */

View File

@@ -238,84 +238,11 @@ void htlc_set_add(struct lightningd *ld UNNEEDED,
struct amount_msat total_msat UNNEEDED, struct amount_msat total_msat UNNEEDED,
const struct secret *payment_secret UNNEEDED) const struct secret *payment_secret UNNEEDED)
{ fprintf(stderr, "htlc_set_add called!\n"); abort(); } { fprintf(stderr, "htlc_set_add called!\n"); abort(); }
/* Generated stub for invoices_create */
bool invoices_create(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escape *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,
const char *description UNNEEDED,
const u8 *features UNNEEDED,
const struct preimage *r UNNEEDED,
const struct sha256 *rhash UNNEEDED,
const struct sha256 *local_offer_id UNNEEDED)
{ fprintf(stderr, "invoices_create called!\n"); abort(); }
/* Generated stub for invoices_delete */
bool invoices_delete(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_delete called!\n"); abort(); }
/* Generated stub for invoices_delete_description */
bool invoices_delete_description(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_delete_description called!\n"); abort(); }
/* Generated stub for invoices_delete_expired */
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
u64 max_expiry_time UNNEEDED)
{ fprintf(stderr, "invoices_delete_expired called!\n"); abort(); }
/* Generated stub for invoices_find_by_label */
bool invoices_find_by_label(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct json_escape *label UNNEEDED)
{ fprintf(stderr, "invoices_find_by_label called!\n"); abort(); }
/* Generated stub for invoices_find_by_rhash */
bool invoices_find_by_rhash(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_by_rhash called!\n"); abort(); }
/* Generated stub for invoices_find_unpaid */
bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
/* Generated stub for invoices_get_details */
struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
/* Generated stub for invoices_iterate */
bool invoices_iterate(struct invoices *invoices UNNEEDED,
struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterate called!\n"); abort(); }
/* Generated stub for invoices_iterator_deref */
const struct invoice_details *invoices_iterator_deref(
const tal_t *ctx UNNEEDED, struct invoices *invoices UNNEEDED,
const struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterator_deref called!\n"); abort(); }
/* Generated stub for invoices_new */ /* Generated stub for invoices_new */
struct invoices *invoices_new(const tal_t *ctx UNNEEDED, struct invoices *invoices_new(const tal_t *ctx UNNEEDED,
struct wallet *wallet UNNEEDED, struct wallet *wallet UNNEEDED,
struct timers *timers UNNEEDED) struct timers *timers UNNEEDED)
{ fprintf(stderr, "invoices_new called!\n"); abort(); } { fprintf(stderr, "invoices_new called!\n"); abort(); }
/* Generated stub for invoices_resolve */
bool invoices_resolve(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED,
struct amount_msat received UNNEEDED)
{ fprintf(stderr, "invoices_resolve called!\n"); abort(); }
/* Generated stub for invoices_waitany */
void invoices_waitany(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 lastpay_index UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitany called!\n"); abort(); }
/* Generated stub for invoices_waitone */
void invoices_waitone(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitone called!\n"); abort(); }
/* Generated stub for is_hsm_secret_encrypted */ /* Generated stub for is_hsm_secret_encrypted */
int is_hsm_secret_encrypted(const char *path UNNEEDED) int is_hsm_secret_encrypted(const char *path UNNEEDED)
{ fprintf(stderr, "is_hsm_secret_encrypted called!\n"); abort(); } { fprintf(stderr, "is_hsm_secret_encrypted called!\n"); abort(); }

View File

@@ -3044,93 +3044,6 @@ bool wallet_htlcs_load_out_for_channel(struct wallet *wallet,
return ok; return ok;
} }
bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice,
const struct amount_msat *msat TAKES,
const struct json_escape *label TAKES,
u64 expiry,
const char *b11enc,
const char *description,
const u8 *features,
const struct preimage *r,
const struct sha256 *rhash,
const struct sha256 *local_offer_id)
{
return invoices_create(wallet->invoices, pinvoice, msat, label, expiry, b11enc, description, features, r, rhash, local_offer_id);
}
bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice,
const struct json_escape *label)
{
return invoices_find_by_label(wallet->invoices, pinvoice, label);
}
bool wallet_invoice_find_by_rhash(struct wallet *wallet,
struct invoice *pinvoice,
const struct sha256 *rhash)
{
return invoices_find_by_rhash(wallet->invoices, pinvoice, rhash);
}
bool wallet_invoice_find_unpaid(struct wallet *wallet,
struct invoice *pinvoice,
const struct sha256 *rhash)
{
return invoices_find_unpaid(wallet->invoices, pinvoice, rhash);
}
bool wallet_invoice_delete(struct wallet *wallet,
struct invoice invoice)
{
return invoices_delete(wallet->invoices, invoice);
}
bool wallet_invoice_delete_description(struct wallet *wallet,
struct invoice invoice)
{
return invoices_delete_description(wallet->invoices, invoice);
}
void wallet_invoice_delete_expired(struct wallet *wallet, u64 e)
{
invoices_delete_expired(wallet->invoices, e);
}
bool wallet_invoice_iterate(struct wallet *wallet,
struct invoice_iterator *it)
{
return invoices_iterate(wallet->invoices, it);
}
const struct invoice_details *
wallet_invoice_iterator_deref(const tal_t *ctx, struct wallet *wallet,
const struct invoice_iterator *it)
{
return invoices_iterator_deref(ctx, wallet->invoices, it);
}
bool wallet_invoice_resolve(struct wallet *wallet,
struct invoice invoice,
struct amount_msat msatoshi_received)
{
return invoices_resolve(wallet->invoices, invoice, msatoshi_received);
}
void wallet_invoice_waitany(const tal_t *ctx,
struct wallet *wallet,
u64 lastpay_index,
void (*cb)(const struct invoice *, void*),
void *cbarg)
{
invoices_waitany(ctx, wallet->invoices, lastpay_index, cb, cbarg);
}
void wallet_invoice_waitone(const tal_t *ctx,
struct wallet *wallet,
struct invoice invoice,
void (*cb)(const struct invoice *, void*),
void *cbarg)
{
invoices_waitone(ctx, wallet->invoices, invoice, cb, cbarg);
}
struct invoice_details *wallet_invoice_details(const tal_t *ctx,
struct wallet *wallet,
struct invoice invoice)
{
return invoices_get_details(ctx, wallet->invoices, invoice);
}
struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet,
struct channel *chan, u64 commit_num) struct channel *chan, u64 commit_num)
{ {

View File

@@ -15,6 +15,7 @@ struct amount_msat;
struct invoices; struct invoices;
struct channel; struct channel;
struct channel_inflight; struct channel_inflight;
struct json_escape;
struct lightningd; struct lightningd;
struct node_id; struct node_id;
struct oneshot; struct oneshot;
@@ -62,6 +63,13 @@ static inline enum output_status output_status_in_db(enum output_status s)
fatal("%s: %u is invalid", __func__, s); fatal("%s: %u is invalid", __func__, s);
} }
/* An object that handles iteration over the set of invoices */
struct invoice_iterator {
/* The contents of this object is subject to change
* and should not be depended upon */
void *p;
};
/* Enumeration of all known output types. These include all types that /* Enumeration of all known output types. These include all types that
* could ever end up on-chain and we may need to react upon. Notice * could ever end up on-chain and we may need to react upon. Notice
* that `to_local`, `htlc_offer`, and `htlc_recv` may need immediate * that `to_local`, `htlc_offer`, and `htlc_recv` may need immediate
@@ -830,247 +838,6 @@ static inline enum invoice_status invoice_status_in_db(enum invoice_status s)
fatal("%s: %u is invalid", __func__, s); fatal("%s: %u is invalid", __func__, s);
} }
/* The information about an invoice */
struct invoice_details {
/* Current invoice state */
enum invoice_status state;
/* Preimage for this invoice */
struct preimage r;
/* Hash of preimage r */
struct sha256 rhash;
/* Label assigned by user */
const struct json_escape *label;
/* NULL if they specified "any" */
struct amount_msat *msat;
/* Absolute UNIX epoch time this will expire */
u64 expiry_time;
/* Set if state == PAID; order to be returned by waitanyinvoice */
u64 pay_index;
/* Set if state == PAID; amount received */
struct amount_msat received;
/* Set if state == PAID; time paid */
u64 paid_timestamp;
/* BOLT11 or BOLT12 encoding for this invoice */
const char *invstring;
/* The description of the payment. */
char *description;
/* The features, if any (tal_arr) */
u8 *features;
/* The offer this refers to, if any. */
struct sha256 *local_offer_id;
};
/* An object that handles iteration over the set of invoices */
struct invoice_iterator {
/* The contents of this object is subject to change
* and should not be depended upon */
void *p;
};
struct invoice {
/* Internal, rest of lightningd should not use */
/* Database ID */
u64 id;
};
#define INVOICE_MAX_LABEL_LEN 128
/**
* wallet_invoice_create - Create a new invoice.
*
* @wallet - the wallet to create the invoice in.
* @pinvoice - pointer to location to load new invoice in.
* @msat - the amount the invoice should have, or
* NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be
* non-NULL.
* @expiry - the number of seconds before the invoice
* expires
*
* Returns false if label already exists or expiry is 0.
* Returns true if created invoice.
* FIXME: Fallback addresses
*/
bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice,
const struct amount_msat *msat TAKES,
const struct json_escape *label TAKES,
u64 expiry,
const char *b11enc,
const char *description,
const u8 *features,
const struct preimage *r,
const struct sha256 *rhash,
const struct sha256 *local_offer_id);
/**
* wallet_invoice_find_by_label - Search for an invoice by label
*
* @wallet - the wallet to search.
* @pinvoice - pointer to location to load found invoice in.
* @label - the label to search for.
*
* Returns false if no invoice with that label exists.
* Returns true if found.
*/
bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice,
const struct json_escape *label);
/**
* wallet_invoice_find_by_rhash - Search for an invoice by payment_hash
*
* @wallet - the wallet to search.
* @pinvoice - pointer to location to load found invoice in.
* @rhash - the payment_hash to search for.
*
* Returns false if no invoice with that rhash exists.
* Returns true if found.
*/
bool wallet_invoice_find_by_rhash(struct wallet *wallet,
struct invoice *pinvoice,
const struct sha256 *rhash);
/**
* wallet_invoice_find_unpaid - Search for an unpaid, unexpired invoice by
* payment_hash
*
* @wallet - the wallet to search.
* @pinvoice - pointer to location to load found invoice in.
* @rhash - the payment_hash to search for.
*
* Returns false if no unpaid invoice with that rhash exists.
* Returns true if found.
*/
bool wallet_invoice_find_unpaid(struct wallet *wallet,
struct invoice *pinvoice,
const struct sha256 *rhash);
/**
* wallet_invoice_delete - Delete an invoice
*
* @wallet - the wallet to delete the invoice from.
* @invoice - the invoice to delete.
*
* Return false on failure.
*/
bool wallet_invoice_delete(struct wallet *wallet,
struct invoice invoice);
bool wallet_invoice_delete_description(struct wallet *wallet,
struct invoice invoice);
/**
* wallet_invoice_delete_expired - Delete all expired invoices
* with expiration time less than or equal to the given.
*
* @wallet - the wallet to delete invoices from.
* @max_expiry_time - the maximum expiry time to delete.
*/
void wallet_invoice_delete_expired(struct wallet *wallet,
u64 max_expiry_time);
/**
* wallet_invoice_iterate - Iterate over all existing invoices
*
* @wallet - the wallet whose invoices are to be iterated over.
* @iterator - the iterator object to use.
*
* Return false at end-of-sequence, true if still iterating.
* Usage:
*
* struct invoice_iterator it;
* memset(&it, 0, sizeof(it))
* while (wallet_invoice_iterate(wallet, &it)) {
* ...
* }
*/
bool wallet_invoice_iterate(struct wallet *wallet,
struct invoice_iterator *it);
/**
* wallet_invoice_iterator_deref - Read the details of the
* invoice currently pointed to by the given iterator.
*
* @ctx - the owner of the label and msatoshi fields returned.
* @wallet - the wallet whose invoices are to be iterated over.
* @iterator - the iterator object to use.
* @return pointer to the invoice details allocated off of `ctx`.
*/
const struct invoice_details *wallet_invoice_iterator_deref(const tal_t *ctx,
struct wallet *wallet,
const struct invoice_iterator *it);
/**
* wallet_invoice_resolve - Mark an invoice as paid
*
* @wallet - the wallet containing the invoice.
* @invoice - the invoice to mark as paid.
* @received - the actual amount received.
*
* If the invoice is not UNPAID, returns false.
*/
bool wallet_invoice_resolve(struct wallet *wallet,
struct invoice invoice,
struct amount_msat received);
/**
* wallet_invoice_waitany - Wait for any invoice to be paid.
*
* @ctx - the owner of the callback. If the owner is freed,
* the callback is cancelled.
* @wallet - the wallet to query.
* @lastpay_index - wait for invoices after the specified
* pay_index. Use 0 to wait for the first invoice.
* @cb - the callback to invoke. If an invoice is already
* paid with pay_index greater than lastpay_index, this
* is called immediately, otherwise it is called during
* an invoices_resolve call. Will never be given a NULL
* pointer-to-invoice.
* @cbarg - the callback data.
*/
void wallet_invoice_waitany(const tal_t *ctx,
struct wallet *wallet,
u64 lastpay_index,
void (*cb)(const struct invoice *, void*),
void *cbarg);
/**
* wallet_invoice_waitone - Wait for a specific invoice to be paid,
* deleted, or expired.
*
* @ctx - the owner of the callback. If the owner is freed,
* the callback is cancelled.
* @wallet - the wallet to query.
* @invoice - the invoice to wait on.
* @cb - the callback to invoice. If invoice is already paid
* or expired, this is called immediately, otherwise it is
* called during an invoices_resolve or invoices_delete call.
* If the invoice was deleted, the callback is given a NULL
* invoice.
* @cbarg - the callback data.
*
*/
void wallet_invoice_waitone(const tal_t *ctx,
struct wallet *wallet,
struct invoice invoice,
void (*cb)(const struct invoice *, void*),
void *cbarg);
/**
* wallet_invoice_details - Get the invoice_details of an invoice.
*
* @ctx - the owner of the label and msatoshi fields returned.
* @wallet - the wallet to query.
* @invoice - the invoice to get details on.
* @return pointer to the invoice details allocated off of `ctx`.
*/
struct invoice_details *wallet_invoice_details(const tal_t *ctx,
struct wallet *wallet,
struct invoice invoice);
/** /**
* wallet_htlc_stubs - Retrieve HTLC stubs for the given channel * wallet_htlc_stubs - Retrieve HTLC stubs for the given channel
* *