mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
db: track open sqlite3_stmt in DEVELOPER mode.
I would have liked to make it a tal object, then we'd catch most things with our memleak detection. However, sqlite3 doesn't seem to allow allocator overrides. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
abf510740d
commit
b036948219
84
wallet/db.c
84
wallet/db.c
@ -331,6 +331,71 @@ char *dbmigrations[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Leak tracking. */
|
||||
#if DEVELOPER
|
||||
/* We need a global here, since caller has no context. Yuck! */
|
||||
static struct list_head db_statements = LIST_HEAD_INIT(db_statements);
|
||||
|
||||
struct db_statement {
|
||||
struct list_node list;
|
||||
sqlite3_stmt *stmt;
|
||||
const char *origin;
|
||||
};
|
||||
|
||||
static struct db_statement *find_statement(sqlite3_stmt *stmt)
|
||||
{
|
||||
struct db_statement *i;
|
||||
|
||||
list_for_each(&db_statements, i, list) {
|
||||
if (i->stmt == stmt)
|
||||
return i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void db_assert_no_outstanding_statements(void)
|
||||
{
|
||||
struct db_statement *dbstat;
|
||||
|
||||
dbstat = list_top(&db_statements, struct db_statement, list);
|
||||
if (dbstat)
|
||||
fatal("Unfinalized statement %s", dbstat->origin);
|
||||
}
|
||||
|
||||
static void dev_statement_start(sqlite3_stmt *stmt, const char *origin)
|
||||
{
|
||||
struct db_statement *dbstat = tal(NULL, struct db_statement);
|
||||
dbstat->stmt = stmt;
|
||||
dbstat->origin = origin;
|
||||
list_add(&db_statements, &dbstat->list);
|
||||
}
|
||||
|
||||
static void dev_statement_end(sqlite3_stmt *stmt)
|
||||
{
|
||||
struct db_statement *dbstat = find_statement(stmt);
|
||||
list_del_from(&db_statements, &dbstat->list);
|
||||
tal_free(dbstat);
|
||||
}
|
||||
#else
|
||||
static void dev_statement_start(sqlite3_stmt *stmt, const char *origin)
|
||||
{
|
||||
}
|
||||
|
||||
static void dev_statement_end(sqlite3_stmt *stmt)
|
||||
{
|
||||
}
|
||||
|
||||
void db_assert_no_outstanding_statements(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void db_stmt_done(sqlite3_stmt *stmt)
|
||||
{
|
||||
dev_statement_end(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
sqlite3_stmt *db_prepare_(const char *caller, struct db *db, const char *query)
|
||||
{
|
||||
int err;
|
||||
@ -343,6 +408,7 @@ sqlite3_stmt *db_prepare_(const char *caller, struct db *db, const char *query)
|
||||
if (err != SQLITE_OK)
|
||||
fatal("%s: %s: %s", caller, query, sqlite3_errmsg(db->sql));
|
||||
|
||||
dev_statement_start(stmt, caller);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@ -353,7 +419,7 @@ void db_exec_prepared_(const char *caller, struct db *db, sqlite3_stmt *stmt)
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE)
|
||||
fatal("%s: %s", caller, sqlite3_errmsg(db->sql));
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
||||
/* This one doesn't check if we're in a transaction. */
|
||||
@ -394,15 +460,15 @@ bool db_exec_prepared_mayfail_(const char *caller UNUSED, struct db *db, sqlite3
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
fail:
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_stmt *PRINTF_FMT(3, 4)
|
||||
db_query(const char *caller UNUSED, struct db *db, const char *fmt, ...)
|
||||
db_query(const char *caller, struct db *db, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *query;
|
||||
@ -417,11 +483,14 @@ sqlite3_stmt *PRINTF_FMT(3, 4)
|
||||
/* Sets stmt to NULL if not SQLITE_OK */
|
||||
sqlite3_prepare_v2(db->sql, query, -1, &stmt, NULL);
|
||||
tal_free(query);
|
||||
if (stmt)
|
||||
dev_statement_start(stmt, caller);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static void destroy_db(struct db *db)
|
||||
{
|
||||
db_assert_no_outstanding_statements();
|
||||
sqlite3_close(db->sql);
|
||||
}
|
||||
|
||||
@ -437,6 +506,7 @@ void db_begin_transaction_(struct db *db, const char *location)
|
||||
void db_commit_transaction(struct db *db)
|
||||
{
|
||||
assert(db->in_transaction);
|
||||
db_assert_no_outstanding_statements();
|
||||
db_exec(__func__, db, "COMMIT;");
|
||||
db->in_transaction = NULL;
|
||||
}
|
||||
@ -492,11 +562,11 @@ static int db_get_version(struct db *db)
|
||||
|
||||
err = sqlite3_step(stmt);
|
||||
if (err != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return -1;
|
||||
} else {
|
||||
res = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -599,7 +669,7 @@ s64 db_get_intvar(struct db *db, char *varname, s64 defval)
|
||||
const unsigned char *stringvar = sqlite3_column_text(stmt, 0);
|
||||
res = atol((const char *)stringvar);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,12 @@ bool db_exec_prepared_mayfail_(const char *caller,
|
||||
struct db *db,
|
||||
sqlite3_stmt *stmt);
|
||||
|
||||
/* Wrapper around sqlite3_finalize(), for tracking statements. */
|
||||
void db_stmt_done(sqlite3_stmt *stmt);
|
||||
|
||||
/* Call when you know there should be no outstanding db statements. */
|
||||
void db_assert_no_outstanding_statements(void);
|
||||
|
||||
/* Do not keep db open across a fork: needed for --daemon */
|
||||
void db_close_for_fork(struct db *db);
|
||||
void db_reopen_after_fork(struct db *db);
|
||||
|
@ -183,7 +183,7 @@ static void trigger_expiration(struct invoices *invoices)
|
||||
list_add_tail(&idlist, &idn->list);
|
||||
idn->id = sqlite3_column_int64(stmt, 0);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
/* Expire all those invoices */
|
||||
update_db_expirations(invoices, now);
|
||||
@ -220,11 +220,11 @@ static void install_expiration_timer(struct invoices *invoices)
|
||||
assert(res == SQLITE_ROW);
|
||||
if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
|
||||
/* Nothing to install */
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return;
|
||||
} else
|
||||
invoices->min_expiry_time = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
memset(&expiry, 0, sizeof(expiry));
|
||||
expiry.ts.tv_sec = invoices->min_expiry_time;
|
||||
@ -339,10 +339,10 @@ bool invoices_find_by_label(struct invoices *invoices,
|
||||
sqlite3_bind_json_escaped(stmt, 1, label);
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
} else {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -360,10 +360,10 @@ bool invoices_find_by_rhash(struct invoices *invoices,
|
||||
sqlite3_bind_blob(stmt, 1, rhash, sizeof(*rhash), SQLITE_TRANSIENT);
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
} else {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -383,10 +383,10 @@ bool invoices_find_unpaid(struct invoices *invoices,
|
||||
sqlite3_bind_int(stmt, 2, UNPAID);
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
pinvoice->id = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
} else {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -476,7 +476,7 @@ bool invoices_iterate(struct invoices *invoices,
|
||||
|
||||
res = sqlite3_step(stmt);
|
||||
if (res == SQLITE_DONE) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
it->p = NULL;
|
||||
return false;
|
||||
} else {
|
||||
@ -586,13 +586,13 @@ void invoices_waitany(const tal_t *ctx,
|
||||
res = sqlite3_step(stmt);
|
||||
if (res == SQLITE_ROW) {
|
||||
invoice.id = sqlite3_column_int64(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
cb(&invoice, cbarg);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
/* None found. */
|
||||
add_invoice_waiter(ctx, &invoices->waiters,
|
||||
@ -618,7 +618,7 @@ void invoices_waitone(const tal_t *ctx,
|
||||
res = sqlite3_step(stmt);
|
||||
assert(res == SQLITE_ROW);
|
||||
state = sqlite3_column_int(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
if (state == PAID || state == EXPIRED) {
|
||||
cb(&invoice, cbarg);
|
||||
@ -650,5 +650,5 @@ void invoices_get_details(const tal_t *ctx,
|
||||
|
||||
wallet_stmt2invoice_details(ctx, stmt, dtl);
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ static void outpointfilters_init(struct wallet *w)
|
||||
outpointfilter_add(w->utxoset_outpoints, &txid, outnum);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
||||
struct wallet *wallet_new(struct lightningd *ld,
|
||||
@ -194,7 +194,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou
|
||||
results[i] = tal(results, struct utxo);
|
||||
wallet_stmt2output(stmt, results[i]);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
return results;
|
||||
}
|
||||
@ -466,13 +466,13 @@ bool wallet_shachain_load(struct wallet *wallet, u64 id,
|
||||
|
||||
err = sqlite3_step(stmt);
|
||||
if (err != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
|
||||
chain->chain.min_index = sqlite3_column_int64(stmt, 0);
|
||||
chain->chain.num_valid = sqlite3_column_int64(stmt, 1);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
/* Load shachain known entries */
|
||||
stmt = db_prepare(wallet->db, "SELECT idx, hash, pos FROM shachain_known WHERE shachain_id=?");
|
||||
@ -484,7 +484,7 @@ bool wallet_shachain_load(struct wallet *wallet, u64 id,
|
||||
memcpy(&chain->chain.known[pos].hash, sqlite3_column_blob(stmt, 1), sqlite3_column_bytes(stmt, 1));
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -500,18 +500,18 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
||||
"SELECT id, node_id, address FROM peers WHERE id=%"PRIu64";", dbid);
|
||||
|
||||
if (!stmt || sqlite3_step(stmt) != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
if (!sqlite3_column_pubkey(stmt, 1, &id)) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
addrstr = sqlite3_column_text(stmt, 2);
|
||||
if (addrstr) {
|
||||
addrp = &addr;
|
||||
if (!parse_wireaddr((const char*)addrstr, addrp, DEFAULT_PORT, NULL)) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
@ -519,7 +519,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
||||
|
||||
peer = new_peer(w->ld, sqlite3_column_int64(stmt, 0),
|
||||
&id, addrp);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
return peer;
|
||||
}
|
||||
@ -537,7 +537,7 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid)
|
||||
sqlite3_column_signature(stmt, 0, &htlc_sigs[n]);
|
||||
n++;
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
log_debug(w->log, "Loaded %zu HTLC signatures from DB", n);
|
||||
return htlc_sigs;
|
||||
}
|
||||
@ -703,7 +703,7 @@ bool wallet_channels_load_active(const tal_t *ctx, struct wallet *w)
|
||||
count++;
|
||||
}
|
||||
log_debug(w->log, "Loaded %d channels from DB", count);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -777,7 +777,7 @@ u32 wallet_blocks_height(struct wallet *w, u32 def)
|
||||
/* If we ever processed a block we'll get the latest block in the chain */
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW && sqlite3_column_type(stmt, 0) != SQLITE_NULL) {
|
||||
blockheight = sqlite3_column_int(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return blockheight;
|
||||
} else
|
||||
return def;
|
||||
@ -830,7 +830,7 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id,
|
||||
"max_accepted_htlcs FROM channel_configs WHERE id=%" PRIu64 ";";
|
||||
sqlite3_stmt *stmt = db_query(__func__, w->db, query, id);
|
||||
if (!stmt || sqlite3_step(stmt) != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
cc->id = id;
|
||||
@ -841,7 +841,7 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id,
|
||||
cc->to_self_delay = sqlite3_column_int(stmt, col++);
|
||||
cc->max_accepted_htlcs = sqlite3_column_int(stmt, col++);
|
||||
assert(col == 7);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -1012,7 +1012,7 @@ void wallet_peer_delete(struct wallet *w, u64 peer_dbid)
|
||||
"SELECT * FROM channels WHERE peer_id = %"PRIu64,
|
||||
peer_dbid);
|
||||
assert(sqlite3_step(stmt) == SQLITE_DONE);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
stmt = db_prepare(w->db, "DELETE FROM peers WHERE id=?");
|
||||
sqlite3_bind_int64(stmt, 1, peer_dbid);
|
||||
@ -1298,7 +1298,7 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
|
||||
ok &= htlc_in_check(in, "wallet_htlcs_load") != NULL;
|
||||
incount++;
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
stmt = db_query(
|
||||
__func__, wallet->db,
|
||||
@ -1320,7 +1320,7 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
|
||||
* dependencies in yet */
|
||||
outcount++;
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
log_debug(wallet->log, "Restored %d incoming and %d outgoing HTLCS", incount, outcount);
|
||||
|
||||
return ok;
|
||||
@ -1482,7 +1482,7 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet,
|
||||
sqlite3_column_sha256(stmt, 3, &payment_hash);
|
||||
ripemd160(&stubs[n].ripemd, payment_hash.u.u8, sizeof(payment_hash.u));
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return stubs;
|
||||
}
|
||||
|
||||
@ -1549,7 +1549,7 @@ void wallet_payment_store(struct wallet *wallet,
|
||||
sqlite3_bind_sha256(stmt, 1, payment_hash);
|
||||
res = sqlite3_step(stmt);
|
||||
assert(res == SQLITE_ROW);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -1664,7 +1664,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
payment = wallet_stmt2payment(ctx, stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return payment;
|
||||
}
|
||||
|
||||
@ -1775,7 +1775,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
*faildetail = tal_strndup(ctx, sqlite3_column_blob(stmt, 7),
|
||||
sqlite3_column_bytes(stmt, 7));
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
||||
void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
@ -1873,7 +1873,7 @@ wallet_payment_list(const tal_t *ctx,
|
||||
payments[i] = wallet_stmt2payment(payments, stmt);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
/* Now attach payments not yet in db. */
|
||||
list_for_each(&wallet->unstored_payments, p, list) {
|
||||
@ -1913,7 +1913,7 @@ bool wallet_network_check(struct wallet *w,
|
||||
|
||||
if (stmt && sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
sqlite3_column_sha256_double(stmt, 0, &chainhash.shad);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
if (!structeq(&chainhash, &chainparams->genesis_blockhash)) {
|
||||
log_broken(w->log, "Wallet blockchain hash does not "
|
||||
"match network blockchain hash: %s "
|
||||
@ -1927,7 +1927,7 @@ bool wallet_network_check(struct wallet *w,
|
||||
} else {
|
||||
/* Still a pristine wallet, claim it for the chain
|
||||
* that we are running */
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
stmt = db_prepare(w->db, "INSERT INTO vars (name, val) VALUES ('genesis_hash', ?);");
|
||||
sqlite3_bind_sha256_double(stmt, 1, &chainparams->genesis_blockhash.shad);
|
||||
db_exec_prepared(w->db, stmt);
|
||||
@ -1950,7 +1950,7 @@ static void wallet_utxoset_prune(struct wallet *w, const u32 blockheight)
|
||||
sqlite3_column_sha256_double(stmt, 0, &txid.shad);
|
||||
outpointfilter_remove(w->utxoset_outpoints, &txid, sqlite3_column_int(stmt, 1));
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
stmt = db_prepare(w->db, "DELETE FROM utxoset WHERE spendheight < ?");
|
||||
sqlite3_bind_int(stmt, 1, blockheight - UTXO_PRUNE_DEPTH);
|
||||
@ -1986,7 +1986,7 @@ void wallet_block_remove(struct wallet *w, struct block *b)
|
||||
stmt = db_prepare(w->db, "SELECT * FROM blocks WHERE height >= ?;");
|
||||
sqlite3_bind_int(stmt, 1, b->height);
|
||||
assert(sqlite3_step(stmt) == SQLITE_DONE);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
||||
void wallet_blocks_rollback(struct wallet *w, u32 height)
|
||||
@ -2049,7 +2049,7 @@ wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockheight,
|
||||
scid = tal(ctx, struct short_channel_id);
|
||||
mk_short_channel_id(scid, sqlite3_column_int(stmt, 0),
|
||||
sqlite3_column_int(stmt, 1), outnum);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return scid;
|
||||
}
|
||||
return NULL;
|
||||
@ -2130,7 +2130,7 @@ void wallet_transaction_add(struct wallet *w, const struct bitcoin_tx *tx,
|
||||
bitcoin_txid(tx, &txid);
|
||||
sqlite3_bind_sha256(stmt, 1, &txid.shad.sha);
|
||||
known = sqlite3_step(stmt) == SQLITE_ROW;
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
if (!known) {
|
||||
/* This transaction is still unknown, insert */
|
||||
@ -2171,12 +2171,12 @@ u32 wallet_transaction_height(struct wallet *w, const struct bitcoin_txid *txid)
|
||||
sqlite3_bind_sha256(stmt, 1, &txid->shad.sha);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
blockheight = sqlite3_column_int(stmt, 0);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return blockheight;
|
||||
}
|
||||
|
||||
@ -2200,11 +2200,11 @@ struct txlocator *wallet_transaction_locate(const tal_t *ctx, struct wallet *w,
|
||||
loc = tal(ctx, struct txlocator);
|
||||
loc->blkheight = sqlite3_column_int(stmt, 0);
|
||||
loc->index = sqlite3_column_int(stmt, 1);
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return loc;
|
||||
|
||||
fail:
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2224,7 +2224,7 @@ struct bitcoin_txid *wallet_transactions_by_height(const tal_t *ctx,
|
||||
tal_resize(&txids, count);
|
||||
sqlite3_column_sha256(stmt, 0, &txids[count-1].shad.sha);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
return txids;
|
||||
}
|
||||
@ -2264,7 +2264,7 @@ u32 *wallet_onchaind_channels(struct wallet *w,
|
||||
tal_resize(&channel_ids, count);
|
||||
channel_ids[count-1] = sqlite3_column_int64(stmt, 0);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
db_stmt_done(stmt);
|
||||
|
||||
return channel_ids;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user