cryptoadvance / cryptoadvance/specter-desktop
Make JSON persistence atomic and robust against truncated config files
- Dominant language
- Python
- Stars
- 847
- Forks
- 259
- Avg merge
- 6d 18h
- Merged PRs (30d)
- 2
Description
## Problem
Issue #2640 exposed that a corrupt or empty `config.json` can prevent Specter Desktop / `specterd --hwibridge` from starting:
```text
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
... while reading file C:\Users\angel\.specter\config.json. Reading from backup
...
Failed to execute script 'specterd' due to unhandled exception
```
The current JSON write path writes directly to the destination file. Opening with `"w"` truncates the target before the new JSON is fully written and validated. If the process is killed, Windows shuts down, antivirus/file locking interferes, or multiple helper processes race, the primary JSON file can be left empty/partial. If the backup is missing or invalid too, startup fails.
## Expected behavior
JSON persistence should be robust against interrupted writes:
- Write JSON to a temporary file in the same directory.
- Flush/fsync and validate the temporary file by reading it back.
- Atomically replace the destination with `os.replace`.
- Preserve a valid backup where possible.
- If primary JSON is invalid but backup is valid, recover cleanly.
- If both are invalid, show/log a clear recovery message instead of a secondary logging traceback.
## Affected area
- `src/cryptoadvance/specter/persistence.py`
- potentially tests around JSON persistence / backup recovery
## Context
This was found while investigating #2640. The reporter appears to run local Windows Specter Desktop in HWI Bridge mode with a remote Raspiblitz Specter, but the crash happens in the local helper process reading local `C:\Users\angel\.specter\config.json`.
The `v2.0.5 -> v2.1.9` diff does not appear to introduce this behavior; the fragile persistence behavior exists in both versions.
## Suggested fix
Add tests for:
1. Invalid primary + valid backup recovers.
2. Invalid primary + invalid/missing backup raises a clear exception without secondary logging errors.
3. Interrupted/temp-file write does not leave a truncated destination.
4. Successful writes are atomic and keep a usable backup.
Then update `_write_json_file`/`read_json_file` accordingly.
Contributor guide
Research direction
Start in src/cryptoadvance/specter/persistence.py by reading _write_json_file and read_json_file, then inspect the existing JSON persistence and backup-recovery tests. Add coverage for invalid primary and backup files, interrupted writes, and successful atomic writes; done means valid recovery, clear failure logging, and no truncated destination.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100