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 anything — git 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.
Task
set_initial_sync_complete(crates/dig-wallet/src/sage/db.rs) is a raw, unguarded setter forinitial_sync_completewith 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_epochguard, because an unguarded write is the money-lie defect that PR exists to close: a catch-up completing after a cache reset setinitial_sync_complete = 1over an emptied table, producingbalance 0, synced trueon a funded wallet — proven by execution, not by reading.Two writers were found and guarded (
complete_catch_upandrefresh_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 anything —git grep set_initial_sync_completeacross the workspace, not just the crate, since a consumer outsidedig-walletwould 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_completecannot be written from production code except through areset_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.