0xMiden / 0xMiden/wallet

Module-scoped state diverges between the service-worker and offscreen realms

未关闭
#714 0 条评论 0 个 reaction 已指派 1 人 已被 @WiktorStarczewski 认领 在 GitHub 查看
主要语言
TypeScript
星标
5
派生
28
平均合并
9 小时 50 分钟
30 天内合并 PR
123

描述

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)
```

贡献指南

打开贡献指南

调研方向

The issue describes three modules with module-scoped state: connectivity-state.ts, prove-telemetry.ts, and speculation-manager.ts. Start by examining the build configuration in vite.background.config.ts to understand the offscreen document setup. Review how chrome.storage.local is used for shared state and trace the writes in each module. The goal is to make each module's storage writes realm-aware or implement a merge strategy instead of blind overwrites.

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, typescript
领域
backend, tooling
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。