| 7012 | } |
| 7013 | |
| 7014 | static bool find_duplicate_chain_move(struct db *db, |
| 7015 | const char *nonchannel_acctname, |
| 7016 | /* 0 if none */ |
| 7017 | u64 channel_dbid, |
| 7018 | const struct bitcoin_outpoint *outpoint, |
| 7019 | /* optional */ |
| 7020 | const struct bitcoin_txid *spending_txid, |
| 7021 | struct mvt_tags tags, |
| 7022 | u64 id_ceiling) |
| 7023 | { |
| 7024 | struct db_stmt *stmt; |
| 7025 | u64 nonchannel_id; |
| 7026 | |
| 7027 | nonchannel_id = move_accounts_id(db, nonchannel_acctname, false); |
| 7028 | |
| 7029 | stmt = db_prepare_v2(db, |
| 7030 | SQL("SELECT" |
| 7031 | " spending_txid, tag_bitmap, account_channel_id, account_nonchannel_id" |
| 7032 | " FROM chain_moves" |
| 7033 | " WHERE " |
| 7034 | " utxo = ?" |
| 7035 | " AND " |
| 7036 | " id < ?")); |
| 7037 | db_bind_outpoint(stmt, outpoint); |
| 7038 | db_bind_u64(stmt, id_ceiling); |
| 7039 | db_query_prepared(stmt); |
| 7040 | |
| 7041 | /* Check that spending_txid and primary_tag match. We could |
| 7042 | * probably just match on spending_txid, but this is robust. */ |
| 7043 | while (db_step(stmt)) { |
| 7044 | struct mvt_tags these_tags; |
| 7045 | u64 this_nonchannel_id, this_channel_id; |
| 7046 | bool have_spending_txid; |
| 7047 | |
| 7048 | /* Access this now so it never complains we don't */ |
| 7049 | these_tags = db_col_mvt_tags(stmt, "tag_bitmap"); |
| 7050 | have_spending_txid = !db_col_is_null(stmt, "spending_txid"); |
| 7051 | this_nonchannel_id = db_col_is_null(stmt, "account_nonchannel_id") ? 0 : db_col_u64(stmt, "account_nonchannel_id"); |
| 7052 | this_channel_id = db_col_is_null(stmt, "account_channel_id") ? 0 : db_col_u64(stmt, "account_channel_id"); |
| 7053 | |
| 7054 | /* Either nonchannel id, or channel id must match */ |
| 7055 | if (nonchannel_id != this_nonchannel_id |
| 7056 | && channel_dbid != this_channel_id) { |
| 7057 | continue; |
| 7058 | } |
| 7059 | |
| 7060 | /* spending_txid must match */ |
| 7061 | if (spending_txid) { |
| 7062 | struct bitcoin_txid txid; |
| 7063 | if (!have_spending_txid) |
| 7064 | continue; |
| 7065 | db_col_txid(stmt, "spending_txid", &txid); |
| 7066 | /* This would only happen for reorgs */ |
| 7067 | if (!bitcoin_txid_eq(&txid, spending_txid)) |
| 7068 | continue; |
| 7069 | } else { |
| 7070 | if (have_spending_txid) |
| 7071 | continue; |
no test coverage detected