From 86d4362b654c8fb001e06374c4d90f55942d2670 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Sat, 22 Jun 2019 15:08:21 +0200 Subject: [PATCH] wallet: Don't delete channels from DB, mark them closed. Since we now have a couple of long-lived dependents it is time we stop removing channels from the table once they are fully closed, and instead just mark them as closed. This allows us to keep forwards and transactions foreign keys intact, and it may help us debug things after the fact. Fixes #2028 Signed-off-by: Christian Decker --- lightningd/channel.c | 2 +- lightningd/test/run-invoice-select-inchan.c | 6 +-- wallet/wallet.c | 48 ++++++++++++++++++++- wallet/wallet.h | 4 +- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lightningd/channel.c b/lightningd/channel.c index 6908bb63c..64b8cfa60 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -113,7 +113,7 @@ static void destroy_channel(struct channel *channel) void delete_channel(struct channel *channel) { struct peer *peer = channel->peer; - wallet_channel_delete(channel->peer->ld->wallet, channel->dbid); + wallet_channel_close(channel->peer->ld->wallet, channel->dbid); tal_free(channel); maybe_delete_peer(peer); diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index a2e615ba7..50a7e3e1e 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -461,9 +461,9 @@ void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *scrip /* Generated stub for version */ const char *version(void) { fprintf(stderr, "version called!\n"); abort(); } -/* Generated stub for wallet_channel_delete */ -void wallet_channel_delete(struct wallet *w UNNEEDED, u64 wallet_id UNNEEDED) -{ fprintf(stderr, "wallet_channel_delete called!\n"); abort(); } +/* Generated stub for wallet_channel_close */ +void wallet_channel_close(struct wallet *w UNNEEDED, u64 wallet_id UNNEEDED) +{ fprintf(stderr, "wallet_channel_close called!\n"); abort(); } /* Generated stub for wallet_channel_save */ void wallet_channel_save(struct wallet *w UNNEEDED, struct channel *chan UNNEEDED) { fprintf(stderr, "wallet_channel_save called!\n"); abort(); } diff --git a/wallet/wallet.c b/wallet/wallet.c index cd783bf78..5def5da15 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1213,13 +1213,57 @@ void wallet_channel_insert(struct wallet *w, struct channel *chan) wallet_channel_save(w, chan); } -void wallet_channel_delete(struct wallet *w, u64 wallet_id) +void wallet_channel_close(struct wallet *w, u64 wallet_id) { + /* We keep a couple of dependent tables around as well, such as the + * channel_configs table, since that might help us debug some issues, + * and it is rather limited in size. Tables that can grow quite + * considerably and that are of limited use after channel closure will + * be pruned as well. */ + sqlite3_stmt *stmt; + + /* Delete entries from `channel_htlcs` */ stmt = db_prepare(w->db, - "DELETE FROM channels WHERE id=?"); + "DELETE FROM channel_htlcs " + "WHERE channel_id=?"); sqlite3_bind_int64(stmt, 1, wallet_id); db_exec_prepared(w->db, stmt); + + /* Delete entries from `htlc_sigs` */ + stmt = db_prepare(w->db, + "DELETE FROM htlc_sigs " + "WHERE channelid=?"); + sqlite3_bind_int64(stmt, 1, wallet_id); + db_exec_prepared(w->db, stmt); + + /* Delete entries from `htlc_sigs` */ + stmt = db_prepare(w->db, + "DELETE FROM channeltxs " + "WHERE channel_id=?"); + sqlite3_bind_int64(stmt, 1, wallet_id); + db_exec_prepared(w->db, stmt); + + /* Delete shachains */ + stmt = db_prepare(w->db, + "DELETE FROM shachains " + "WHERE id IN (" + " SELECT shachain_remote_id " + " FROM channels " + " WHERE channels.id=?" + ")"); + sqlite3_bind_int64(stmt, 1, wallet_id); + db_exec_prepared(w->db, stmt); + + /* Set the channel to closed and disassociate with peer */ + stmt = db_prepare(w->db, + "UPDATE channels " + "SET state=?, peer_id=?" + "WHERE channels.id=?"); + sqlite3_bind_int64(stmt, 1, CLOSED); + sqlite3_bind_null(stmt, 2); + sqlite3_bind_int64(stmt, 3, wallet_id); + db_exec_prepared(w->db, stmt); } void wallet_peer_delete(struct wallet *w, u64 peer_dbid) diff --git a/wallet/wallet.h b/wallet/wallet.h index 23c91e7ae..bb6224644 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -454,9 +454,9 @@ void wallet_channel_save(struct wallet *w, struct channel *chan); void wallet_channel_insert(struct wallet *w, struct channel *chan); /** - * wallet_channel_delete -- After resolving a channel, forget about it + * After fully resolving a channel, only keep a lightweight stub */ -void wallet_channel_delete(struct wallet *w, u64 wallet_id); +void wallet_channel_close(struct wallet *w, u64 wallet_id); /** * wallet_peer_delete -- After no more channels in peer, forget about it