When we imported from accounts.db, we always used a reference into * the move_accounts table (via account_nonchannel_id). But (on * replay) if a channel was live, we used the reference into the * channels table (via account_channel_id) and our duplicate detection * didn't trigger. Now we need to get rid of such duplicates. * * Note that if the channel is now CLOSED, the references to accou
| 7825 | * Note that if the channel is now CLOSED, the references to account_channel_id |
| 7826 | * will have been converted to references using account_nonchannel_id. */ |
| 7827 | void migrate_remove_chain_moves_duplicates(struct lightningd *ld, struct db *db) |
| 7828 | { |
| 7829 | /* This is O(n^2) but there just aren't that many! */ |
| 7830 | u64 *to_delete = tal_arr(tmpctx, u64, 0); |
| 7831 | struct db_stmt *stmt; |
| 7832 | |
| 7833 | /* Gather */ |
| 7834 | stmt = db_prepare_v2(db, SQL("SELECT" |
| 7835 | " chain_moves.id," |
| 7836 | " utxo," |
| 7837 | " spending_txid," |
| 7838 | " tag_bitmap," |
| 7839 | " account_channel_id," |
| 7840 | " channels.full_channel_id," |
| 7841 | " move_accounts.name" |
| 7842 | " FROM chain_moves " |
| 7843 | " LEFT JOIN move_accounts " |
| 7844 | " ON move_accounts.id = chain_moves.account_nonchannel_id " |
| 7845 | " LEFT JOIN channels " |
| 7846 | " ON channels.id = chain_moves.account_channel_id " |
| 7847 | " ORDER BY move_accounts.id;")); |
| 7848 | db_query_prepared(stmt); |
| 7849 | while (db_step(stmt)) { |
| 7850 | struct bitcoin_outpoint outpoint; |
| 7851 | u64 id, channel_dbid; |
| 7852 | struct bitcoin_txid *spending_txid; |
| 7853 | struct mvt_tags tags; |
| 7854 | const char *nonchannel_acctname; |
| 7855 | |
| 7856 | id = db_col_u64(stmt, "chain_moves.id"); |
| 7857 | db_col_outpoint(stmt, "utxo", &outpoint); |
| 7858 | if (db_col_is_null(stmt, "spending_txid")) |
| 7859 | spending_txid = NULL; |
| 7860 | else { |
| 7861 | spending_txid = tal(tmpctx, struct bitcoin_txid); |
| 7862 | db_col_txid(stmt, "spending_txid", spending_txid); |
| 7863 | } |
| 7864 | tags = db_col_mvt_tags(stmt, "tag_bitmap"); |
| 7865 | if (db_col_is_null(stmt, "account_channel_id")) { |
| 7866 | channel_dbid = 0; |
| 7867 | nonchannel_acctname = db_col_strdup(tmpctx, stmt, "move_accounts.name"); |
| 7868 | db_col_ignore(stmt, "channels.full_channel_id"); |
| 7869 | } else { |
| 7870 | struct channel_id cid; |
| 7871 | channel_dbid = db_col_u64(stmt, "account_channel_id"); |
| 7872 | db_col_channel_id(stmt, "channels.full_channel_id", &cid); |
| 7873 | nonchannel_acctname = fmt_channel_id(tmpctx, &cid); |
| 7874 | } |
| 7875 | |
| 7876 | if (find_duplicate_chain_move(db, nonchannel_acctname, |
| 7877 | channel_dbid, |
| 7878 | &outpoint, |
| 7879 | spending_txid, |
| 7880 | tags, |
| 7881 | id)) { |
| 7882 | log_unusual(ld->log, |
| 7883 | "Deleting redundant chain_moves %"PRIu64" for account %s", |
| 7884 | id, nonchannel_acctname); |