Module-scoped state diverges between the service-worker and offscreen realms
- Ngôn ngữ chính
- TypeScript
- Star
- 5
- Fork
- 28
- Merge trung bình
- 9 giờ 50 phút
- Pull request đã merge (30 ngày)
- 123
Mô tả
Three modules keep state at module scope and write it to a **shared** `chrome.storage.local` key with a blind whole-value write. Since #260 moved work into the offscreen document — a separate JS realm with its own module instances — each realm holds its own copy and each write clobbers the other's.
`vite.background.config.ts` defaults `MIDEN_USE_OFFSCREEN_CLIENT` to `true` for the service worker, so on Chrome both realms are live and this is the default configuration, not an edge case.
This is pre-existing on `main`; it is not caused by the 0.16 merge (#713). Filed from that PR's realm audit, which fixed the endpoint-override and stage-stamp instances of the same class and left these three.
### 1. Connectivity banner shows a stale or wrong state
`src/lib/miden/activity/connectivity-state.ts` — `current` is module-scoped (:71) and `notify()` (:85) blind-writes the whole snapshot to `miden-connectivity-state` (:97).
Flag-ON the offscreen realm reaches it through the prove fallback (`connectivity-issues.ts:25` → `markConnectivityIssue('prover')`), while the service worker writes the same key from `sync-manager.ts:179`. Neither realm has seen the other's issues, so whichever writes last replaces the full picture.
**Impact:** the connectivity banner can clear a genuine node problem because the offscreen realm reported a prover success, or vice versa. User-visible and misleading — it is the surface that tells someone whether the wallet can reach the network.
### 2. Prove telemetry silently loses entries
`src/lib/miden/sdk/prove-telemetry.ts` — `ring` is module-scoped (:42) and `persist()` (:103) writes the whole local ring to `miden_prove_telemetry` (:107).
Flag-ON, non-guardian proves record in the offscreen realm while guardian requeues and any SW-side prove record in the service worker. Each `persist()` overwrites the other realm's entries.
**Impact:** #466's always-on prove-timing telemetry under-reports, and which entries survive depends on write interleaving. Diagnostic only — no funds or UX consequence — but it is the data used to reason about prove performance, so it should not be quietly lossy.
### 3. Speculation cache is dead on the extension, and its producer still runs
`src/lib/miden/back/speculation-manager.ts` — `_instance` (:230) is only ever set by `initSpeculationManager`, called from `src/lib/miden/back/main.ts:72`, i.e. the **service worker** realm.
Flag-ON, the consumer (`miden-client-interface.ts:902`) runs in the **offscreen** realm, where `getSpeculationManager()` returns `null`. Meanwhile the popup still fires `SPECULATE` requests that the service worker services against its own instance.
**Impact:** the speculation cache never hits on the extension — the work is performed and then thrown away, so sends pay full prove cost while the wallet still spends CPU speculating. Wasted work on both sides.
### Expected
Each of these is single-writer or realm-aware:
- **(1)** one realm owns the connectivity snapshot; the other reports into it rather than overwriting — or the write merges instead of replacing.
- **(2)** `persist()` merges (read, concat, sort by timestamp, truncate to `RING_CAPACITY`) rather than overwriting; entries can carry their realm.
- **(3)** producer and consumer agree: either the manager is available in the realm that consumes it, or the producer stops speculating when it cannot be consumed.
Verification
All three modules are present in the built offscreen bundle (`dist/chrome_unpacked`), so the offscreen realm genuinely reaches them:
```
miden-connectivity-state offscreen chunks: 2
miden_prove_telemetry offscreen chunks: 1
SpeculationManager offscreen chunks: 2
```
Flag defaults, for reference — the service worker is the one build that turns the offscreen client on:
```
vite.background.config.ts MIDEN_USE_OFFSCREEN_CLIENT ?? 'true'
vite.extension.config.ts ?? 'false'
vite.desktop.config.ts ?? 'false'
vite.contentScripts.config.ts ?? 'false'
vite.mobile.config.ts 'false' (hardcoded)
```
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.