cryptoadvance / cryptoadvance/specter-desktop

Make JSON persistence atomic and robust against truncated config files

Open
#2,642 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.