invoices: Add `paid_timestamp` field.

Fixes: #615
This commit is contained in:
ZmnSCPxj 2018-01-16 12:59:22 +00:00 committed by Christian Decker
parent 5a87fb1c3b
commit a88c73a41b
5 changed files with 34 additions and 7 deletions

View File

@ -31,6 +31,8 @@ static void json_add_invoice(struct json_result *response,
json_add_u64(response, "pay_index", inv->pay_index);
json_add_u64(response, "msatoshi_received",
inv->msatoshi_received);
json_add_u64(response, "paid_timestamp",
inv->paid_timestamp);
}
json_add_u64(response, "expiry_time", inv->expiry_time);
json_object_end(response);

View File

@ -743,8 +743,13 @@ class LightningDTests(BaseLightningDTests):
self.wait_for_routes(l1, [chanid])
inv = l2.rpc.invoice(123000, 'test_pay', 'description')['bolt11']
before = int(time.time())
l1.rpc.pay(inv)
assert l2.rpc.listinvoice('test_pay')[0]['complete'] == True
after = int(time.time())
invoice = l2.rpc.listinvoice('test_pay')[0]
assert invoice['complete'] == True
assert invoice['paid_timestamp'] >= before
assert invoice['paid_timestamp'] <= after
# Repeat payments are NOPs (if valid): we can hand null.
l1.rpc.pay(inv, None)

View File

@ -177,6 +177,12 @@ char *dbmigrations[] = {
"ALTER TABLE payments ADD COLUMN payment_preimage BLOB;",
/* We need to keep the shared secrets to decode error returns. */
"ALTER TABLE payments ADD COLUMN path_secrets BLOB;",
/* Create time-of-payment of invoice, default already-paid
* invoices to current time. */
"ALTER TABLE invoices ADD paid_timestamp INTEGER;",
"UPDATE invoices"
" SET paid_timestamp = strftime('%s', 'now')"
" WHERE state = 1;",
NULL,
};

View File

@ -61,8 +61,10 @@ static bool wallet_stmt2invoice(sqlite3_stmt *stmt, struct invoice *inv)
/* Correctly 0 if pay_index is NULL. */
inv->pay_index = sqlite3_column_int64(stmt, 7);
if (inv->state == PAID)
if (inv->state == PAID) {
inv->msatoshi_received = sqlite3_column_int64(stmt, 8);
inv->paid_timestamp = sqlite3_column_int64(stmt, 9);
}
list_head_init(&inv->waitone_waiters);
return true;
@ -94,7 +96,7 @@ bool invoices_load(struct invoices *invoices)
stmt = db_query(__func__, invoices->db,
"SELECT id, state, payment_key, payment_hash"
" , label, msatoshi, expiry_time, pay_index"
" , msatoshi_received"
" , msatoshi_received, paid_timestamp"
" FROM invoices;");
if (!stmt) {
log_broken(invoices->log, "Could not load invoices");
@ -148,8 +150,14 @@ const struct invoice *invoices_create(struct invoices *invoices,
* that string for sql injections... */
stmt = db_prepare(invoices->db,
"INSERT INTO invoices"
" (payment_hash, payment_key, state, msatoshi, label, expiry_time, pay_index, msatoshi_received)"
" VALUES (?, ?, ?, ?, ?, ?, NULL, NULL);");
" ( payment_hash, payment_key, state"
" , msatoshi, label, expiry_time"
" , pay_index, msatoshi_received"
" , paid_timestamp)"
" VALUES ( ?, ?, ?"
" , ?, ?, ?"
" , NULL, NULL"
" , NULL);");
sqlite3_bind_blob(stmt, 1, &rhash, sizeof(rhash), SQLITE_TRANSIENT);
sqlite3_bind_blob(stmt, 2, &r, sizeof(r), SQLITE_TRANSIENT);
@ -274,11 +282,12 @@ void invoices_resolve(struct invoices *invoices,
struct invoice_waiter *w;
struct invoice *invoice = (struct invoice *)cinvoice;
s64 pay_index;
u64 paid_timestamp;
const tal_t *tmpctx = tal_tmpctx(NULL);
/* Assign a pay-index. */
pay_index = get_next_pay_index(invoices->db);
/* FIXME: Save time of payment. */
paid_timestamp = time_now().ts.tv_sec;
/* Update database. */
stmt = db_prepare(invoices->db,
@ -286,17 +295,20 @@ void invoices_resolve(struct invoices *invoices,
" SET state=?"
" , pay_index=?"
" , msatoshi_received=?"
" , paid_timestamp=?"
" WHERE id=?;");
sqlite3_bind_int(stmt, 1, PAID);
sqlite3_bind_int64(stmt, 2, pay_index);
sqlite3_bind_int64(stmt, 3, msatoshi_received);
sqlite3_bind_int64(stmt, 4, invoice->id);
sqlite3_bind_int64(stmt, 4, paid_timestamp);
sqlite3_bind_int64(stmt, 5, invoice->id);
db_exec_prepared(invoices->db, stmt);
/* Update in-memory structure. */
invoice->state = PAID;
invoice->pay_index = pay_index;
invoice->msatoshi_received = msatoshi_received;
invoice->paid_timestamp = paid_timestamp;
/* Tell all the waitany waiters about the new paid invoice. */
while ((w = list_pop(&invoices->waitany_waiters,

View File

@ -365,6 +365,8 @@ struct invoice {
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;