Skip to content

Old guardian never releases an account whose switch delta never reached it #434

Description

@haseebrabbani

Problem

#369 proposed a periodic chain-reconciliation sweep for guardian switches that never reach the push path. It was closed COMPLETED on 2026-08-06, but it was closed by the merge of #375 — which fixed the first-tx reconstruction bug on the push path, not the sweep. On current main, release_if_guardian_switched still fires from exactly two push-triggered sites (services/delta_commit.rs and the canonicalization processor); jobs/canonicalization/reconciliation.rs is the unrelated #345 retained-delta sweep. No startup scan, no periodic chain check.

So every blind spot #369 enumerated still exists: switches predating v0.15.1, clients older than v0.15.0, failed best-effort pushes, and the offline switch path (which never pushes by design). The consequence is a permanent split-brain on the old operator: the account stays active (released_at: null), GET /state and /state/lookup serve stale pre-switch state, and the account holds capacity forever. No custody risk — the old operator's co-signatures are invalid on-chain — but recovery flows that query the old operator get convincingly stale state.

This is not hypothetical: 0xMiden/wallet#782 describes a switch executed while the old operator is network-dead — the exact case where the push can never land and only a chain-driven sweep can ever release the account.

Proposal

As in #369: a periodic job (or an extension of the canonicalization worker loop) that, for each non-released, non-EVM account, compares the stored commitment against chain via NetworkClient::verify_commitment, and on sustained mismatch where the on-chain guardian commitment differs from this server's ack key, runs the existing release path (release_if_guardian_switched semantics, accounts.release audit with operator_identity: system). Backoff/paging along the lines of the #345 sweep to keep it cheap.

Refs: #305, #311, #345, #369, #375.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions