Commit 5aaa3c9
fix(db): clean orphaned FK rows and add startup consistency checks (#816)
* fix(db): clean orphaned FK rows before v33 network rename migration
Users whose wallets were deleted while system SQLite had FK enforcement
OFF retained orphaned child rows in wallet_transactions (and potentially
shielded tables). The v33 rename_network_dash_to_mainnet UPDATE triggers
FK re-validation under bundled SQLite (SQLITE_DEFAULT_FOREIGN_KEYS=1),
causing "FOREIGN KEY constraint failed". Add clean_orphaned_fk_rows()
step that safely removes orphans before the rename, handling tables that
may not yet exist.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(db): add non-fatal consistency checks on startup
Run PRAGMA quick_check and PRAGMA foreign_key_check before migrations
on every startup (skipped for first-time setup). Logs warnings for any
b-tree corruption or FK violations but never blocks initialization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(db): extend orphan cleanup to wallet_addresses and asset_lock_transaction
Add wallet_addresses to FK orphan deletion (seed_hash → wallet).
For asset_lock_transaction, apply the intended ON DELETE SET NULL
behavior: nullify identity_id and identity_id_potentially_in_creation
where the referenced identity no longer exists.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): comprehensive FK orphan cleanup covering all parent-child relationships
Extend clean_orphaned_fk_rows to cover every FK constraint in the schema:
- wallet children: wallet_addresses, wallet_transactions, platform_address_balances,
shielded_notes, shielded_wallet_meta, asset_lock_transaction, identity
- identity children: top_up, scheduled_votes, identity_order,
identity_token_balances, token_order
- identity SET NULL: asset_lock_transaction.identity_id columns
- token/contract/contested_name cascades
Add table_exists helper and per-table logging of cleaned rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): run orphan cleanup first in v33 migration
Move clean_orphaned_fk_rows to the top of the v33 migration step,
before any ALTER TABLE or CREATE TABLE operations that might trigger
FK re-validation on orphaned rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): move wallet column additions into v33 migration after orphan cleanup
ensure_wallet_columns_exist() ran ALTER TABLE wallet_addresses before
the migration system, triggering FK re-validation on orphaned rows
before clean_orphaned_fk_rows had a chance to run. This was the actual
cause of the user-reported migration failure.
Move add_wallet_balance_columns (v16) and add_address_total_received_column
(v17) into the v33 migration arm, after orphan cleanup. Both are idempotent
(check column existence first) so safe to re-run. Remove the pre-migration
ensure_wallet_columns_exist() call from initialize().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): remove redundant wallet column additions from v33 migration
The v16/v17 migration steps already add these columns sequentially
before v33 runs. The idempotent re-add in v33 was unnecessary — any
database reaching v33 has already passed through v16 and v17.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): handle missing network column in v0.9.0 scheduled_votes migration
The v0.9.0 release created scheduled_votes without a network column.
The v6 migration (update_scheduled_votes_table) assumed it existed,
causing migration failure for v0.9.0 users upgrading to v1.0.
Fix: check if scheduled_votes_old has a network column before copying
data. If missing, default to 'dash' (the only network at v0.9.0).
Add test_migration_from_v090_to_current that creates the exact v0.9.0
schema at DB version 5, populates realistic data, and migrates all
the way to current version — verifying data survives with correct
network rename.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(db): clean up historical comments in migration code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): defer FK checks during rename, improve consistency check logging
CMT-1: Add PRAGMA defer_foreign_keys = ON before rename_network_dash_to_mainnet.
Tables contestant and token have composite FKs that include network —
updating parent tables first would temporarily break child FK references.
CMT-2: PRAGMA quick_check can return multiple rows. Replace query_row
with prepare + query_map to capture all issues, with bounded logging.
CMT-3: Replace filter_map(|r| r.ok()) with explicit error handling in
foreign_key_check. Row decode errors are now logged instead of silently
dropped. Both checks cap output at 20 issues to avoid log spam.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(db): add debug logging to v33 migration steps for failure diagnosis
Add per-step debug logging to the v33 migration arm, per-table logging
to rename_network_dash_to_mainnet (with error-level on failure), and
version context to try_perform_migration error messages. This helps
pinpoint exactly which statement causes FK constraint failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(db): replace stringly-typed migration errors with MigrationError
Introduce a structured MigrationError type that carries table name,
operation details, and the underlying rusqlite::Error. This replaces
the previous String-based error path in try_perform_migration and gives
exact context when a migration step fails.
Also adds automatic PRAGMA foreign_key_check diagnostics when a
SQLITE_CONSTRAINT_FOREIGNKEY error is detected during migration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(db): use MigrationResultExt trait for cleaner error wrapping
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(db): fix schema-too-new error type and bound FK diagnostic logging
CMT-2: Replace InvalidParameterName with InvalidQuery for the
"schema version too new" error — semantically correct for a misuse
condition rather than a parameter naming issue.
CMT-3: Fix log_fk_violations to handle row decode errors (logged,
capped at 3) and cap violation output at 50 entries. Early-return
with explicit error messages on prepare/execute failures instead
of silently dropping them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent f4d3b3b commit 5aaa3c9
2 files changed
Lines changed: 1204 additions & 66 deletions
0 commit comments