From 876d698f3c395f24a38ef4f144dc2baae895db2f Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 3 Apr 2018 16:57:28 +0200 Subject: [PATCH] wallet: Add primitives to store onchaind transactions in the DB Signed-off-by: Christian Decker --- wallet/wallet.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ wallet/wallet.h | 21 +++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/wallet/wallet.c b/wallet/wallet.c index 112595545..b19a58040 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #define SQLITE_MAX_UINT 0x7FFFFFFFFFFFFFFF @@ -2277,3 +2278,77 @@ struct bitcoin_txid *wallet_transactions_by_height(const tal_t *ctx, return txids; } +void wallet_channeltxs_add(struct wallet *w, struct channel *chan, + const int type, const struct bitcoin_txid *txid, + const u32 input_num, const u32 blockheight) +{ + sqlite3_stmt *stmt; + stmt = db_prepare(w->db, "INSERT INTO channeltxs (" + " channel_id" + ", type" + ", transaction_id" + ", input_num" + ", blockheight" + ") VALUES (?, ?, ?, ?, ?);"); + sqlite3_bind_int(stmt, 1, chan->dbid); + sqlite3_bind_int(stmt, 2, type); + sqlite3_bind_sha256(stmt, 3, &txid->shad.sha); + sqlite3_bind_int(stmt, 4, input_num); + sqlite3_bind_int(stmt, 5, blockheight); + + db_exec_prepared(w->db, stmt); +} + +u32 *wallet_onchaind_channels(struct wallet *w, + const tal_t *ctx) +{ + sqlite3_stmt *stmt; + size_t count = 0; + u32 *channel_ids = tal_arr(ctx, u32, 0); + stmt = db_prepare(w->db, "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;"); + sqlite3_bind_int(stmt, 1, WIRE_ONCHAIN_INIT); + + while (sqlite3_step(stmt) == SQLITE_ROW) { + count++; + tal_resize(&channel_ids, count); + channel_ids[count-1] = sqlite3_column_int64(stmt, 0); + } + + return channel_ids; +} + +struct channeltx *wallet_channeltxs_get(struct wallet *w, const tal_t *ctx, + u32 channel_id) +{ + sqlite3_stmt *stmt; + size_t count = 0; + struct channeltx *res = tal_arr(ctx, struct channeltx, 0); + stmt = db_prepare(w->db, + "SELECT" + " c.type" + ", c.blockheight" + ", t.rawtx" + ", c.input_num" + ", c.blockheight - t.blockheight + 1 AS depth" + ", t.id as txid " + "FROM channeltxs c " + "JOIN transactions t ON t.id == c.transaction_id " + "WHERE channel_id = ? " + "ORDER BY c.id ASC;"); + sqlite3_bind_int(stmt, 1, channel_id); + + while (sqlite3_step(stmt) == SQLITE_ROW) { + count++; + tal_resize(&res, count); + + res[count-1].channel_id = channel_id; + res[count-1].type = sqlite3_column_int(stmt, 0); + res[count-1].blockheight = sqlite3_column_int(stmt, 1); + res[count-1].tx = sqlite3_column_tx(ctx, stmt, 2); + res[count-1].input_num = sqlite3_column_int(stmt, 3); + res[count-1].depth = sqlite3_column_int(stmt, 4); + sqlite3_column_sha256(stmt, 5, &res[count-1].txid.shad.sha); + } + + return res; +} diff --git a/wallet/wallet.h b/wallet/wallet.h index d07d734cb..e940d6c7c 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -128,7 +128,7 @@ struct channel_stats { u64 out_msatoshi_offered, out_msatoshi_fulfilled; }; -struct onchaindtx { +struct channeltx { u32 channel_id; int type; u32 blockheight; @@ -846,4 +846,23 @@ struct bitcoin_txid *wallet_transactions_by_height(const tal_t *ctx, struct wallet *w, const u32 blockheight); +/** + * Store transactions of interest in the database to replay on restart + */ +void wallet_channeltxs_add(struct wallet *w, struct channel *chan, + const int type, const struct bitcoin_txid *txid, + const u32 input_num, const u32 blockheight); + +/** + * List channels for which we had an onchaind running + */ +u32 *wallet_onchaind_channels(struct wallet *w, + const tal_t *ctx); + +/** + * Get transactions that we'd like to replay for a channel. + */ +struct channeltx *wallet_channeltxs_get(struct wallet *w, const tal_t *ctx, + u32 channel_id); + #endif /* LIGHTNING_WALLET_WALLET_H */