Skip to content

Handle every wallet status in the readiness gate - #23

Open
Ikari wants to merge 1 commit into
masterfrom
fix/wallet-readiness-gate
Open

Handle every wallet status in the readiness gate#23
Ikari wants to merge 1 commit into
masterfrom
fix/wallet-readiness-gate

Conversation

@Ikari

@Ikari Ikari commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Corrige um caminho no gate de readiness que fazia o federator travar no boot, em silêncio.

Não mergear ainda — segue o mesmo ciclo do #22.

O bug

HathorWallet#isReady só reconhecia CONNECTING (1), SYNCING (2) e READY (3). A wallet headless reporta seis estados. Ela chega em PROCESSING (5) depois de baixar o histórico, enquanto processa o que baixou — um estado em que a checagem pode legitimamente cair, ainda mais logo após um restart.

Caindo ali, nenhum if casava, a função caía fora sem return e resolvia undefined. O main.ts lia isso como "não pronta" e passava a esperar o evento wallets-ready, que só o próprio isReady emite — e nada mais re-checa depois. O federator travava no boot, sem log de erro.

A correção

  • PROCESSING entra junto com CONNECTING e SYNCING como estado transitório que faz retry.
  • CLOSED (0) e ERROR (4) vão para o caminho de restart, ao lado da heurística de "looks stopped" que já existia. O start é idempotente, então isso também recupera uma wallet que morreu no meio do sync.
  • Estado desconhecido loga warn e faz retry, em vez de cair fora — a função nunca mais pode resolver undefined.

Testes

test/HathorWallet.test.ts, novo, 7 casos cobrindo cada estado — incluindo que esgotar o budget de retry resolve para um false definido.

A suíte completa tem 5 falhas em hathorEvent.test.js, pré-existentes: confirmei com git stash que falham igual no master limpo, sem relação com esta mudança.

Escopo e honestidade sobre o alcance

Encontrado enquanto eu testava a atualização da imagem da wallet, mas a lacuna não é novaPROCESSING já existia na wallet-lib 1.14, então é latente também na imagem que roda em produção hoje.

Não consegui disparar sob demanda: subi o federator de propósito com a wallet em PROCESSING e ele repetiu a checagem e passou. A janela é curta — uns segundos num arranque de ~40 s. Isso explica por que passou despercebido, não por que seria inofensivo: restart é exatamente quando se cai nela.

O budget de retry atual (5 tentativas, ~150 s no total) não foi alterado neste PR. Se em algum momento o sync voltar a demorar muito, ele estoura antes da wallet ficar pronta — vale revisitar separadamente, com um número escolhido a partir de medição.

🤖 Generated with Claude Code

https://claude.ai/code/session_013NgawoxTe2eyJZzUBBh7pr

HathorWallet#isReady only recognized CONNECTING (1), SYNCING (2) and READY (3), but
the headless wallet reports six states. The wallet reaches PROCESSING (5) after it
finishes downloading history, while it processes what it just downloaded - a state a
status check can legitimately land on, especially right after a restart.

Landing there hit no branch, so the function fell off the end and resolved undefined.
main.ts read that as "not ready" and then waited on a 'wallets-ready' event that only
isReady itself can emit - and nothing re-checks afterwards. The federator would hang
at boot, silently, with no error logged.

Now:
- PROCESSING joins CONNECTING and SYNCING as a transient state that retries.
- CLOSED (0) and ERROR (4) take the restart path, alongside the existing
  "looks stopped" heuristic; start is idempotent, so it also recovers a wallet that
  died mid-sync.
- Any unrecognized status warns and retries instead of falling through, so the
  function can never resolve undefined again.

Adds test/HathorWallet.test.ts covering each state, including that exhausting the
retry budget resolves to a definite false.

Found while testing the upgrade to the official wallet image, but the gap is not new -
PROCESSING already existed in wallet-lib 1.14, so this is latent on the current
production image too. It was not reproducible on demand in testing: the PROCESSING
window is short (a few seconds out of a ~40 s startup), which is why it has gone
unnoticed rather than why it is harmless.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant