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