diff --git a/tests/test_invoices.py b/tests/test_invoices.py index fd2481fa4..f8f2425ad 100644 --- a/tests/test_invoices.py +++ b/tests/test_invoices.py @@ -732,16 +732,46 @@ def test_wait_invoices(node_factory, executor): assert waitres == {'subsystem': 'invoices', 'created': 1} - # Deleting correctly produces 2, not another 1! - l2.rpc.delinvoice('invlabel', 'unpaid') + # Now for updates + waitres = l2.rpc.call('wait', {'subsystem': 'invoices', 'indexname': 'updated', 'nextvalue': 0}) + assert waitres == {'subsystem': 'invoices', + 'updated': 0} - waitfut = executor.submit(l2.rpc.call, 'wait', {'subsystem': 'invoices', 'indexname': 'created', 'nextvalue': 2}) + waitfut = executor.submit(l2.rpc.call, 'wait', {'subsystem': 'invoices', 'indexname': 'updated', 'nextvalue': 1}) time.sleep(1) - inv = l2.rpc.invoice(42, 'invlabel', 'invdesc2') + l1.rpc.pay(inv['bolt11']) waitres = waitfut.result(TIMEOUT) assert waitres == {'subsystem': 'invoices', - 'created': 2, - 'details': {'label': 'invlabel', + 'updated': 1, + # FIXME: fill in details! + # {'label': 'invlabel', 'bolt11': inv['bolt11'], 'status': 'paid'} + 'details': {'status': 'paid'}} + + # Second returns instantly, without any details. + waitres = l2.rpc.call('wait', {'subsystem': 'invoices', 'indexname': 'updated', 'nextvalue': 1}) + assert waitres == {'subsystem': 'invoices', + 'updated': 1} + + # Now check expiry works. + l2.rpc.invoice(42, 'invlabel2', 'invdesc2', expiry=2) + waitres = l2.rpc.call('wait', {'subsystem': 'invoices', 'indexname': 'updated', 'nextvalue': 2}) + + assert waitres == {'subsystem': 'invoices', + 'updated': 2, + # FIXME: fill in details! + # {'label': 'invlabel2', 'bolt11': inv2['bolt11'], 'status': 'expired'} + 'details': {'status': 'expired'}} + + # Deleting correctly produces 3, not another 2! + l2.rpc.delinvoice('invlabel2', 'expired') + + waitfut = executor.submit(l2.rpc.call, 'wait', {'subsystem': 'invoices', 'indexname': 'created', 'nextvalue': 3}) + time.sleep(1) + inv = l2.rpc.invoice(42, 'invlabel2', 'invdesc2') + waitres = waitfut.result(TIMEOUT) + assert waitres == {'subsystem': 'invoices', + 'created': 3, + 'details': {'label': 'invlabel2', 'bolt11': inv['bolt11'], 'status': 'unpaid'}} diff --git a/wallet/invoices.c b/wallet/invoices.c index c7514e549..8ab9caa3e 100644 --- a/wallet/invoices.c +++ b/wallet/invoices.c @@ -115,20 +115,7 @@ static struct invoice_details *wallet_stmt2invoice_details(const tal_t *ctx, return dtl; } -/* Update expirations. */ -static void update_db_expirations(struct invoices *invoices, u64 now) -{ - struct db_stmt *stmt; - stmt = db_prepare_v2(invoices->wallet->db, SQL("UPDATE invoices" - " SET state = ?" - " WHERE state = ?" - " AND expiry_time <= ?;")); - db_bind_int(stmt, EXPIRED); - db_bind_int(stmt, UNPAID); - db_bind_u64(stmt, now); - db_exec_prepared_v2(take(stmt)); -} - +static void trigger_expiration(struct invoices *invoices); static void install_expiration_timer(struct invoices *invoices); struct invoices *invoices_new(const tal_t *ctx, @@ -144,8 +131,7 @@ struct invoices *invoices_new(const tal_t *ctx, invs->expiration_timer = NULL; - update_db_expirations(invs, time_now().ts.tv_sec); - install_expiration_timer(invs); + trigger_expiration(invs); return invs; } @@ -181,11 +167,20 @@ static void trigger_expiration(struct invoices *invoices) } tal_free(stmt); - /* Expire all those invoices */ - update_db_expirations(invoices, now); - /* Trigger expirations */ list_for_each(&idlist, idn, list) { + stmt = db_prepare_v2(invoices->wallet->db, SQL("UPDATE invoices" + " SET state = ?" + " , updated_index = ?" + " WHERE id = ?")); + db_bind_int(stmt, EXPIRED); + db_bind_u64(stmt, + /* FIXME: details! */ + invoice_index_update_status(invoices->wallet->ld, + NULL, EXPIRED)); + db_bind_u64(stmt, idn->inv_dbid); + db_exec_prepared_v2(take(stmt)); + /* Trigger expiration */ trigger_invoice_waiter_expire_or_delete(invoices, idn->inv_dbid, false); } @@ -540,11 +535,16 @@ bool invoices_resolve(struct invoices *invoices, " , pay_index=?" " , msatoshi_received=?" " , paid_timestamp=?" + " , updated_index=?" " WHERE id=?;")); db_bind_int(stmt, PAID); db_bind_u64(stmt, pay_index); db_bind_amount_msat(stmt, &received); db_bind_u64(stmt, paid_timestamp); + /* FIXME: populate label */ + db_bind_u64(stmt, + invoice_index_update_status(invoices->wallet->ld, + NULL, PAID)); db_bind_u64(stmt, inv_dbid); db_exec_prepared_v2(take(stmt));