Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion fmo_server/schema/v9.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions fmo_server/src/federation/observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
}
}