mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
invoices: Semantically separate invoice details from invoice.
In preparation for removing in-memory invoice structures. Invoice details are requested rarely anyway.
This commit is contained in:
parent
fc3e6782dd
commit
9b4c6699f9
@ -19,7 +19,7 @@
|
|||||||
#include <sodium/randombytes.h>
|
#include <sodium/randombytes.h>
|
||||||
#include <wire/wire_sync.h>
|
#include <wire/wire_sync.h>
|
||||||
|
|
||||||
static const char *invoice_status_str(const struct invoice *inv)
|
static const char *invoice_status_str(const struct invoice_details *inv)
|
||||||
{
|
{
|
||||||
if (inv->state == PAID)
|
if (inv->state == PAID)
|
||||||
return "paid";
|
return "paid";
|
||||||
@ -29,7 +29,7 @@ static const char *invoice_status_str(const struct invoice *inv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void json_add_invoice(struct json_result *response,
|
static void json_add_invoice(struct json_result *response,
|
||||||
const struct invoice *inv,
|
const struct invoice_details *inv,
|
||||||
bool modern)
|
bool modern)
|
||||||
{
|
{
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@ -60,9 +60,11 @@ static void json_add_invoice(struct json_result *response,
|
|||||||
static void tell_waiter(struct command *cmd, const struct invoice *inv)
|
static void tell_waiter(struct command *cmd, const struct invoice *inv)
|
||||||
{
|
{
|
||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(cmd);
|
||||||
|
struct invoice_details details;
|
||||||
|
|
||||||
json_add_invoice(response, inv, true);
|
wallet_invoice_details(cmd, cmd->ld->wallet, inv, &details);
|
||||||
if (inv->state == PAID)
|
json_add_invoice(response, &details, true);
|
||||||
|
if (details.state == PAID)
|
||||||
command_success(cmd, response);
|
command_success(cmd, response);
|
||||||
else
|
else
|
||||||
command_fail_detailed(cmd, -2, response,
|
command_fail_detailed(cmd, -2, response,
|
||||||
@ -103,6 +105,7 @@ static void json_invoice(struct command *cmd,
|
|||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
const struct invoice *invoice;
|
const struct invoice *invoice;
|
||||||
|
struct invoice_details details;
|
||||||
jsmntok_t *msatoshi, *label, *desc, *exp, *fallback;
|
jsmntok_t *msatoshi, *label, *desc, *exp, *fallback;
|
||||||
u64 *msatoshi_val;
|
u64 *msatoshi_val;
|
||||||
const char *label_val;
|
const char *label_val;
|
||||||
@ -199,11 +202,14 @@ static void json_invoice(struct command *cmd,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get details */
|
||||||
|
wallet_invoice_details(cmd, cmd->ld->wallet, invoice, &details);
|
||||||
|
|
||||||
/* Construct bolt11 string. */
|
/* Construct bolt11 string. */
|
||||||
b11 = new_bolt11(cmd, invoice->msatoshi);
|
b11 = new_bolt11(cmd, details.msatoshi);
|
||||||
b11->chain = get_chainparams(cmd->ld);
|
b11->chain = get_chainparams(cmd->ld);
|
||||||
b11->timestamp = time_now().ts.tv_sec;
|
b11->timestamp = time_now().ts.tv_sec;
|
||||||
b11->payment_hash = invoice->rhash;
|
b11->payment_hash = details.rhash;
|
||||||
b11->receiver_id = cmd->ld->id;
|
b11->receiver_id = cmd->ld->id;
|
||||||
b11->min_final_cltv_expiry = cmd->ld->config.cltv_final;
|
b11->min_final_cltv_expiry = cmd->ld->config.cltv_final;
|
||||||
b11->expiry = expiry;
|
b11->expiry = expiry;
|
||||||
@ -217,10 +223,10 @@ static void json_invoice(struct command *cmd,
|
|||||||
|
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_hex(response, "payment_hash",
|
json_add_hex(response, "payment_hash",
|
||||||
&invoice->rhash, sizeof(invoice->rhash));
|
&details.rhash, sizeof(details.rhash));
|
||||||
if (deprecated_apis)
|
if (deprecated_apis)
|
||||||
json_add_u64(response, "expiry_time", invoice->expiry_time);
|
json_add_u64(response, "expiry_time", details.expiry_time);
|
||||||
json_add_u64(response, "expires_at", invoice->expiry_time);
|
json_add_u64(response, "expires_at", details.expiry_time);
|
||||||
json_add_string(response, "bolt11", b11enc);
|
json_add_string(response, "bolt11", b11enc);
|
||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
|
|
||||||
@ -240,15 +246,17 @@ static void json_add_invoices(struct json_result *response,
|
|||||||
bool modern)
|
bool modern)
|
||||||
{
|
{
|
||||||
const struct invoice *i;
|
const struct invoice *i;
|
||||||
|
struct invoice_details details;
|
||||||
char *lbl = NULL;
|
char *lbl = NULL;
|
||||||
if (label)
|
if (label)
|
||||||
lbl = tal_strndup(response, &buffer[label->start], label->end - label->start);
|
lbl = tal_strndup(response, &buffer[label->start], label->end - label->start);
|
||||||
|
|
||||||
i = NULL;
|
i = NULL;
|
||||||
while ((i = wallet_invoice_iterate(wallet, i)) != NULL) {
|
while ((i = wallet_invoice_iterate(wallet, i)) != NULL) {
|
||||||
if (lbl && !streq(i->label, lbl))
|
wallet_invoice_details(response, wallet, i, &details);
|
||||||
|
if (lbl && !streq(details.label, lbl))
|
||||||
continue;
|
continue;
|
||||||
json_add_invoice(response, i, modern);
|
json_add_invoice(response, &details, modern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +319,7 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
const struct invoice *i;
|
const struct invoice *i;
|
||||||
|
struct invoice_details details;
|
||||||
jsmntok_t *labeltok, *statustok;
|
jsmntok_t *labeltok, *statustok;
|
||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(cmd);
|
||||||
const char *label, *status, *actual_status;
|
const char *label, *status, *actual_status;
|
||||||
@ -330,12 +339,13 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
command_fail(cmd, "Unknown invoice");
|
command_fail(cmd, "Unknown invoice");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
||||||
|
|
||||||
status = tal_strndup(cmd, buffer + statustok->start,
|
status = tal_strndup(cmd, buffer + statustok->start,
|
||||||
statustok->end - statustok->start);
|
statustok->end - statustok->start);
|
||||||
/* 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! */
|
||||||
actual_status = invoice_status_str(i);
|
actual_status = invoice_status_str(&details);
|
||||||
if (!streq(actual_status, status)) {
|
if (!streq(actual_status, status)) {
|
||||||
command_fail(cmd, "Invoice status is %s not %s",
|
command_fail(cmd, "Invoice status is %s not %s",
|
||||||
actual_status, status);
|
actual_status, status);
|
||||||
@ -344,7 +354,7 @@ static void json_delinvoice(struct command *cmd,
|
|||||||
|
|
||||||
/* Get invoice details before attempting to delete, as
|
/* Get invoice details before attempting to delete, as
|
||||||
* otherwise the invoice will be freed. */
|
* otherwise the invoice will be freed. */
|
||||||
json_add_invoice(response, i, true);
|
json_add_invoice(response, &details, true);
|
||||||
|
|
||||||
if (!wallet_invoice_delete(wallet, i)) {
|
if (!wallet_invoice_delete(wallet, i)) {
|
||||||
log_broken(cmd->ld->log,
|
log_broken(cmd->ld->log,
|
||||||
@ -415,6 +425,7 @@ static void json_waitinvoice(struct command *cmd,
|
|||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
const struct invoice *i;
|
const struct invoice *i;
|
||||||
|
struct invoice_details details;
|
||||||
struct wallet *wallet = cmd->ld->wallet;
|
struct wallet *wallet = cmd->ld->wallet;
|
||||||
jsmntok_t *labeltok;
|
jsmntok_t *labeltok;
|
||||||
const char *label = NULL;
|
const char *label = NULL;
|
||||||
@ -430,7 +441,10 @@ static void json_waitinvoice(struct command *cmd,
|
|||||||
if (!i) {
|
if (!i) {
|
||||||
command_fail(cmd, "Label not found");
|
command_fail(cmd, "Label not found");
|
||||||
return;
|
return;
|
||||||
} else if (i->state == PAID || i->state == EXPIRED) {
|
}
|
||||||
|
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
|
||||||
|
|
||||||
|
if (details.state == PAID || details.state == EXPIRED) {
|
||||||
tell_waiter(cmd, i);
|
tell_waiter(cmd, i);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -230,7 +230,9 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
{
|
{
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
const struct invoice *invoice;
|
const struct invoice *invoice;
|
||||||
|
struct invoice_details details;
|
||||||
struct lightningd *ld = hin->key.channel->peer->ld;
|
struct lightningd *ld = hin->key.channel->peer->ld;
|
||||||
|
const tal_t *tmpctx = tal_tmpctx(ld);
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
@ -265,6 +267,7 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
failcode = WIRE_UNKNOWN_PAYMENT_HASH;
|
failcode = WIRE_UNKNOWN_PAYMENT_HASH;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
wallet_invoice_details(tmpctx, ld->wallet, invoice, &details);
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
@ -276,10 +279,10 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
*
|
*
|
||||||
* 1. type: PERM|16 (`incorrect_payment_amount`)
|
* 1. type: PERM|16 (`incorrect_payment_amount`)
|
||||||
*/
|
*/
|
||||||
if (invoice->msatoshi != NULL && hin->msatoshi < *invoice->msatoshi) {
|
if (details.msatoshi != NULL && hin->msatoshi < *details.msatoshi) {
|
||||||
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
|
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (invoice->msatoshi != NULL && hin->msatoshi > *invoice->msatoshi * 2) {
|
} else if (details.msatoshi != NULL && hin->msatoshi > *details.msatoshi * 2) {
|
||||||
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
|
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -300,17 +303,21 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64,
|
log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64,
|
||||||
invoice->label, hin->key.id);
|
details.label, hin->key.id);
|
||||||
log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u",
|
log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u",
|
||||||
invoice->label, hin->msatoshi, cltv_expiry);
|
details.label, hin->msatoshi, cltv_expiry);
|
||||||
fulfill_htlc(hin, &invoice->r);
|
fulfill_htlc(hin, &details.r);
|
||||||
wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi);
|
wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi);
|
||||||
|
|
||||||
|
tal_free(tmpctx);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* Final hop never sends an UPDATE. */
|
/* Final hop never sends an UPDATE. */
|
||||||
assert(!(failcode & UPDATE));
|
assert(!(failcode & UPDATE));
|
||||||
local_fail_htlc(hin, failcode, NULL);
|
local_fail_htlc(hin, failcode, NULL);
|
||||||
|
|
||||||
|
tal_free(tmpctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,36 +42,38 @@ static void trigger_invoice_waiter(struct invoice_waiter *w,
|
|||||||
w->cb(invoice, w->cbarg);
|
w->cb(invoice, w->cbarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wallet_stmt2invoice(sqlite3_stmt *stmt, struct invoice *inv)
|
static bool wallet_stmt2invoice_details(sqlite3_stmt *stmt,
|
||||||
|
struct invoice *invoice,
|
||||||
|
struct invoice_details *dtl)
|
||||||
{
|
{
|
||||||
inv->id = sqlite3_column_int64(stmt, 0);
|
invoice->id = sqlite3_column_int64(stmt, 0);
|
||||||
inv->state = sqlite3_column_int(stmt, 1);
|
dtl->state = sqlite3_column_int(stmt, 1);
|
||||||
|
|
||||||
assert(sqlite3_column_bytes(stmt, 2) == sizeof(struct preimage));
|
assert(sqlite3_column_bytes(stmt, 2) == sizeof(struct preimage));
|
||||||
memcpy(&inv->r, sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
|
memcpy(&dtl->r, sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
|
||||||
|
|
||||||
assert(sqlite3_column_bytes(stmt, 3) == sizeof(struct sha256));
|
assert(sqlite3_column_bytes(stmt, 3) == sizeof(struct sha256));
|
||||||
memcpy(&inv->rhash, sqlite3_column_blob(stmt, 3), sqlite3_column_bytes(stmt, 3));
|
memcpy(&dtl->rhash, sqlite3_column_blob(stmt, 3), sqlite3_column_bytes(stmt, 3));
|
||||||
|
|
||||||
inv->label = tal_strndup(inv, sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
|
dtl->label = tal_strndup(dtl, sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
|
||||||
|
|
||||||
if (sqlite3_column_type(stmt, 5) != SQLITE_NULL) {
|
if (sqlite3_column_type(stmt, 5) != SQLITE_NULL) {
|
||||||
inv->msatoshi = tal(inv, u64);
|
dtl->msatoshi = tal(dtl, u64);
|
||||||
*inv->msatoshi = sqlite3_column_int64(stmt, 5);
|
*dtl->msatoshi = sqlite3_column_int64(stmt, 5);
|
||||||
} else {
|
} else {
|
||||||
inv->msatoshi = NULL;
|
dtl->msatoshi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inv->expiry_time = sqlite3_column_int64(stmt, 6);
|
dtl->expiry_time = sqlite3_column_int64(stmt, 6);
|
||||||
|
|
||||||
if (inv->state == PAID) {
|
if (dtl->state == PAID) {
|
||||||
inv->pay_index = sqlite3_column_int64(stmt, 7);
|
dtl->pay_index = sqlite3_column_int64(stmt, 7);
|
||||||
inv->msatoshi_received = sqlite3_column_int64(stmt, 8);
|
dtl->msatoshi_received = sqlite3_column_int64(stmt, 8);
|
||||||
inv->paid_timestamp = sqlite3_column_int64(stmt, 9);
|
dtl->paid_timestamp = sqlite3_column_int64(stmt, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_head_init(&inv->waitone_waiters);
|
list_head_init(&invoice->waitone_waiters);
|
||||||
inv->expiration_timer = NULL;
|
invoice->expiration_timer = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -102,7 +104,7 @@ static void trigger_expiration(struct invoice *i)
|
|||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
struct invoice_waiter *w;
|
struct invoice_waiter *w;
|
||||||
|
|
||||||
assert(i->state == UNPAID);
|
assert(i->details->state == UNPAID);
|
||||||
|
|
||||||
/* Timer already triggered, destroy the timer object. */
|
/* Timer already triggered, destroy the timer object. */
|
||||||
i->expiration_timer = tal_free(i->expiration_timer);
|
i->expiration_timer = tal_free(i->expiration_timer);
|
||||||
@ -111,11 +113,11 @@ static void trigger_expiration(struct invoice *i)
|
|||||||
* (used by the timer system) and time_now (used
|
* (used by the timer system) and time_now (used
|
||||||
* by the expiry time measurements). So check that
|
* by the expiry time measurements). So check that
|
||||||
* time_now is reached. */
|
* time_now is reached. */
|
||||||
if (i->expiry_time <= now) {
|
if (i->details->expiry_time <= now) {
|
||||||
const tal_t *tmpctx = tal_tmpctx(i);
|
const tal_t *tmpctx = tal_tmpctx(i);
|
||||||
|
|
||||||
/* Update in-memory and db. */
|
/* Update in-memory and db. */
|
||||||
i->state = EXPIRED;
|
i->details->state = EXPIRED;
|
||||||
stmt = db_prepare(invoices->db,
|
stmt = db_prepare(invoices->db,
|
||||||
"UPDATE invoices"
|
"UPDATE invoices"
|
||||||
" SET state = ?"
|
" SET state = ?"
|
||||||
@ -143,11 +145,11 @@ static void install_expiration_timer(struct invoices *invoices,
|
|||||||
struct timeabs expiry;
|
struct timeabs expiry;
|
||||||
struct timeabs now = time_now();
|
struct timeabs now = time_now();
|
||||||
|
|
||||||
assert(i->state == UNPAID);
|
assert(i->details->state == UNPAID);
|
||||||
assert(!i->expiration_timer);
|
assert(!i->expiration_timer);
|
||||||
|
|
||||||
memset(&expiry, 0, sizeof(expiry));
|
memset(&expiry, 0, sizeof(expiry));
|
||||||
expiry.ts.tv_sec = i->expiry_time;
|
expiry.ts.tv_sec = i->details->expiry_time;
|
||||||
|
|
||||||
/* now > expiry */
|
/* now > expiry */
|
||||||
if (time_after(now, expiry))
|
if (time_after(now, expiry))
|
||||||
@ -197,12 +199,13 @@ bool invoices_load(struct invoices *invoices)
|
|||||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
i = tal(invoices, struct invoice);
|
i = tal(invoices, struct invoice);
|
||||||
i->owner = invoices;
|
i->owner = invoices;
|
||||||
if (!wallet_stmt2invoice(stmt, i)) {
|
i->details = tal(i, struct invoice_details);
|
||||||
|
if (!wallet_stmt2invoice_details(stmt, i, i->details)) {
|
||||||
log_broken(invoices->log, "Error deserializing invoice");
|
log_broken(invoices->log, "Error deserializing invoice");
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (i->state == UNPAID)
|
if (i->details->state == UNPAID)
|
||||||
install_expiration_timer(invoices, i);
|
install_expiration_timer(invoices, i);
|
||||||
list_add_tail(&invoices->invlist, &i->list);
|
list_add_tail(&invoices->invlist, &i->list);
|
||||||
count++;
|
count++;
|
||||||
@ -272,12 +275,13 @@ const struct invoice *invoices_create(struct invoices *invoices,
|
|||||||
invoice->owner = invoices;
|
invoice->owner = invoices;
|
||||||
|
|
||||||
invoice->id = sqlite3_last_insert_rowid(invoices->db->sql);
|
invoice->id = sqlite3_last_insert_rowid(invoices->db->sql);
|
||||||
invoice->state = UNPAID;
|
invoice->details = tal(invoice, struct invoice_details);
|
||||||
invoice->label = tal_strdup(invoice, label);
|
invoice->details->state = UNPAID;
|
||||||
invoice->msatoshi = tal_dup(invoice, u64, msatoshi); /* Works even if msatoshi == NULL. */
|
invoice->details->label = tal_strdup(invoice->details, label);
|
||||||
memcpy(&invoice->r, &r, sizeof(invoice->r));
|
invoice->details->msatoshi = tal_dup(invoice->details, u64, msatoshi); /* Works even if msatoshi == NULL. */
|
||||||
memcpy(&invoice->rhash, &rhash, sizeof(invoice->rhash));
|
memcpy(&invoice->details->r, &r, sizeof(invoice->details->r));
|
||||||
invoice->expiry_time = expiry_time;
|
memcpy(&invoice->details->rhash, &rhash, sizeof(invoice->details->rhash));
|
||||||
|
invoice->details->expiry_time = expiry_time;
|
||||||
list_head_init(&invoice->waitone_waiters);
|
list_head_init(&invoice->waitone_waiters);
|
||||||
invoice->expiration_timer = NULL;
|
invoice->expiration_timer = NULL;
|
||||||
|
|
||||||
@ -298,7 +302,7 @@ const struct invoice *invoices_find_by_label(struct invoices *invoices,
|
|||||||
|
|
||||||
/* FIXME: Use something better than a linear scan. */
|
/* FIXME: Use something better than a linear scan. */
|
||||||
list_for_each(&invoices->invlist, i, list) {
|
list_for_each(&invoices->invlist, i, list) {
|
||||||
if (streq(i->label, label))
|
if (streq(i->details->label, label))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -310,8 +314,9 @@ const struct invoice *invoices_find_unpaid(struct invoices *invoices,
|
|||||||
struct invoice *i;
|
struct invoice *i;
|
||||||
|
|
||||||
list_for_each(&invoices->invlist, i, list) {
|
list_for_each(&invoices->invlist, i, list) {
|
||||||
if (structeq(rhash, &i->rhash) && i->state == UNPAID) {
|
if (structeq(rhash, &i->details->rhash) &&
|
||||||
if (time_now().ts.tv_sec > i->expiry_time)
|
i->details->state == UNPAID) {
|
||||||
|
if (time_now().ts.tv_sec > i->details->expiry_time)
|
||||||
break;
|
break;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -407,10 +412,10 @@ void invoices_resolve(struct invoices *invoices,
|
|||||||
db_exec_prepared(invoices->db, stmt);
|
db_exec_prepared(invoices->db, stmt);
|
||||||
|
|
||||||
/* Update in-memory structure. */
|
/* Update in-memory structure. */
|
||||||
invoice->state = PAID;
|
invoice->details->state = PAID;
|
||||||
invoice->pay_index = pay_index;
|
invoice->details->pay_index = pay_index;
|
||||||
invoice->msatoshi_received = msatoshi_received;
|
invoice->details->msatoshi_received = msatoshi_received;
|
||||||
invoice->paid_timestamp = paid_timestamp;
|
invoice->details->paid_timestamp = paid_timestamp;
|
||||||
invoice->expiration_timer = tal_free(invoice->expiration_timer);
|
invoice->expiration_timer = tal_free(invoice->expiration_timer);
|
||||||
|
|
||||||
/* Tell all the waitany waiters about the new paid invoice. */
|
/* Tell all the waitany waiters about the new paid invoice. */
|
||||||
@ -506,7 +511,7 @@ void invoices_waitone(const tal_t *ctx,
|
|||||||
void *cbarg)
|
void *cbarg)
|
||||||
{
|
{
|
||||||
struct invoice *invoice = (struct invoice*) cinvoice;
|
struct invoice *invoice = (struct invoice*) cinvoice;
|
||||||
if (invoice->state == PAID || invoice->state == EXPIRED) {
|
if (invoice->details->state == PAID || invoice->details->state == EXPIRED) {
|
||||||
cb(invoice, cbarg);
|
cb(invoice, cbarg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -514,3 +519,24 @@ void invoices_waitone(const tal_t *ctx,
|
|||||||
/* Not yet paid. */
|
/* Not yet paid. */
|
||||||
add_invoice_waiter(ctx, &invoice->waitone_waiters, cb, cbarg);
|
add_invoice_waiter(ctx, &invoice->waitone_waiters, cb, cbarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invoices_get_details(const tal_t *ctx,
|
||||||
|
struct invoices *invoices,
|
||||||
|
const struct invoice *invoice,
|
||||||
|
struct invoice_details *dtl)
|
||||||
|
{
|
||||||
|
dtl->state = invoice->details->state;
|
||||||
|
dtl->r = invoice->details->r;
|
||||||
|
dtl->rhash = invoice->details->rhash;
|
||||||
|
dtl->label = tal_strdup(ctx, invoice->details->label);
|
||||||
|
dtl->msatoshi =
|
||||||
|
invoice->details->msatoshi ?
|
||||||
|
tal_dup(ctx, u64, invoice->details->msatoshi) :
|
||||||
|
/*otherwise*/ NULL ;
|
||||||
|
dtl->expiry_time = invoice->details->expiry_time;
|
||||||
|
if (dtl->state == PAID) {
|
||||||
|
dtl->pay_index = invoice->details->pay_index;
|
||||||
|
dtl->msatoshi_received = invoice->details->msatoshi_received;
|
||||||
|
dtl->paid_timestamp = invoice->details->paid_timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
struct db;
|
struct db;
|
||||||
struct invoice;
|
struct invoice;
|
||||||
|
struct invoice_details;
|
||||||
struct invoices;
|
struct invoices;
|
||||||
struct log;
|
struct log;
|
||||||
struct sha256;
|
struct sha256;
|
||||||
@ -159,4 +160,17 @@ void invoices_waitone(const tal_t *ctx,
|
|||||||
void (*cb)(const struct invoice *, void*),
|
void (*cb)(const struct invoice *, void*),
|
||||||
void *cbarg);
|
void *cbarg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* invoices_get_details - Get the invoice_details of an invoice.
|
||||||
|
*
|
||||||
|
* @ctx - the owner of the label and msatoshi fields returned.
|
||||||
|
* @invoices - the invoice handler,
|
||||||
|
* @invoice - the invoice to get details on.
|
||||||
|
* @details - pointer to details object to load.
|
||||||
|
*/
|
||||||
|
void invoices_get_details(const tal_t *ctx,
|
||||||
|
struct invoices *invoices,
|
||||||
|
const struct invoice *invoice,
|
||||||
|
struct invoice_details *details);
|
||||||
|
|
||||||
#endif /* LIGHTNING_WALLET_INVOICES_H */
|
#endif /* LIGHTNING_WALLET_INVOICES_H */
|
||||||
|
@ -112,6 +112,12 @@ const struct invoice *invoices_find_by_label(struct invoices *invoices UNNEEDED,
|
|||||||
const struct invoice *invoices_find_unpaid(struct invoices *invoices UNNEEDED,
|
const struct invoice *invoices_find_unpaid(struct invoices *invoices UNNEEDED,
|
||||||
const struct sha256 *rhash UNNEEDED)
|
const struct sha256 *rhash UNNEEDED)
|
||||||
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
|
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
|
||||||
|
/* Generated stub for invoices_get_details */
|
||||||
|
void invoices_get_details(const tal_t *ctx UNNEEDED,
|
||||||
|
struct invoices *invoices UNNEEDED,
|
||||||
|
const struct invoice *invoice UNNEEDED,
|
||||||
|
struct invoice_details *details UNNEEDED)
|
||||||
|
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
|
||||||
/* Generated stub for invoices_iterate */
|
/* Generated stub for invoices_iterate */
|
||||||
const struct invoice *invoices_iterate(struct invoices *invoices UNNEEDED,
|
const struct invoice *invoices_iterate(struct invoices *invoices UNNEEDED,
|
||||||
const struct invoice *invoice UNNEEDED)
|
const struct invoice *invoice UNNEEDED)
|
||||||
|
@ -1314,7 +1314,13 @@ void wallet_invoice_waitone(const tal_t *ctx,
|
|||||||
{
|
{
|
||||||
invoices_waitone(ctx, wallet->invoices, invoice, cb, cbarg);
|
invoices_waitone(ctx, wallet->invoices, invoice, cb, cbarg);
|
||||||
}
|
}
|
||||||
|
void wallet_invoice_details(const tal_t *ctx,
|
||||||
|
struct wallet *wallet,
|
||||||
|
const struct invoice *invoice,
|
||||||
|
struct invoice_details *details)
|
||||||
|
{
|
||||||
|
invoices_get_details(ctx, wallet->invoices, invoice, details);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
@ -368,6 +368,28 @@ enum invoice_status {
|
|||||||
EXPIRED,
|
EXPIRED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 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 char *label;
|
||||||
|
/* NULL if they specified "any" */
|
||||||
|
u64 *msatoshi;
|
||||||
|
/* 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 */
|
||||||
|
u64 msatoshi_received;
|
||||||
|
/* Set if state == PAID; time paid */
|
||||||
|
u64 paid_timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
struct invoice {
|
struct invoice {
|
||||||
/* Internal, rest of lightningd should not use */
|
/* Internal, rest of lightningd should not use */
|
||||||
/* List off ld->wallet->invoices. Must be first or else
|
/* List off ld->wallet->invoices. Must be first or else
|
||||||
@ -381,21 +403,8 @@ struct invoice {
|
|||||||
struct oneshot *expiration_timer;
|
struct oneshot *expiration_timer;
|
||||||
/* The owning invoices object. */
|
/* The owning invoices object. */
|
||||||
struct invoices *owner;
|
struct invoices *owner;
|
||||||
|
/* Loaded details. */
|
||||||
/* Publicly-usable fields. */
|
struct invoice_details *details;
|
||||||
enum invoice_status state;
|
|
||||||
const char *label;
|
|
||||||
/* NULL if they specified "any" */
|
|
||||||
u64 *msatoshi;
|
|
||||||
/* Set if state == PAID */
|
|
||||||
u64 msatoshi_received;
|
|
||||||
/* Set if state == PAID */
|
|
||||||
u64 paid_timestamp;
|
|
||||||
struct preimage r;
|
|
||||||
u64 expiry_time;
|
|
||||||
struct sha256 rhash;
|
|
||||||
/* Set if state == PAID */
|
|
||||||
u64 pay_index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INVOICE_MAX_LABEL_LEN 128
|
#define INVOICE_MAX_LABEL_LEN 128
|
||||||
@ -540,6 +549,18 @@ void wallet_invoice_waitone(const tal_t *ctx,
|
|||||||
void (*cb)(const struct invoice *, void*),
|
void (*cb)(const struct invoice *, void*),
|
||||||
void *cbarg);
|
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.
|
||||||
|
* @details - pointer to details object to load.
|
||||||
|
*/
|
||||||
|
void wallet_invoice_details(const tal_t *ctx,
|
||||||
|
struct wallet *wallet,
|
||||||
|
const struct invoice *invoice,
|
||||||
|
struct invoice_details *details);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wallet_htlc_stubs - Retrieve HTLC stubs for the given channel
|
* wallet_htlc_stubs - Retrieve HTLC stubs for the given channel
|
||||||
|
Loading…
Reference in New Issue
Block a user