oasis-wallet-web icon indicating copy to clipboard operation
oasis-wallet-web copied to clipboard

Ledger crashes after enumerating twice without waiting

Open lukaw3d opened this issue 2 years ago • 0 comments

Crash

  • After https://github.com/oasisprotocol/oasis-wallet-web/pull/864/commits/4eb371ed17652bb7ef617a1765989abca54b40a5
  • open /open-wallet/ledger
  • click "Select accounts to open"
  • quickly press Esc
  • click "Select accounts to open"
  • Enumerating never finishes, and Ledger device needs to be restarted

This probably happens because takeEvery calls enumerateAccounts again, calling getUSBTransport before old transport.close https://github.com/oasisprotocol/oasis-wallet-web/blob/ad9591363d53216551537d37603ff67fb01fa2e4/src/app/state/ledger/saga.ts#L92 https://github.com/oasisprotocol/oasis-wallet-web/blob/ad9591363d53216551537d37603ff67fb01fa2e4/src/app/state/ledger/saga.ts#L72-L74

Solution

If we used takeLatest, it would cancel old enumerateAccounts and call transport.close first, before calling enumerateAccounts again. But cancellation doesn't wait for finally to finish https://redux-saga.js.org/docs/advanced/TaskCancellation/#note, so it still doesn't work.

Maybe reimplement takeLatest with additional timeout?

export function* ledgerSaga() {
  let enumerateTask = null
  // Reimplemented `takeLatest` with additional delay after canceling
  // TODO: Probably need to use actionChannel?
  while (yield* take(ledgerActions.enumerateAccounts)) {
    if (enumerateTask?.isRunning()) {
      yield* cancel(enumerateTask)
      // Workaround: `cancel` doesn't wait for `finally` to finish
      // https://redux-saga.js.org/docs/advanced/TaskCancellation/#note
      yield delay(2000)
    }
    enumerateTask = yield* fork(enumerateAccounts)
  }

Maybe just disable Esc again, and write a long comment?

lukaw3d avatar Jun 21 '22 22:06 lukaw3d