0xMiden / 0xMiden/wallet

Send fails permanently on a transient "block_to is greater than chain tip" pre-send sync error instead of requeuing

Abierto
#822 2 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
5
Forks
28
Merge medio
9 h 50 min
PR fusionados (30 d)
123

Descripción

## Summary
A send can be marked Failed before anything is executed, proven or submitted, purely because the mandatory pre-send sync hit a transient RPC error. The send pipeline runs one un-retried `syncState` at stage `syncing`, and any throw from it falls through the processing loop's catch to `cancelTransaction`. The loop already owns a requeue-with-backoff primitive (used for prover outages since #419), but a syncing-stage failure never reaches it. The user sees a red Failed transaction and must press Retry by hand.

## Version
Bread Wallet 1.15.21 (Chrome extension), `@miden-sdk/miden-sdk` 0.15.9 (rust-client v0.15.5), testnet node 0.15.0 via rpc.testnet.miden.io. The same un-retried sync is present on `main`, `v1.16.0-rc.1` and `next`.

## Steps to reproduce
1. Use a testnet account on v1.15.21 and send any amount while the public RPC's backends are momentarily out of step (they are eventually consistent followers; two sequential calls can be answered by backends whose committed tips differ).
2. The client's sync learns the chain tip from one backend and immediately asks the other for notes up to that tip.
3. Observe the transaction row.

Not reproducible on demand: 0 of 260 replayed sync sequences hit the skew today. Observed once in 86 sends on one profile (2026-09-04 05:43:33Z), with the sends 30 seconds before and 60 seconds after completing normally.

## Expected
A sync failure before anything is built is treated as transient: the row is returned to Queued with a backoff and picked up on a later cycle, the same way a remote-prover outage is handled.

## Observed
Row goes to status Failed at stage `syncing`, with no processing-started timestamp and no transaction id, showing:

```
Error: Offscreen call 'syncState' failed: failed to sync state: RPC error: grpc request failed for sync_notes: invalid request parameters: code: 'Client specified an invalid argument', message: "block_to (2093442) is greater than chain tip (2093440)"
```

Nothing reached the chain (no client transaction record; no on-chain transaction or note from the account between its neighbouring sends). Retry is safe and succeeds.

## Root cause
Wallet side: `src/lib/miden/transaction/index.ts` stamps stage `syncing` and awaits the sync with no retry; the loop catch only special-cases locked-vault, apply-after-submit, note-already-consumed and killed-consume, then cancels; `requeueTransactionForRetry` is reachable only from guardian and prover branches (and the locked-vault branch on rc.1 and next). Only the background sync-manager tolerates a generic sync failure.

Underlying trigger: rust-client passes the tip returned by `sync_chain_mmr` verbatim as `block_to` to `sync_notes` and does not retry InvalidArgument; the node rejects any `block_to` above the answering backend's own committed tip; the testnet RPC is a load-balanced pool of follower backends routed per stream, so the two calls can see tips a few blocks apart. Upstream tracks the SDK side in rust-sdk #2383 ("retrying immediately is harmless"). The node behaviour is by design.

## Fix
Classify a throw at stage `syncing` as transient and route it through the existing requeue-with-backoff path instead of cancelling, bounded by the existing queued-age cap, so the next cycle re-syncs and proceeds. This is independent of the SDK change in #2383: only the wallet can make the syncing stage non-terminal. Consider surfacing a short "waiting for network" state rather than Failed while the row is backed off.

## Related
rust-sdk #2383 (SDK classification of future-block errors, open); node #2210 / #1866 (range check, by design); wallet #419 (prover-outage requeue precedent); wallet #777 / #788 (bounded sync lock on next, no retry).

Image

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.