Skip to content

Commit 5720db0

Browse files
committed
wallet: don't delete old htlcs when we forget a channel, do it on startup.
For old channels, this can take a while, and it stops everything. But we are only doing this to save space; it's not a *functional* necessity. A quick and dirty test with 50,000 htlcs shows the htlc deletion took 450msec. I tried adding an index, and changing it to set hstate to HTLC_STATE_INVALID instead of deleting entries, but it still took about 350ms. Reported-by: @michael1011 Signed-off-by: Rusty Russell <[email protected]> Changelog-Changed: lightningd: we defer deletion of old htlcs on channel close, to avoid pausing for a long time. Fixes: #7962
1 parent 89bce95 commit 5720db0

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

lightningd/lightningd.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,9 @@ int main(int argc, char *argv[])
13711371
trace_span_end(ld->topology);
13721372

13731373
db_begin_transaction(ld->wallet->db);
1374+
trace_span_start("delete_old_htlcs", ld->wallet);
1375+
wallet_delete_old_htlcs(ld->wallet);
1376+
trace_span_end(ld->wallet);
13741377

13751378
/*~ Pull peers, channels and HTLCs from db. Needs to happen after the
13761379
* topology is initialized since some decisions rely on being able to

wallet/wallet.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,6 +2957,21 @@ void wallet_channel_insert(struct wallet *w, struct channel *chan)
29572957
wallet_channel_save(w, chan);
29582958
}
29592959

2960+
void wallet_delete_old_htlcs(struct wallet *w)
2961+
{
2962+
struct db_stmt *stmt;
2963+
2964+
/* Delete htlcs for closed channels */
2965+
stmt = db_prepare_v2(w->db, SQL("DELETE FROM channel_htlcs"
2966+
" WHERE id IN ("
2967+
" SELECT ch.id"
2968+
" FROM channel_htlcs AS ch"
2969+
" JOIN channels AS c ON c.id = ch.channel_id"
2970+
" WHERE c.state = ?);"));
2971+
db_bind_int(stmt, channel_state_in_db(CLOSED));
2972+
db_exec_prepared_v2(take(stmt));
2973+
}
2974+
29602975
void wallet_channel_close(struct wallet *w,
29612976
const struct channel *chan)
29622977
{
@@ -2968,15 +2983,9 @@ void wallet_channel_close(struct wallet *w,
29682983
struct db_stmt *stmt;
29692984
u64 new_move_id;
29702985

2971-
/* Delete entries from `channel_htlcs` */
2972-
stmt = db_prepare_v2(w->db, SQL("DELETE FROM channel_htlcs "
2973-
"WHERE channel_id=?"));
2974-
db_bind_u64(stmt, chan->dbid);
2975-
db_exec_prepared_v2(stmt);
2976-
/* FIXME: We don't actually tell them what was deleted! */
2977-
if (db_count_changes(stmt) != 0)
2978-
htlcs_index_deleted(w->ld, chan, db_count_changes(stmt));
2979-
tal_free(stmt);
2986+
/* The channel_htlcs table is quite large, and deleting it can take a
2987+
* while. So we do that on next restart by calling
2988+
* wallet_delete_old_htlcs. */
29802989

29812990
/* Delete entries from `htlc_sigs` */
29822991
stmt = db_prepare_v2(w->db, SQL("DELETE FROM htlc_sigs "

wallet/wallet.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,14 @@ void wallet_state_change_add(struct wallet *w,
725725
*/
726726
void wallet_delete_peer_if_unused(struct wallet *w, u64 peer_dbid);
727727

728+
/**
729+
* wallet_delete_old_htlcs -- delete htlcs associated with CLOSED channels.
730+
*
731+
* We do this at startup, instead of when we finally CLOSED a channel, to
732+
* avoid a significant pause.
733+
*/
734+
void wallet_delete_old_htlcs(struct wallet *w);
735+
728736
/**
729737
* wallet_init_channels -- Loads active channels into peers
730738
* and inits the dbid counter for next channel.

0 commit comments

Comments
 (0)