mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-13 02:54:24 +01:00
db: Migrate invoices.c to new abstraction layer
Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
committed by
Rusty Russell
parent
460299850f
commit
f19dc2ecc1
@@ -12,7 +12,6 @@
|
||||
#include <lightningd/invoice.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <sodium/randombytes.h>
|
||||
#include <sqlite3.h>
|
||||
#include <string.h>
|
||||
|
||||
struct invoice_waiter {
|
||||
@@ -85,38 +84,38 @@ trigger_invoice_waiter_expire_or_delete(struct invoices *invoices,
|
||||
}
|
||||
|
||||
static struct invoice_details *wallet_stmt2invoice_details(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt)
|
||||
struct db_stmt *stmt)
|
||||
{
|
||||
struct invoice_details *dtl = tal(ctx, struct invoice_details);
|
||||
dtl->state = sqlite3_column_int(stmt, 0);
|
||||
dtl->state = db_column_int(stmt, 0);
|
||||
|
||||
sqlite3_column_preimage(stmt, 1, &dtl->r);
|
||||
db_column_preimage(stmt, 1, &dtl->r);
|
||||
|
||||
sqlite3_column_sha256(stmt, 2, &dtl->rhash);
|
||||
db_column_sha256(stmt, 2, &dtl->rhash);
|
||||
|
||||
dtl->label = sqlite3_column_json_escape(dtl, stmt, 3);
|
||||
dtl->label = db_column_json_escape(dtl, stmt, 3);
|
||||
|
||||
if (sqlite3_column_type(stmt, 4) != SQLITE_NULL) {
|
||||
if (!db_column_is_null(stmt, 4)) {
|
||||
dtl->msat = tal(dtl, struct amount_msat);
|
||||
*dtl->msat = sqlite3_column_amount_msat(stmt, 4);
|
||||
db_column_amount_msat(stmt, 4, dtl->msat);
|
||||
} else {
|
||||
dtl->msat = NULL;
|
||||
}
|
||||
|
||||
dtl->expiry_time = sqlite3_column_int64(stmt, 5);
|
||||
dtl->expiry_time = db_column_u64(stmt, 5);
|
||||
|
||||
if (dtl->state == PAID) {
|
||||
dtl->pay_index = sqlite3_column_int64(stmt, 6);
|
||||
dtl->received = sqlite3_column_amount_msat(stmt, 7);
|
||||
dtl->paid_timestamp = sqlite3_column_int64(stmt, 8);
|
||||
dtl->pay_index = db_column_u64(stmt, 6);
|
||||
db_column_amount_msat(stmt, 7, &dtl->received);
|
||||
dtl->paid_timestamp = db_column_u64(stmt, 8);
|
||||
}
|
||||
|
||||
dtl->bolt11 = tal_strndup(dtl, sqlite3_column_blob(stmt, 9),
|
||||
sqlite3_column_bytes(stmt, 9));
|
||||
dtl->bolt11 = tal_strndup(dtl, db_column_blob(stmt, 9),
|
||||
db_column_bytes(stmt, 9));
|
||||
|
||||
if (sqlite3_column_type(stmt, 10) != SQLITE_NULL)
|
||||
if (!db_column_is_null(stmt, 10))
|
||||
dtl->description = tal_strdup(
|
||||
dtl, (const char *)sqlite3_column_text(stmt, 10));
|
||||
dtl, (const char *)db_column_text(stmt, 10));
|
||||
else
|
||||
dtl->description = NULL;
|
||||
|
||||
@@ -126,16 +125,15 @@ static struct invoice_details *wallet_stmt2invoice_details(const tal_t *ctx,
|
||||
/* Update expirations. */
|
||||
static void update_db_expirations(struct invoices *invoices, u64 now)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
stmt = db_prepare(invoices->db,
|
||||
"UPDATE invoices"
|
||||
" SET state = ?"
|
||||
" WHERE state = ?"
|
||||
" AND expiry_time <= ?;");
|
||||
sqlite3_bind_int(stmt, 1, EXPIRED);
|
||||
sqlite3_bind_int(stmt, 2, UNPAID);
|
||||
sqlite3_bind_int64(stmt, 3, now);
|
||||
db_exec_prepared(invoices->db, stmt);
|
||||
struct db_stmt *stmt;
|
||||
stmt = db_prepare_v2(invoices->db, SQL("UPDATE invoices"
|
||||
" SET state = ?"
|
||||
" WHERE state = ?"
|
||||
" AND expiry_time <= ?;"));
|
||||
db_bind_int(stmt, 0, EXPIRED);
|
||||
db_bind_int(stmt, 1, UNPAID);
|
||||
db_bind_u64(stmt, 2, now);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
||||
static void install_expiration_timer(struct invoices *invoices);
|
||||
@@ -170,7 +168,7 @@ static void trigger_expiration(struct invoices *invoices)
|
||||
struct list_head idlist;
|
||||
struct invoice_id_node *idn;
|
||||
u64 now = time_now().ts.tv_sec;
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
struct invoice i;
|
||||
|
||||
/* Free current expiration timer */
|
||||
@@ -178,18 +176,20 @@ static void trigger_expiration(struct invoices *invoices)
|
||||
|
||||
/* Acquire all expired invoices and save them in a list */
|
||||
list_head_init(&idlist);
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE state = ?"
|
||||
" AND expiry_time <= ?;");
|
||||
sqlite3_bind_int(stmt, 1, UNPAID);
|
||||
sqlite3_bind_int64(stmt, 2, now);
|
||||
while (db_select_step(invoices->db, stmt)) {
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE state = ?"
|
||||
" AND expiry_time <= ?"));
|
||||
db_bind_int(stmt, 0, UNPAID);
|
||||
db_bind_u64(stmt, 1, now);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
while (db_step(stmt)) {
|
||||
idn = tal(tmpctx, struct invoice_id_node);
|
||||
list_add_tail(&idlist, &idn->list);
|
||||
idn->id = sqlite3_column_int64(stmt, 0);
|
||||
idn->id = db_column_u64(stmt, 0);
|
||||
}
|
||||
tal_free(stmt);
|
||||
|
||||
/* Expire all those invoices */
|
||||
update_db_expirations(invoices, now);
|
||||
@@ -198,9 +198,7 @@ static void trigger_expiration(struct invoices *invoices)
|
||||
list_for_each(&idlist, idn, list) {
|
||||
/* Trigger expiration */
|
||||
i.id = idn->id;
|
||||
trigger_invoice_waiter_expire_or_delete(invoices,
|
||||
idn->id,
|
||||
&i);
|
||||
trigger_invoice_waiter_expire_or_delete(invoices, idn->id, &i);
|
||||
}
|
||||
|
||||
install_expiration_timer(invoices);
|
||||
@@ -209,7 +207,7 @@ static void trigger_expiration(struct invoices *invoices)
|
||||
static void install_expiration_timer(struct invoices *invoices)
|
||||
{
|
||||
bool res;
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
struct timerel rel;
|
||||
struct timeabs expiry;
|
||||
struct timeabs now = time_now();
|
||||
@@ -217,20 +215,21 @@ static void install_expiration_timer(struct invoices *invoices)
|
||||
assert(!invoices->expiration_timer);
|
||||
|
||||
/* Find unpaid invoice with nearest expiry time */
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT MIN(expiry_time)"
|
||||
" FROM invoices"
|
||||
" WHERE state = ?;");
|
||||
sqlite3_bind_int(stmt, 1, UNPAID);
|
||||
res = db_select_step(invoices->db, stmt);
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT MIN(expiry_time)"
|
||||
" FROM invoices"
|
||||
" WHERE state = ?;"));
|
||||
db_bind_int(stmt, 0, UNPAID);
|
||||
|
||||
db_query_prepared(stmt);
|
||||
|
||||
res = db_step(stmt);
|
||||
assert(res);
|
||||
if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
|
||||
|
||||
if (db_column_is_null(stmt, 0))
|
||||
/* Nothing to install */
|
||||
db_stmt_done(stmt);
|
||||
return;
|
||||
} else
|
||||
invoices->min_expiry_time = sqlite3_column_int64(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
goto done;
|
||||
|
||||
invoices->min_expiry_time = db_column_u64(stmt, 0);
|
||||
|
||||
memset(&expiry, 0, sizeof(expiry));
|
||||
expiry.ts.tv_sec = invoices->min_expiry_time;
|
||||
@@ -248,6 +247,8 @@ static void install_expiration_timer(struct invoices *invoices)
|
||||
rel,
|
||||
&trigger_expiration,
|
||||
invoices);
|
||||
done:
|
||||
tal_free(stmt);
|
||||
}
|
||||
|
||||
bool invoices_create(struct invoices *invoices,
|
||||
@@ -260,7 +261,7 @@ bool invoices_create(struct invoices *invoices,
|
||||
const struct preimage *r,
|
||||
const struct sha256 *rhash)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
struct invoice dummy;
|
||||
u64 expiry_time;
|
||||
u64 now = time_now().ts.tv_sec;
|
||||
@@ -277,35 +278,34 @@ bool invoices_create(struct invoices *invoices,
|
||||
expiry_time = now + expiry;
|
||||
|
||||
/* Save to database. */
|
||||
/* Need to use the lower level API of sqlite3 to bind
|
||||
* label. Otherwise we'd need to implement sanitization of
|
||||
* 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"
|
||||
" , paid_timestamp, bolt11, description)"
|
||||
" VALUES ( ?, ?, ?"
|
||||
" , ?, ?, ?"
|
||||
" , NULL, NULL"
|
||||
" , NULL, ?, ?);");
|
||||
stmt = db_prepare_v2(
|
||||
invoices->db,
|
||||
SQL("INSERT INTO invoices"
|
||||
" ( payment_hash, payment_key, state"
|
||||
" , msatoshi, label, expiry_time"
|
||||
" , pay_index, msatoshi_received"
|
||||
" , paid_timestamp, bolt11, description)"
|
||||
" VALUES ( ?, ?, ?"
|
||||
" , ?, ?, ?"
|
||||
" , NULL, NULL"
|
||||
" , NULL, ?, ?);"));
|
||||
|
||||
sqlite3_bind_blob(stmt, 1, rhash, sizeof(struct sha256), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_blob(stmt, 2, r, sizeof(struct preimage), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, UNPAID);
|
||||
db_bind_sha256(stmt, 0, rhash);
|
||||
db_bind_preimage(stmt, 1, r);
|
||||
db_bind_int(stmt, 2, UNPAID);
|
||||
if (msat)
|
||||
sqlite3_bind_amount_msat(stmt, 4, *msat);
|
||||
db_bind_amount_msat(stmt, 3, msat);
|
||||
else
|
||||
sqlite3_bind_null(stmt, 4);
|
||||
sqlite3_bind_json_escape(stmt, 5, label);
|
||||
sqlite3_bind_int64(stmt, 6, expiry_time);
|
||||
sqlite3_bind_text(stmt, 7, b11enc, strlen(b11enc), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 8, description, strlen(description), SQLITE_TRANSIENT);
|
||||
db_bind_null(stmt, 3);
|
||||
db_bind_json_escape(stmt, 4, label);
|
||||
db_bind_u64(stmt, 5, expiry_time);
|
||||
db_bind_text(stmt, 6, b11enc);
|
||||
db_bind_text(stmt, 7, description);
|
||||
|
||||
db_exec_prepared(invoices->db, stmt);
|
||||
db_exec_prepared_v2(stmt);
|
||||
|
||||
pinvoice->id = db_last_insert_id(invoices->db);
|
||||
tal_free(stmt);
|
||||
|
||||
/* Install expiration trigger. */
|
||||
if (!invoices->expiration_timer ||
|
||||
@@ -327,18 +327,20 @@ bool invoices_find_by_label(struct invoices *invoices,
|
||||
struct invoice *pinvoice,
|
||||
const struct json_escape *label)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE label = ?;"));
|
||||
db_bind_json_escape(stmt, 0, label);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE label = ?;");
|
||||
sqlite3_bind_json_escape(stmt, 1, label);
|
||||
if (!db_select_step(invoices->db, stmt))
|
||||
if (!db_step(stmt)) {
|
||||
tal_free(stmt);
|
||||
return false;
|
||||
}
|
||||
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
pinvoice->id = db_column_u64(stmt, 0);
|
||||
tal_free(stmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -346,101 +348,112 @@ bool invoices_find_by_rhash(struct invoices *invoices,
|
||||
struct invoice *pinvoice,
|
||||
const struct sha256 *rhash)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE payment_hash = ?;");
|
||||
sqlite3_bind_blob(stmt, 1, rhash, sizeof(*rhash), SQLITE_TRANSIENT);
|
||||
if (!db_select_step(invoices->db, stmt))
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE payment_hash = ?;"));
|
||||
db_bind_sha256(stmt, 0, rhash);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
if (!db_step(stmt)) {
|
||||
tal_free(stmt);
|
||||
return false;
|
||||
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
} else {
|
||||
pinvoice->id = db_column_u64(stmt, 0);
|
||||
tal_free(stmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool invoices_find_unpaid(struct invoices *invoices,
|
||||
struct invoice *pinvoice,
|
||||
const struct sha256 *rhash)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE payment_hash = ?"
|
||||
" AND state = ?;"));
|
||||
db_bind_sha256(stmt, 0, rhash);
|
||||
db_bind_int(stmt, 1, UNPAID);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE payment_hash = ?"
|
||||
" AND state = ?;");
|
||||
sqlite3_bind_blob(stmt, 1, rhash, sizeof(*rhash), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 2, UNPAID);
|
||||
if (!db_select_step(invoices->db, stmt))
|
||||
if (!db_step(stmt)) {
|
||||
tal_free(stmt);
|
||||
return false;
|
||||
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
} else {
|
||||
pinvoice->id = db_column_u64(stmt, 0);
|
||||
tal_free(stmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool invoices_delete(struct invoices *invoices,
|
||||
struct invoice invoice)
|
||||
bool invoices_delete(struct invoices *invoices, struct invoice invoice)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
struct db_stmt *stmt;
|
||||
int changes;
|
||||
/* Delete from database. */
|
||||
stmt = db_prepare(invoices->db, "DELETE FROM invoices WHERE id=?;");
|
||||
sqlite3_bind_int64(stmt, 1, invoice.id);
|
||||
db_exec_prepared(invoices->db, stmt);
|
||||
stmt = db_prepare_v2(invoices->db,
|
||||
SQL("DELETE FROM invoices WHERE id=?;"));
|
||||
db_bind_u64(stmt, 0, invoice.id);
|
||||
db_exec_prepared_v2(stmt);
|
||||
|
||||
if (db_changes(invoices->db) != 1)
|
||||
changes = db_count_changes(stmt);
|
||||
tal_free(stmt);
|
||||
|
||||
if (changes != 1) {
|
||||
return false;
|
||||
|
||||
}
|
||||
/* Tell all the waiters about the fact that it was deleted. */
|
||||
trigger_invoice_waiter_expire_or_delete(invoices,
|
||||
invoice.id, NULL);
|
||||
trigger_invoice_waiter_expire_or_delete(invoices, invoice.id, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void invoices_delete_expired(struct invoices *invoices,
|
||||
u64 max_expiry_time)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
stmt = db_prepare(invoices->db,
|
||||
struct db_stmt *stmt;
|
||||
stmt = db_prepare_v2(invoices->db, SQL(
|
||||
"DELETE FROM invoices"
|
||||
" WHERE state = ?"
|
||||
" AND expiry_time <= ?;");
|
||||
sqlite3_bind_int(stmt, 1, EXPIRED);
|
||||
sqlite3_bind_int64(stmt, 2, max_expiry_time);
|
||||
db_exec_prepared(invoices->db, stmt);
|
||||
" AND expiry_time <= ?;"));
|
||||
db_bind_int(stmt, 0, EXPIRED);
|
||||
db_bind_u64(stmt, 1, max_expiry_time);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
||||
bool invoices_iterate(struct invoices *invoices,
|
||||
struct invoice_iterator *it)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
|
||||
if (!it->p) {
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT"
|
||||
" state"
|
||||
", payment_key"
|
||||
", payment_hash"
|
||||
", label"
|
||||
", msatoshi"
|
||||
", expiry_time"
|
||||
", pay_index"
|
||||
", msatoshi_received"
|
||||
", paid_timestamp"
|
||||
", bolt11"
|
||||
", description"
|
||||
" FROM invoices;");
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT"
|
||||
" state"
|
||||
", payment_key"
|
||||
", payment_hash"
|
||||
", label"
|
||||
", msatoshi"
|
||||
", expiry_time"
|
||||
", pay_index"
|
||||
", msatoshi_received"
|
||||
", paid_timestamp"
|
||||
", bolt11"
|
||||
", description"
|
||||
" FROM invoices;"));
|
||||
db_query_prepared(stmt);
|
||||
it->p = stmt;
|
||||
} else
|
||||
stmt = it->p;
|
||||
|
||||
if (db_select_step(invoices->db, stmt))
|
||||
|
||||
if (db_step(stmt))
|
||||
/* stmt doesn't need to be freed since we expect to be called
|
||||
* again, and stmt will be freed on the last iteration. */
|
||||
return true;
|
||||
|
||||
tal_free(stmt);
|
||||
it->p = NULL;
|
||||
return false;
|
||||
}
|
||||
@@ -450,7 +463,7 @@ invoices_iterator_deref(const tal_t *ctx, struct invoices *invoices UNUSED,
|
||||
const struct invoice_iterator *it)
|
||||
{
|
||||
assert(it->p);
|
||||
return wallet_stmt2invoice_details(ctx, (sqlite3_stmt*) it->p);
|
||||
return wallet_stmt2invoice_details(ctx, (struct db_stmt*) it->p);
|
||||
}
|
||||
|
||||
static s64 get_next_pay_index(struct db *db)
|
||||
@@ -466,17 +479,19 @@ static s64 get_next_pay_index(struct db *db)
|
||||
|
||||
static enum invoice_status invoice_get_status(struct invoices *invoices, struct invoice invoice)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
enum invoice_status state;
|
||||
bool res;
|
||||
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT state FROM invoices WHERE id = ?;");
|
||||
sqlite3_bind_int64(stmt, 1, invoice.id);
|
||||
res = db_select_step(invoices->db, stmt);
|
||||
stmt = db_prepare_v2(
|
||||
invoices->db, SQL("SELECT state FROM invoices WHERE id = ?;"));
|
||||
db_bind_u64(stmt, 0, invoice.id);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
res = db_step(stmt);
|
||||
assert(res);
|
||||
state = sqlite3_column_int(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
state = db_column_int(stmt, 0);
|
||||
tal_free(stmt);
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -484,7 +499,7 @@ void invoices_resolve(struct invoices *invoices,
|
||||
struct invoice invoice,
|
||||
struct amount_msat received)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
s64 pay_index;
|
||||
u64 paid_timestamp;
|
||||
enum invoice_status state = invoice_get_status(invoices, invoice);
|
||||
@@ -496,19 +511,18 @@ void invoices_resolve(struct invoices *invoices,
|
||||
paid_timestamp = time_now().ts.tv_sec;
|
||||
|
||||
/* Update database. */
|
||||
stmt = db_prepare(invoices->db,
|
||||
"UPDATE 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_amount_msat(stmt, 3, received);
|
||||
sqlite3_bind_int64(stmt, 4, paid_timestamp);
|
||||
sqlite3_bind_int64(stmt, 5, invoice.id);
|
||||
db_exec_prepared(invoices->db, stmt);
|
||||
stmt = db_prepare_v2(invoices->db, SQL("UPDATE invoices"
|
||||
" SET state=?"
|
||||
" , pay_index=?"
|
||||
" , msatoshi_received=?"
|
||||
" , paid_timestamp=?"
|
||||
" WHERE id=?;"));
|
||||
db_bind_int(stmt, 0, PAID);
|
||||
db_bind_u64(stmt, 1, pay_index);
|
||||
db_bind_amount_msat(stmt, 2, &received);
|
||||
db_bind_u64(stmt, 3, paid_timestamp);
|
||||
db_bind_u64(stmt, 4, invoice.id);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
|
||||
/* Tell all the waiters about the paid invoice. */
|
||||
trigger_invoice_waiter_resolve(invoices, invoice.id, &invoice);
|
||||
@@ -548,29 +562,29 @@ void invoices_waitany(const tal_t *ctx,
|
||||
void (*cb)(const struct invoice *, void*),
|
||||
void *cbarg)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
struct invoice invoice;
|
||||
|
||||
/* Look for an already-paid invoice. */
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT id"
|
||||
stmt = db_prepare_v2(invoices->db,
|
||||
SQL("SELECT id"
|
||||
" FROM invoices"
|
||||
" WHERE pay_index NOT NULL"
|
||||
" AND pay_index > ?"
|
||||
" ORDER BY pay_index ASC LIMIT 1;");
|
||||
sqlite3_bind_int64(stmt, 1, lastpay_index);
|
||||
" ORDER BY pay_index ASC LIMIT 1;"));
|
||||
db_bind_u64(stmt, 0, lastpay_index);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
if (db_select_step(invoices->db, stmt)) {
|
||||
invoice.id = sqlite3_column_int64(stmt, 0);
|
||||
db_stmt_done(stmt);
|
||||
if (db_step(stmt)) {
|
||||
invoice.id = db_column_u64(stmt, 0);
|
||||
|
||||
cb(&invoice, cbarg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* None found. */
|
||||
add_invoice_waiter(ctx, &invoices->waiters,
|
||||
} else {
|
||||
/* None found. */
|
||||
add_invoice_waiter(ctx, &invoices->waiters,
|
||||
true, 0, cb, cbarg);
|
||||
}
|
||||
tal_free(stmt);
|
||||
}
|
||||
|
||||
|
||||
@@ -598,30 +612,30 @@ const struct invoice_details *invoices_get_details(const tal_t *ctx,
|
||||
struct invoices *invoices,
|
||||
struct invoice invoice)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
bool res;
|
||||
struct invoice_details *details;
|
||||
|
||||
stmt = db_select_prepare(invoices->db,
|
||||
"SELECT"
|
||||
" state"
|
||||
", payment_key"
|
||||
", payment_hash"
|
||||
", label"
|
||||
", msatoshi"
|
||||
", expiry_time"
|
||||
", pay_index"
|
||||
", msatoshi_received"
|
||||
", paid_timestamp"
|
||||
", bolt11"
|
||||
", description"
|
||||
" FROM invoices"
|
||||
" WHERE id = ?;");
|
||||
sqlite3_bind_int64(stmt, 1, invoice.id);
|
||||
res = db_select_step(invoices->db, stmt);
|
||||
stmt = db_prepare_v2(invoices->db, SQL("SELECT"
|
||||
" state"
|
||||
", payment_key"
|
||||
", payment_hash"
|
||||
", label"
|
||||
", msatoshi"
|
||||
", expiry_time"
|
||||
", pay_index"
|
||||
", msatoshi_received"
|
||||
", paid_timestamp"
|
||||
", bolt11"
|
||||
", description"
|
||||
" FROM invoices"
|
||||
" WHERE id = ?;"));
|
||||
db_bind_u64(stmt, 0, invoice.id);
|
||||
db_query_prepared(stmt);
|
||||
res = db_step(stmt);
|
||||
assert(res);
|
||||
|
||||
details = wallet_stmt2invoice_details(ctx, stmt);
|
||||
db_stmt_done(stmt);
|
||||
tal_free(stmt);
|
||||
return details;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ struct wallet *wallet_new(struct lightningd *ld,
|
||||
bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
|
||||
enum wallet_output_type type)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
struct db_stmt *stmt;
|
||||
|
||||
stmt = db_select_prepare(w->db,
|
||||
"SELECT * from outputs WHERE prev_out_tx=? AND prev_out_index=?");
|
||||
@@ -81,55 +81,54 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
|
||||
return false;
|
||||
}
|
||||
|
||||
stmt = db_prepare(w->db,
|
||||
"INSERT INTO outputs ("
|
||||
" prev_out_tx"
|
||||
", prev_out_index"
|
||||
", value"
|
||||
", type"
|
||||
", status"
|
||||
", keyindex"
|
||||
", channel_id"
|
||||
", peer_id"
|
||||
", commitment_point"
|
||||
", confirmation_height"
|
||||
", spend_height"
|
||||
", scriptpubkey"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||
sqlite3_bind_blob(stmt, 1, &utxo->txid, sizeof(utxo->txid), SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 2, utxo->outnum);
|
||||
sqlite3_bind_amount_sat(stmt, 3, utxo->amount);
|
||||
sqlite3_bind_int(stmt, 4, wallet_output_type_in_db(type));
|
||||
sqlite3_bind_int(stmt, 5, output_state_available);
|
||||
sqlite3_bind_int(stmt, 6, utxo->keyindex);
|
||||
stmt = db_prepare_v2(
|
||||
w->db, SQL("INSERT INTO outputs ("
|
||||
" prev_out_tx"
|
||||
", prev_out_index"
|
||||
", value"
|
||||
", type"
|
||||
", status"
|
||||
", keyindex"
|
||||
", channel_id"
|
||||
", peer_id"
|
||||
", commitment_point"
|
||||
", confirmation_height"
|
||||
", spend_height"
|
||||
", scriptpubkey"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
db_bind_txid(stmt, 0, &utxo->txid);
|
||||
db_bind_int(stmt, 1, utxo->outnum);
|
||||
db_bind_amount_sat(stmt, 2, &utxo->amount);
|
||||
db_bind_int(stmt, 3, wallet_output_type_in_db(type));
|
||||
db_bind_int(stmt, 4, output_state_available);
|
||||
db_bind_int(stmt, 5, utxo->keyindex);
|
||||
if (utxo->close_info) {
|
||||
sqlite3_bind_int64(stmt, 7, utxo->close_info->channel_id);
|
||||
sqlite3_bind_node_id(stmt, 8, &utxo->close_info->peer_id);
|
||||
sqlite3_bind_pubkey(stmt, 9, &utxo->close_info->commitment_point);
|
||||
db_bind_u64(stmt, 6, utxo->close_info->channel_id);
|
||||
db_bind_node_id(stmt, 7, &utxo->close_info->peer_id);
|
||||
db_bind_pubkey(stmt, 8, &utxo->close_info->commitment_point);
|
||||
} else {
|
||||
sqlite3_bind_null(stmt, 7);
|
||||
sqlite3_bind_null(stmt, 8);
|
||||
sqlite3_bind_null(stmt, 9);
|
||||
db_bind_null(stmt, 6);
|
||||
db_bind_null(stmt, 7);
|
||||
db_bind_null(stmt, 8);
|
||||
}
|
||||
|
||||
if (utxo->blockheight) {
|
||||
sqlite3_bind_int(stmt, 10, *utxo->blockheight);
|
||||
db_bind_int(stmt, 9, *utxo->blockheight);
|
||||
} else
|
||||
sqlite3_bind_null(stmt, 10);
|
||||
db_bind_null(stmt, 9);
|
||||
|
||||
if (utxo->spendheight)
|
||||
sqlite3_bind_int(stmt, 11, *utxo->spendheight);
|
||||
db_bind_int(stmt, 10, *utxo->spendheight);
|
||||
else
|
||||
sqlite3_bind_null(stmt, 11);
|
||||
db_bind_null(stmt, 10);
|
||||
|
||||
if (utxo->scriptPubkey)
|
||||
sqlite3_bind_blob(stmt, 12, utxo->scriptPubkey,
|
||||
tal_bytelen(utxo->scriptPubkey),
|
||||
SQLITE_TRANSIENT);
|
||||
db_bind_blob(stmt, 11, utxo->scriptPubkey,
|
||||
tal_bytelen(utxo->scriptPubkey));
|
||||
else
|
||||
sqlite3_bind_null(stmt, 12);
|
||||
db_bind_null(stmt, 11);
|
||||
|
||||
db_exec_prepared(w->db, stmt);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user