diff --git a/README.md b/README.md index 1127c01..eecc3c2 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,20 @@ When it comes to stability guarantees the Postgres database should always be mig don't lose historic data. The API under `/federations` isn't stable at this point and I'd recommend to subscribing to changes in Fedimint Observer if building against it. +### What database migrations actually do +On startup the backend runs schema setup/migrations in order (`v0.sql`, `v1.sql`, …). + +1. It checks the current DB version via `schema_version`. +2. It runs every migration newer than the current version inside a SQL transaction. +3. For migrations that need data reshaping, it runs a Rust backfill procedure before commit. + +There are three migration kinds in code: +* `schema_setup`: only for fresh DB setup, not allowed when upgrading an already populated DB. +* `migration`: pure SQL migration that can run for setup and upgrades. +* `migration_backfill`: SQL + Rust backfill for safe upgrades. + +In the current code path, `v0`-`v6` are marked as `schema_setup` (fresh setup only), while `v7`, `v8`, and `v9` are upgrade-capable migrations for existing databases. `v9` is additive and creates a new `gateways` table plus indexes; it does not alter/drop existing tables. + ## Federation Inspector The lesser-known component is an API under the `/config` path it can be used to get a JSON-encoded version of the federation config if you have an invite code. The first time it fetches the config from the federation using the invite diff --git a/fmo_server/schema/v9.sql b/fmo_server/schema/v9.sql index b262f74..7d4af1d 100644 --- a/fmo_server/schema/v9.sql +++ b/fmo_server/schema/v9.sql @@ -5,7 +5,9 @@ INSERT INTO VALUES (9); -CREATE TABLE IF NOT EXISTS gateways ( +-- V9 is intentionally additive: it creates a new table and indexes only. +-- It must not modify or drop any existing production tables. +CREATE TABLE gateways ( federation_id BYTEA NOT NULL REFERENCES federations (federation_id), gateway_id TEXT NOT NULL, node_pub_key TEXT NOT NULL, diff --git a/fmo_server/src/federation/observer.rs b/fmo_server/src/federation/observer.rs index 432177d..a5e22f9 100644 --- a/fmo_server/src/federation/observer.rs +++ b/fmo_server/src/federation/observer.rs @@ -1620,4 +1620,16 @@ mod tests { assert_eq!(last_7_days[6], now); assert_eq!(last_7_days[0], now - chrono::Duration::days(6)); } + + #[test] + fn v9_schema_is_additive_only() { + let migration = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/schema/v9.sql")).to_lowercase(); + + assert!(migration.contains("create table gateways")); + assert!(migration.contains("create index if not exists gateways_federation_id")); + assert!(migration.contains("create index if not exists gateways_node_pub_key")); + assert!(!migration.contains("alter table")); + assert!(!migration.contains("drop table")); + assert!(!migration.contains("create table if not exists gateways")); + } }