A never-settling syncState wedges withSyncLock's coalescing forever — a fresh client still joins the corpse
- Lingua principale
- TypeScript
- Stelle
- 1
- Fork
- 21
- Merge medio
- 12h 14m
- PR unite (30g)
- 41
Descrizione
## Symptom
One `syncState()` whose underlying RPC never settles kills sync **permanently for the whole realm**: every later `syncState()` — including from a freshly constructed client — parks instantly without issuing a single network request, and no client-side recovery can release it.
## Why
`withSyncLock` coalesces per `(dbId, methodId)` through a **module-level** `inFlight` map, and the entry is removed only in the promise's `finally`. A sync that never settles (on wasm32 the transport carries no deadline — the wasm `ApiClient` drops its `timeout_ms`) therefore stays in `inFlight` forever, and every subsequent caller joins the corpse's promise. Replacing the client doesn't help: the map (and the `miden-sync-` Web Lock the corpse holds) are shared module state, not client state.
## Evidence (live, on-device — from the 0xMiden/wallet#777 investigation)
- iOS simulator, one sync RPC forced to hang: the wallet evicted its lock holder and built a fresh client; the next tick's `syncState` produced **zero** network traffic and never settled.
- `navigator.locks.query()` at that moment: `held: ["miden-sync-default:exclusive"]`, `pending: []` — held by the abandoned call, and the new caller isn't even queued (it coalesced in `inFlight`).
## Expected
A single stuck call must not be able to wedge sync beyond its own lifetime. The root cure is the transport deadline (miden-client's wasm `ApiClient` ignoring `timeout_ms`); a defensive bound on how long an `inFlight` entry may be joined would additionally keep any future never-settling path from becoming realm-permanent.
## Impact
On mobile (wallet runs the client on the main thread, 3s idle sync) this is the unrecoverable half of wallet#777: after the wedge, the wallet is chain-blind until the app is killed.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Esamina la funzione `withSyncLock` e la mappa a livello di modulo `inFlight`. Il bug si trova nel trasporto `ApiClient` wasm che ignora il `timeout_ms`. Inizia esaminando la costruzione del client e il flusso di sincronizzazione per capire dove vengono impostate e applicate le scadenze. La correzione implica garantire che il trasporto rispetti i timeout e possibilmente aggiungere un limite difensivo alla coalescenza di `inFlight`. I test richiedono la simulazione di una RPC bloccata in un ambiente wasm.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript, wasm
- Ambito
- backend, mobile-dev, web-dev
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Attiva
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 45/100