Browse Source

invoices: Unify waitone/any waiters to invoices object.

In preparation for removing in-memory invoice objects.
Since they will be removed, there will no longer be any
individual invoice objects to attach to.
ppa-0.6.1
ZmnSCPxj 7 years ago
committed by Christian Decker
parent
commit
7a6fe0704e
  1. 108
      wallet/invoices.c
  2. 2
      wallet/wallet.h

108
wallet/invoices.c

@ -16,8 +16,16 @@
#include <common/utils.h> #include <common/utils.h>
struct invoice_waiter { struct invoice_waiter {
/* Is this waiter already triggered? */
bool triggered; bool triggered;
/* Is this waiting for any invoice to resolve? */
bool any;
/* If !any, the specific invoice this is waiting on */
u64 id;
struct list_node list; struct list_node list;
/* The callback to use */
void (*cb)(const struct invoice *, void*); void (*cb)(const struct invoice *, void*);
void *cbarg; void *cbarg;
}; };
@ -31,17 +39,55 @@ struct invoices {
struct timers *timers; struct timers *timers;
/* The invoice list. */ /* The invoice list. */
struct list_head invlist; struct list_head invlist;
/* Waiters waiting for any new invoice to be paid. */ /* Waiters waiting for invoices to be paid, expired, or deleted. */
struct list_head waitany_waiters; struct list_head waiters;
}; };
static void trigger_invoice_waiter(struct invoice_waiter *w, static void trigger_invoice_waiter(struct invoice_waiter *w,
struct invoice *invoice) const struct invoice *invoice)
{ {
w->triggered = true; w->triggered = true;
w->cb(invoice, w->cbarg); w->cb(invoice, w->cbarg);
} }
static void trigger_invoice_waiter_resolve(struct invoices *invoices,
u64 id,
const struct invoice *invoice)
{
const tal_t *tmpctx = tal_tmpctx(invoices);
struct invoice_waiter *w;
struct invoice_waiter *n;
list_for_each_safe(&invoices->waiters, w, n, list) {
if (!w->any && w->id != id)
continue;
list_del_from(&invoices->waiters, &w->list);
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice);
}
tal_free(tmpctx);
}
static void
trigger_invoice_waiter_expire_or_delete(struct invoices *invoices,
u64 id,
const struct invoice *invoice)
{
const tal_t *tmpctx = tal_tmpctx(invoices);
struct invoice_waiter *w;
struct invoice_waiter *n;
list_for_each_safe(&invoices->waiters, w, n, list) {
if (w->any || w->id != id)
continue;
list_del_from(&invoices->waiters, &w->list);
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice);
}
tal_free(tmpctx);
}
static bool wallet_stmt2invoice_details(sqlite3_stmt *stmt, static bool wallet_stmt2invoice_details(sqlite3_stmt *stmt,
struct invoice *invoice, struct invoice *invoice,
struct invoice_details *dtl) struct invoice_details *dtl)
@ -72,7 +118,6 @@ static bool wallet_stmt2invoice_details(sqlite3_stmt *stmt,
dtl->paid_timestamp = sqlite3_column_int64(stmt, 9); dtl->paid_timestamp = sqlite3_column_int64(stmt, 9);
} }
list_head_init(&invoice->waitone_waiters);
invoice->expiration_timer = NULL; invoice->expiration_timer = NULL;
return true; return true;
@ -90,7 +135,7 @@ struct invoices *invoices_new(const tal_t *ctx,
invs->timers = timers; invs->timers = timers;
list_head_init(&invs->invlist); list_head_init(&invs->invlist);
list_head_init(&invs->waitany_waiters); list_head_init(&invs->waiters);
return invs; return invs;
} }
@ -102,7 +147,6 @@ static void trigger_expiration(struct invoice *i)
struct invoices *invoices = i->owner; struct invoices *invoices = i->owner;
u64 now = time_now().ts.tv_sec; u64 now = time_now().ts.tv_sec;
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
struct invoice_waiter *w;
assert(i->details->state == UNPAID); assert(i->details->state == UNPAID);
@ -126,12 +170,7 @@ static void trigger_expiration(struct invoice *i)
sqlite3_bind_int64(stmt, 2, i->id); sqlite3_bind_int64(stmt, 2, i->id);
db_exec_prepared(invoices->db, stmt); db_exec_prepared(invoices->db, stmt);
/* Wake up all waiters. */ /* Wake up all waiters. */
while ((w = list_pop(&i->waitone_waiters, trigger_invoice_waiter_expire_or_delete(invoices, i->id, i);
struct invoice_waiter,
list)) != NULL) {
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, i);
}
tal_free(tmpctx); tal_free(tmpctx);
} else } else
@ -282,7 +321,6 @@ const struct invoice *invoices_create(struct invoices *invoices,
memcpy(&invoice->details->r, &r, sizeof(invoice->details->r)); memcpy(&invoice->details->r, &r, sizeof(invoice->details->r));
memcpy(&invoice->details->rhash, &rhash, sizeof(invoice->details->rhash)); memcpy(&invoice->details->rhash, &rhash, sizeof(invoice->details->rhash));
invoice->details->expiry_time = expiry_time; invoice->details->expiry_time = expiry_time;
list_head_init(&invoice->waitone_waiters);
invoice->expiration_timer = NULL; invoice->expiration_timer = NULL;
/* Add to invoices object. */ /* Add to invoices object. */
@ -328,34 +366,24 @@ bool invoices_delete(struct invoices *invoices,
const struct invoice *cinvoice) const struct invoice *cinvoice)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
struct invoice_waiter *w;
struct invoice *invoice = (struct invoice *) cinvoice; struct invoice *invoice = (struct invoice *) cinvoice;
const tal_t *tmpctx = tal_tmpctx(NULL);
/* Delete from database. */ /* Delete from database. */
stmt = db_prepare(invoices->db, "DELETE FROM invoices WHERE id=?;"); stmt = db_prepare(invoices->db, "DELETE FROM invoices WHERE id=?;");
sqlite3_bind_int64(stmt, 1, invoice->id); sqlite3_bind_int64(stmt, 1, invoice->id);
db_exec_prepared(invoices->db, stmt); db_exec_prepared(invoices->db, stmt);
if (sqlite3_changes(invoices->db->sql) != 1) { if (sqlite3_changes(invoices->db->sql) != 1)
tal_free(tmpctx);
return false; return false;
}
/* Delete from invoices object. */ /* Delete from invoices object. */
list_del_from(&invoices->invlist, &invoice->list); list_del_from(&invoices->invlist, &invoice->list);
/* Tell all the waiters about the fact that it was deleted. */ /* Tell all the waiters about the fact that it was deleted. */
while ((w = list_pop(&invoice->waitone_waiters, trigger_invoice_waiter_expire_or_delete(invoices,
struct invoice_waiter, invoice->id, NULL);
list)) != NULL) {
/* Acquire the watcher for ourself first. */
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, NULL);
}
/* Free all watchers and the invoice. */ /* Free all watchers and the invoice. */
tal_free(tmpctx);
tal_free(invoice); tal_free(invoice);
return true; return true;
} }
@ -386,7 +414,6 @@ void invoices_resolve(struct invoices *invoices,
u64 msatoshi_received) u64 msatoshi_received)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
struct invoice_waiter *w;
struct invoice *invoice = (struct invoice *)cinvoice; struct invoice *invoice = (struct invoice *)cinvoice;
s64 pay_index; s64 pay_index;
u64 paid_timestamp; u64 paid_timestamp;
@ -418,21 +445,8 @@ void invoices_resolve(struct invoices *invoices,
invoice->details->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 waiters about the paid invoice. */
while ((w = list_pop(&invoices->waitany_waiters, trigger_invoice_waiter_resolve(invoices, invoice->id, invoice);
struct invoice_waiter,
list)) != NULL) {
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice);
}
/* Tell any waitinvoice waiters about the specific invoice
* getting paid. */
while ((w = list_pop(&invoice->waitone_waiters,
struct invoice_waiter,
list)) != NULL) {
tal_steal(tmpctx, w);
trigger_invoice_waiter(w, invoice);
}
/* Free all watchers. */ /* Free all watchers. */
tal_free(tmpctx); tal_free(tmpctx);
@ -450,11 +464,15 @@ static void destroy_invoice_waiter(struct invoice_waiter *w)
/* Add an invoice waiter to the specified list of invoice waiters. */ /* Add an invoice waiter to the specified list of invoice waiters. */
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,
u64 id,
void (*cb)(const struct invoice *, void*), void (*cb)(const struct invoice *, 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->id = id;
list_add_tail(waiters, &w->list); list_add_tail(waiters, &w->list);
w->cb = cb; w->cb = cb;
w->cbarg = cbarg; w->cbarg = cbarg;
@ -500,7 +518,8 @@ void invoices_waitany(const tal_t *ctx,
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
/* None found. */ /* None found. */
add_invoice_waiter(ctx, &invoices->waitany_waiters, cb, cbarg); add_invoice_waiter(ctx, &invoices->waiters,
true, 0, cb, cbarg);
} }
@ -517,7 +536,8 @@ 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, &invoices->waiters,
false, invoice->id, cb, cbarg);
} }
void invoices_get_details(const tal_t *ctx, void invoices_get_details(const tal_t *ctx,

2
wallet/wallet.h

@ -397,8 +397,6 @@ struct invoice {
struct list_node list; struct list_node list;
/* Database ID */ /* Database ID */
u64 id; u64 id;
/* Any JSON waitinvoice calls waiting for this to be paid */
struct list_head waitone_waiters;
/* Any expiration timer in effect */ /* Any expiration timer in effect */
struct oneshot *expiration_timer; struct oneshot *expiration_timer;
/* The owning invoices object. */ /* The owning invoices object. */

Loading…
Cancel
Save