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 <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-06-22 15:08:21 +02:00 committed by Rusty Russell
parent 1dbdc74bc3
commit 86d4362b65
4 changed files with 52 additions and 8 deletions

View File

@ -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);

View File

@ -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(); }

View File

@ -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)

View File

@ -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