Skip to content

Suite Sync: label rejected by the relay for exceeded quota is never re-sent after the top-up #32162

Description

@Vere-Grey

Describe the bug

When a wallet has used up its Suite Sync storage limit and the user edits a label, the relay rejects the write (ProtocolQuotaError). Suite reacts correctly and tops the wallet's limit up from the device pool — but the rejected label is never sent again. It stays local only, with no error shown, until the relay connection is re-established (app restart, or re-saving the relay URL in debug settings). Labels edited after the top-up sync normally, so the user silently loses exactly the one edit that hit the limit.

Info:

  • Platform: web and desktop (both reproduced; mobile not tested but shares the same sync code)
  • Browser: Chromium 151 (Playwright)
  • Suite Version: 26.10.0 (develop)
  • Firmware Version: T3W1 emulator, latest via trezor-user-env
  • OS: Linux

Steps to reproduce

Realistic:

  1. Enable Suite Sync and label something so the wallet gets its first storage allocation.
  2. Fill the wallet's allocation (roughly 10 KB of label edits), then edit one more label.
  3. Observe on a second device / fresh client: the label from step 2 never arrives, while any label edited afterwards does.
  4. Restart the app — the missing label now arrives.

Fast, deterministic (e2e infra on develop, #32070):

  1. yarn workspace @trezor/suite-e2e docker:suite-sync
  2. Run suite/e2e/tests/metadata/suite-sync/quota-manager.test.ts — the top-up test shrinks the wallet limit in the quota DB, writes a label, verifies the top-up happened, and fails on its last step because the label never reaches the relay.

Without Suite (bare Evolu client, proves it is client library behavior): branch quota-dead-sync-repro, then

cd suite/e2e && yarn tsx scripts/reproduce-quota-dead-sync.ts

8 self-verifying checks, exit code 0 when all pass.

Expected behavior

After a successful quota top-up, the rejected label is re-sent and reaches the relay without user action.

Screenshots

n/a

Additional context

Root cause is in the Evolu client, not the relay: on a quota error the client only reports the error (@evolu/common Shared.ts, ApplySyncMessage error branch) and drops the message — there is no retry queue. Each mutation is pushed once with only its own delta; previously rejected changes are re-sent only on a full re-sync, which happens when the owner is (re)subscribed. Suite subscribes the owner exactly once per wallet (createEnsureStorage returns the cached storage afterwards) and nothing triggers a re-sync after the top-up in createSuiteSyncInternalErrorHandler.

Suggested fix (Suite-side, no library change): after a successful allocateOwnerQuota in the RelayQuotaExceeded branch, re-subscribe the owner — the same path reconnectAllRelays / evoluStorage.updateRelayUrl uses. The top-up e2e test then becomes the regression guard.

Related: #32070 (tests), branch quota-dead-sync-repro (standalone reproduction).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    • Status
      🎯 To do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions