0xMiden / 0xMiden/web-sdk

prove({ prover: newLocalProver() }) is 18-49x slower than prove() with no argument

未關閉
#350 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
主要語言
TypeScript
星號
1
分支
21
平均合併
13 小時 14 分鐘
30 天內合併 PR
41

描述

Passing a prover to `prove()` is around fifty times slower than leaving the argument off, for the same transaction.

I hit this while timing proving for an app, and the gap was large enough that I assumed my measurement was wrong. It reproduces on the same request object, in the same page, back to back.

### Repro

```js
const script = await client.compile.txScript({
code: "use miden::core::sys\nbegin\n push.1 drop\n exec.sys::truncate_stack\nend\n",
});
const request = new TransactionRequestBuilder().withCustomScript(script).build();

// A — no prover argument
let staged = await client.transactions.executeRequest(account, request);
await staged.prove();

// B — explicit local prover
const prover = TransactionProver.newLocalProver();
staged = await client.transactions.executeRequest(account, request);
await staged.prove({ prover });
```

Timings on macOS, 8 cores, Chrome 152, `@miden-sdk/miden-sdk@0.15.9` single threaded, testnet:

```
A prove() 1925 ms 1267 ms
B prove({ prover }) 209043 ms 62244 ms
```

A second run on the same setup gave 2940 / 2726 ms for A and 53242 / 49823 ms for B. The later B call is faster than the first in both runs, so this is not degradation over time. The ratio lands between 18x and 49x depending on the run.

Both paths are local. I checked that by pulling the network down after the client was ready and the transaction executed, then calling `prove()` with no argument: it completed offline in 1742 ms. So the fast path is not delegating to a remote prover.

### Where the paths diverge

`proveResult` in the SDK sends the two cases to different calls, and `defaultProver` is null unless the app sets one:

```js
const prover = opts?.prover ?? defaultProver;
return prover
? await inner.proveTransaction(result, prover)
: await inner.proveTransaction(result);
```

The two branches resolve different provers: `custom_prover.get_prover()` versus `client.prover()`. `newLocalProver()` builds `LocalTransactionProver::new(ProvingOptions::default())`. I could not work out from here what `client.prover()` resolves to, so I am reporting the measurement rather than guessing at the cause.

This may be the same routing asymmetry described in #312, though that one is about `batch()` and the main thread, and here both calls go through the worker wrapper.

### Why it matters

`newLocalProver()` reads as the ordinary way to prove locally, and an app that wants local proving will reach for it. Nothing in the README or the API surface suggests the argument changes performance by this much. A note in the docs would help even if the behaviour is intended.

Environment: macOS, Chrome 152, node 24, pnpm 10.18, SDK 0.15.9, testnet.

貢獻指南

開啟貢獻指南

研究方向

查看 SDK 中的 `proveResult` 函數,了解兩個分支:一個有證明器參數,一個沒有。檢查 `client.prover()` 和 `LocalTransactionProver::new(ProvingOptions::default())` 以理解效能差異。執行提供的重現腳本來確認時間,然後分析兩個路徑以識別瓶頸。修復可能涉及對齊證明器配置或最佳化自訂證明器路徑。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
javascript, nodejs
領域
backend, performance
Issue 類型
缺陷
難度
3/5
預估耗時
1-2 天
活躍度
活躍
描述清晰度
描述清楚
新手友好度
65/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。