parent
5a87fb1c3b
commit
a88c73a41b
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue