Submission confirmation is not tied to transaction identity — silent failures and possible duplicate actions
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- blockchain, frontend
Línea de trabajo
Start with src/submit/confirmationGate.ts, ActionSubmitController.ts, and ActionSubmitController.test.ts:156, then trace optimistic updates in bus/ingest.ts and retries in src/utils/cosmos/client.ts:281-303 and joinTable.ts:66. Run the existing submission tests first; done means confirmation and failure states are tied to transaction identity, optimistic movement cannot confirm a job, and uncertain retries do not create duplicate actions.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
From the external repository review (10 Sep 2026). Both halves verified against HEAD. Filed as one issue because they share a root cause and a fix: nothing in the submission path is tied to transaction identity.
a) Table progress is treated as confirmation
src/submit/confirmationGate.ts:41-49:
const countAdvanced = hasValue(current.actionCount) && current.actionCount > baseline.actionCount;
const indexAdvanced = nextActionIndex(current) > baseline.actionIndex;
const handAdvanced = hasValue(current.handNumber) && current.handNumber > baseline.handNumber;
return countAdvanced || indexAdvanced || handAdvanced;
All three are table-global counters. Any other player acting confirms our submission. The controller never compares job.hash to anything — it is assigned at ActionSubmitController.ts:199 and used only to call onSuccess.
The 8s timeout also marks the job confirmed, not unknown (:245-254 → confirmJob → status = "confirmed"). The timer starts at runJob entry, before broadcast, so it covers signing + broadcast + block time.
And a later rejection is then discarded (:207-210): isTerminal(job) is true for "confirmed", so a real chain rejection arriving afterwards is swallowed — no toast, no onError.
⚠️ Optimistic snapshots feed the same path. bus/ingest.ts:33 classifies optimistic as kind: "state", and those go straight onto the logical track that the controller reads. So a mempool projection of someone else's pending action can confirm our submission.
b) Uncertain failures cause fresh submissions
ActionSubmitController.ts:219-233 retries on transport errors. There is a guard — the reviewer under-stated this — but it is the same weak gate above, given only gateSettleMs: 250ms to observe a chain that commits in ~5s.
The retry re-signs from scratch: clearSigningCache() discards the memoized client, so the retry rebuilds the wallet and re-queries the account sequence.
The precise dangerous window: if the first tx is still pending, the re-query returns the same sequence and the identical bytes get deduped — harmless. If the first tx committed between the failure and the retry, the re-query returns sequence N+1 and produces a genuinely distinct, valid second action.
src/utils/cosmos/client.ts:281-303 (withMoneyMoverRetry, used by joinTable.ts:66) does the same with no confirmation gate at all, on a money-moving path.
Why this matters more than it looks
Combined with poker-vm#2609 — where the SDK returns a transaction hash for failed execution — there is currently no layer that can tell a user their action failed. The SDK reports failure as a hash; the UI confirms on unrelated table movement or an 8s timer; and any late rejection is discarded as moot.
Suggested plan
- Model the states honestly:
submitted,accepted,committed-success,committed-failure,unknown. A timer expiring producesunknown, neverconfirmed. That single change removes the silent-failure class. - Match by transaction identity. Correlate the committed receipt by hash rather than by counters.
performActionSyncalready returns a hash; the WS push should be reconcilable against it. - Keep optimistic state visually distinct from authoritative state and never let it satisfy a confirmation.
- On uncertain transport failure, query before resubmitting — and rebroadcast identical signed bytes rather than re-signing, so a duplicate is impossible rather than merely unlikely. Preserve the signed bytes and hash for that purpose.
- Serialize account-level submissions across the action path and
withMoneyMoverRetry, so two flows cannot race on the same sequence. - Tests exist for the current behaviour (
ActionSubmitController.test.ts:156codifies the 8s escape hatch as intended) — those need updating deliberately, not silently.
Original review findings 7 and 8.
- Lenguaje dominante
- TypeScript
- Estrellas
- 2
- Forks
- 5
- Merge medio
- 23 h 33 min
- PR fusionados (30 d)
- 87
Preparar el entorno
Aún no hemos revisado los archivos de configuración de este proyecto. Empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de block52/ui
-
guards: accept readonly arrays (and other array-likes) in isEmpty / hasElements / safeLengthAbiertoenhancement tech debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
chore(ui): move existing inline null/empty and typeof checks to the guardsPosiblemente ocupada @bitcoinbrisbane la tomó hoy. Abiertorefactor tech debt UI
Los mantenedores suelen responder en 1 día
-
architecture refactor tech debt
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
Los mantenedores suelen responder en 1 día
Todos los issues de block52/ui
Issues similares
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:auth-provider issue-rating: 🦞 diamond lobster no-stale P1
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
steipete/oracle#614 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Koenkk/zigbee-herdsman-converters#13656 ·
Los mantenedores suelen responder en 2 días
-
Report: Mooz Dance SDAbiertocheck:passed streams:remove
Dificultad 1/5 Menos de una hora Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
-
bug needs triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
actions/setup-node#1659 ·
Los mantenedores suelen responder en 1 día