Skip to content

set_initial_sync_complete can express the unguarded true direction — narrow its type #462

Description

@MichaelTaylor3d

Task

set_initial_sync_complete (crates/dig-wallet/src/sage/db.rs) is a raw, unguarded setter for initial_sync_complete with no production caller. Make it unreachable from production code.

Why it matters now rather than as tidiness

dig-node#454 has just made every real writer of that flag take a reset_epoch guard, because an unguarded write is the money-lie defect that PR exists to close: a catch-up completing after a cache reset set initial_sync_complete = 1 over an emptied table, producing balance 0, synced true on a funded wallet — proven by execution, not by reading.

Two writers were found and guarded (complete_catch_up and refresh_tracked_coins; the second was found only because someone went looking for a sibling). This setter is a third path to the same state that bypasses the guard entirely. It is safe today only because nothing calls it — which is precisely the condition that changes the moment someone needs to set that flag and finds a function whose name says it does exactly that.

The guard is the invariant. A public unguarded setter beside it is an invitation to re-open the hole, and the next author will have no reason to suspect one exists.

Scope

Make it #[cfg(test)], or delete it if the tests do not need it either. Confirm the no-caller claim yourself before removing anythinggit grep set_initial_sync_complete across the workspace, not just the crate, since a consumer outside dig-wallet would make this a breaking change rather than a cleanup.

If tests genuinely need to force the flag, keep it test-only and name it so its danger is on its face (force_initial_sync_complete_for_test, or similar). A test-only escape hatch is fine; an ambiguous one is what this ticket is about.

Evidence

Found by the dig-node#454 lane while guarding the two real writers, and flagged by it as "a loaded gun for the next writer" — correctly filed rather than folded into an unrelated diff.

Acceptance

initial_sync_complete cannot be written from production code except through a reset_epoch-guarded path, enforced by the compiler rather than by convention. A test that greps for callers is not sufficient — the point is that the next writer cannot reach it, not that today's writers do not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions