Complete the alpha-hardening Ralph task set, including tracker billing/accounting guards, validator fraud-audit primitives, wallet binding proof support, documentation runbooks, and updated tests. Verification: .venv/bin/python -m compileall -q packages tests; .venv/bin/python -m pytest -q --tb=short (313 passed, 3 skipped, 1 failed: tests/test_mining_cli.py::test_legacy_start_without_port_uses_next_available_port because meshnet-node pid 1263451 is already listening on port 7000).
4.5 KiB
4.5 KiB
Status: stub
Runbook: Ledger backup
Covers backing up the tracker's authoritative money/trust state — the billing ledger, dashboard accounts DB, and node registry (strike/ban/reputation) — and how to pause hive gossip during the backup window so peers don't replicate against a half-copied file.
Trust assumptions (read first)
Per ADR-0016, one operator-designated tracker holds the treasury keypair and is the source of truth for settlement; other hive members only replicate. Back up that tracker's databases — a follower's copies are eventually consistent, not authoritative. See ADR-0015 for the settlement loop these tables feed.
Prerequisites
- Shell access to the settlement-capable tracker host.
sqlite3CLI (or.backupsupport in the Pythonsqlite3module) available for online, consistent snapshots.- Know the tracker's configured DB paths — defaults, unless overridden by CLI
flags:
- Billing ledger:
billing.sqlite(--billing-db,DEFAULT_BILLING_DB_PATHinpackages/tracker/meshnet_tracker/billing.py) - Dashboard accounts:
accounts.sqlite(--accounts-db,DEFAULT_ACCOUNTS_DB_PATHinpackages/tracker/meshnet_tracker/accounts.py) - Node registry (strike/ban/reputation event log,
packages/contracts/meshnet_contracts/__init__.py::RegistryEventLog): path is whatever was passed asregistry_dbwhen the tracker'sLocalSolanaContractswas constructed. As of this writing the tracker CLI (meshnet_tracker/cli.py) does not expose a--registry-dbflag or wire acontracts=instance intoTrackerServerby default — confirm with whoever deployed this tracker whether registry persistence is actually enabled before assuming a file exists to back up. If it isn't wired up yet, strike/ban/reputation state is RAM-only and this step is moot until that gap closes (tracked loosely against issue 05).
- Billing ledger:
Steps
- Identify the actual DB paths in use (check the tracker's start command /
systemd unit / process env for
--billing-db,--accounts-db, and any registry DB argument). - Pause hive gossip on this tracker so peers don't pull a partial/locked
file mid-backup:
- If the tracker is the sole settlement node with no
--cluster-peers, gossip is already off — skip to step 3. - Otherwise, stop replication by restarting the process without
--cluster-peers(or with an empty peer list) for the duration of the backup, or take the backup during a maintenance window with peers temporarily pointed away from this tracker at the load balancer/DNS level. There is currently no live "pause gossip" admin endpoint — this is a process-restart-level operation. - Confirm no in-flight
/v1/registry/gossip,/v1/billing/gossip, or/v1/accounts/gossiptraffic before proceeding (check access logs).
- If the tracker is the sole settlement node with no
- Take an online, consistent copy of each SQLite file using the backup API
rather than
cp(WAL-mode files can be mid-write):sqlite3 billing.sqlite ".backup '/backups/billing-$(date +%Y%m%dT%H%M%S).sqlite'" sqlite3 accounts.sqlite ".backup '/backups/accounts-$(date +%Y%m%dT%H%M%S).sqlite'" # registry DB, if configured: sqlite3 registry.sqlite ".backup '/backups/registry-$(date +%Y%m%dT%H%M%S).sqlite'" - Verify each backup opens and has rows in its expected tables
(
billing_ledger/event log tables,accounts,registry_events). - Resume gossip (restore
--cluster-peers/ routing) once backups are confirmed good. - Ship backups off-host per your normal retention policy. Do not store them
alongside
.env.devnetor keypair files (see secrets handling below).
Rollback
- If a restore is needed, stop the tracker, replace the live
.sqlitefile(s) with the chosen backup, and restart. Because billing/accounts/registry each use append-only event logs, a stale restore under-counts recent activity rather than corrupting state — reconcile any gap against node/operator reports for the missing window before resuming payouts. - If gossip was paused via a peer-list restart, confirm peers re-sync
(
events_sincecatch-up) before considering the rollback complete.
Secrets handling
- Never commit
.env.devnet, treasury keypair JSON files,--hive-secret, or--validator-service-tokenvalues to a repo or ship them inside a DB backup archive. Back these up separately, encrypted, per your existing secrets process.