0xMiden / 0xMiden/web-sdk

waitFor can sleep beyond its configured polling timeout

Aperta Adatta ai principianti
#378 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
1
Fork
21
Merge medio
12h 14m
PR unite (30g)
41

Descrizione

`TransactionsResource.waitFor()` documents `timeout` as a wall-clock polling
timeout. It checks the deadline at the start of each iteration, but then
sleeps for the full `interval` even when less time remains.

With immediately resolving sync/store calls and no committed transaction:

- `timeout: 50, interval: 5000`: the promise is still pending at 50 ms and
rejects at 5000 ms in a fake-timer test.
- `timeout: 50, interval: 200`: three real-clock runs rejected after 203, 201,
and 201 ms; the error message said `timed out after 50ms`.
- An immediately committed transaction still succeeds, and `timeout: 0`
continues to allow waiting without a deadline.

The tests import the unchanged resource implementation. Only the inner
sync/store interface and WASM ID/filter constructors are stubbed. No node,
proof generation, transaction submission, or WASM binary is involved.
The existing 141 resource tests pass; the new idle-sleep deadline assertion
fails. The wider web-client JavaScript unit suite passes all 555 tests.

Checked on `next` at `5316dc12585a5702da19b2e0bf85d432b2eaa842`. The resource
file is identical on `main` at `671335b15701865621b9340fe116f8cb816135f1`.
I am not attributing this to the latest release.

## Reproduction

From the repository root, run this with Node 22 using
`node --input-type=module` (paste the snippet on stdin). It imports the real
resource but makes no network requests:

```js
import { TransactionsResource } from './crates/web-client/js/resources/transactions.js';

const inner = {
syncChain: async () => {},
getTransactions: async () => [],
};
const wasm = {
TransactionId: { fromHex: value => ({ value }) },
TransactionFilter: { ids: values => ({ values }) },
};
const resource = new TransactionsResource(inner, async () => wasm, {
assertNotTerminated() {},
});
const start = performance.now();
try {
await resource.waitFor('synthetic-id', { timeout: 50, interval: 200 });
} catch (error) {
console.log({
elapsedMs: Math.round(performance.now() - start),
message: error.message,
});
}
```

Elapsed time is approximately 200 ms rather than 50 ms. Timing will vary;
the fake-timer case above isolates the same extra sleep deterministically.

- [waitFor deadline check and unconditional interval sleep](https://github.com/0xMiden/web-sdk/blob/5316dc12585a5702da19b2e0bf85d432b2eaa842/crates/web-client/js/resources/transactions.js#L930)
- [Documented wall-clock polling timeout](https://github.com/0xMiden/web-sdk/blob/5316dc12585a5702da19b2e0bf85d432b2eaa842/crates/web-client/js/types/api-types.d.ts#L840)

## Scope

This appears distinct from #314/#320 (batch confirmation and its sync
method), and #321 (a sync call that never settles): here the singular wait's
sync and store calls complete immediately, and only the inter-poll sleep
exceeds the deadline.

Should a finite timeout bound that idle sleep by the remaining polling
budget, while retaining `timeout: 0`? I would keep any follow-up scoped to
that behavior and its regression cases, not active RPC cancellation, batch
confirmation, submission, or transaction recovery. Bounding the sleep alone
would not guarantee a hard deadline while an RPC is still pending.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

The bug is in `crates/web-client/js/resources/transactions.js` in the `waitFor` method. Start by reading the method around line 930. The issue is that the function sleeps for the full polling interval even when less time remains before the timeout. Look at the existing tests for the TransactionsResource to understand the testing pattern. The reproduction script in the issue body can be run to verify the bug. The fix involves calculating the remaining time before the deadline and sleeping for the minimum of that and the polling interval.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
javascript, typescript
Ambito
backend-api-design, testing
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
75/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.