Skip to content

reconcile_persisted_torrents never rebuilds torrent_map, making all persisted downloads unmanageable after restart #360

Description

@forkwright

Finding

TorrentSession::new initialises the librqbit Session with SessionPersistenceConfig::Json, so librqbit reloads every previously active torrent from disk on startup. The harmonia-side mapping torrent_map (DashMap<DownloadId, usize>) is always constructed empty and is never repopulated from the persisted state. reconcile_persisted_torrents only reads a count and logs it; it never iterates the live torrents to rebuild the DownloadId -> librqbit_index mapping. After a restart, every get_torrent, get_stats, pause_torrent, and delete_torrent for a previously started download returns TorrentNotFound, even though librqbit is actively seeding those torrents in the background with no management path.

Evidence

crates/ergasia/src/session.rs:85

DashMap::new()

torrent_map is created empty at construction and is the sole source of DownloadId -> index lookups.

crates/ergasia/src/session.rs:195

pub fn reconcile_persisted_torrents(&self) {

The body (lines 196-197) only calls with_torrents(|t| t.count()) and logs the result. torrent_map is never modified, so the reload performed by librqbit is invisible to every harmonia lookup.

Why this matters

Under the counter-surveillance threat model, restarts are routine and expected (kill switch, power-cycling, OS reboots after updates, crash recovery). With the mapping unrestored, the operator silently loses all control over in-progress transfers across any restart: a download cannot be paused, deleted, or even queried, while librqbit keeps the torrent active and continues announcing to trackers and peers. An operator who believes a sensitive transfer was paused or removed has no way to confirm or act on it through harmonia's API, and the unmanaged seeding continues to generate network traffic that the operator can no longer stop.

Desired correction

reconcile_persisted_torrents must enumerate the session's live torrents, recover each one's harmonia DownloadId from the persisted metadata (or a supplementary persisted mapping table written alongside the librqbit state), and repopulate torrent_map before the session is considered ready. Done when: after a clean restart, get_stats(download_id), pause_torrent(download_id), and delete_torrent(download_id) all succeed for a download that was active before the restart.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions