Skip to content

fix(accounts): speed up account backup imports - #80

Merged
tomcasaburi merged 4 commits into
masterfrom
fix/account-import-performance
Jul 29, 2026
Merged

fix(accounts): speed up account backup imports#80
tomcasaburi merged 4 commits into
masterfrom
fix/account-import-performance

Conversation

@tomcasaburi

@tomcasaburi tomcasaburi commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • import the backed-up identity directly instead of generating and deleting disposable credentials
  • bulk-write comments, votes, and edits, then rebuild derived indexes once per import
  • limit post-import comment refresh subscriptions to the ten newest comments
  • add regression tests for compacted records, index rebuilding, and import orchestration

Root cause

Account backups were replayed one record at a time through normal mutation paths. In particular, every imported edit rebuilt derived indexes and post summaries, making larger imports effectively quadratic. The flow also created an unused default account and started a refresh watcher for every imported comment.

Impact

A 100 KiB account file is not inherently excessive. In a production 5chan preview, representative 100 KiB imports improved as follows:

Fixture Released hooks This branch
250 comments 679.4 ms 151.8 ms
400 votes 1159.4 ms 159.2 ms
300 edits 2405.4 ms 112.4 ms

A mixed 100 KiB account imported in 90.7 ms normally and 507.9 ms under 4x CPU throttling with constrained networking. Import and re-export preserved all 100 comments, 100 votes, and 50 edits. No 5chan source change is required.

Verification

  • corepack yarn test --reporter=dot (1154 passed, 6 skipped)
  • corepack yarn test:coverage --reporter=dot (97.26% overall)
  • node scripts/verify-hooks-stores-coverage.mjs
  • corepack yarn type-check
  • corepack yarn lint (0 errors; existing warnings only)
  • corepack yarn knip
  • corepack yarn prettier
  • corepack yarn build
  • git diff --check
  • production 5chan preview import/export round-trip with synthetic 100 KiB account fixtures

Note

Medium Risk
Changes touch local account identity, IndexedDB history writes, and import failure rollback; mistakes could corrupt or partially apply account data, though extensive new tests cover bulk import and rollback paths.

Overview
Account backup import no longer creates a disposable default account and replays each comment, vote, and edit through the normal single-record APIs. Imports merge getDefaultAccountFields() with the backup, assign a new local id (so re-import cannot overwrite), hydrate once via addAccount(..., { returnHydratedAccount: true }), then persist history through importAccountHistory in one bulk replace with snapshot rollback on failure; failed history import removes the new account and destroys its PKC client.

importAccountHistory sanitizes comments/votes/edits, rebuilds vote and edit indexes and summaries once, and uses replaceDatabaseArraysWithRollback across the three per-account history stores.

Post-import, comment update watchers match startup: only the ten newest comments via getInitAccountCommentsToUpdate, not the full history.

addAccount gains stricter name-map handling (stale vacated names, missing metadata) and optional hydrated return without destroying the PKC instance. getDefaultAccountFields is shared between default account generation and import defaults.

Reviewed by Cursor Bugbot for commit 7c2036f. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Account imports now receive a fresh local identifier, preventing existing accounts from being overwritten.
    • Imported comments, votes, and edits are restored in bulk for faster handling of large backups.
    • Imported account history is available with its indexes and summaries intact.
  • Bug Fixes

    • Account imports now preserve the original signer and author information.
    • Invalid vote or edit history is rejected before it can be saved.
    • Comment update monitoring is limited to the ten newest imported comments for improved efficiency.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Account import now assigns fresh local identifiers, hydrates identities once, bulk-imports sanitized history, and initializes update watchers only for the ten newest imported comments. Database and action tests cover hydration, validation, round-tripping, and bulk-write behavior.

Changes

Account import

Layer / File(s) Summary
Identity hydration and import orchestration
src/stores/accounts/accounts-database.ts, src/stores/accounts/accounts-actions.ts, src/stores/accounts/*test.ts
Account insertion can return a hydrated account, while import preserves identity fields, assigns a fresh ID, and avoids disposable credential generation.
Validated bulk history persistence
src/stores/accounts/accounts-database.ts, src/stores/accounts/*test.ts
Comments, votes, and edits are sanitized, validated, indexed, and replaced in bulk with associated metadata; export and empty-history cases are tested.
Limited imported-comment watcher initialization
src/stores/accounts/accounts-actions.ts, src/stores/accounts/accounts-actions.test.ts
Import starts update watchers only for the ten newest imported comments.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ImportAccount
  participant AccountsDatabase
  participant HistoryStorage
  ImportAccount->>AccountsDatabase: addAccount with returnHydratedAccount
  AccountsDatabase-->>ImportAccount: hydrated account
  ImportAccount->>AccountsDatabase: importAccountHistory
  AccountsDatabase->>HistoryStorage: replace sanitized comments, votes, and edits
  HistoryStorage-->>AccountsDatabase: indexed history
  AccountsDatabase-->>ImportAccount: imported history
  ImportAccount->>ImportAccount: initialize watchers for newest comments
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: improving account backup import performance in accounts.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/account-import-performance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc73be676f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +292 to +294
const existingAccountId = accountNamesToAccountIds?.[account.name];
if (existingAccountId && existingAccountId !== account.id) {
throw Error(`account name '${account.name}' already exists in database`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify stale name mappings before rejecting duplicates

When an existing account is renamed through setAccount, addAccount adds the new accountNamesToAccountIds entry but does not remove the old name entry. The previous duplicate-name check loaded the actual accounts and compared their current names, so a later createAccount/import using the vacated old name worked; this metadata-only check now treats that stale old-name mapping as a real duplicate and rejects the operation. Please either clean/rebuild the name map on rename or verify that the mapped account still has this name before throwing.

Useful? React with 👍 / 👎.

Comment on lines +650 to 654
const accountToImport = {
...imported.account,
communities,
id: generatedAccount.id,
id: uuid(),
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore default account fields during import

When importing an older backup that lacks fields now supplied by generateDefaultAccount (for example blockedAddresses, blockedCids, or subscriptions), this direct import no longer overlays those defaults before persisting the account. The imported account can then remain in store with undefined block maps, and paths such as useBlock/feed filtering index account.blockedAddresses[...] or account.blockedCids[...] directly, causing a runtime crash after an otherwise valid legacy backup import. Seed the imported account with current defaults or migrate missing fields before saving.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/stores/accounts/accounts-actions.ts`:
- Around line 644-671: Ensure importAccount does not leave a persisted account
when importAccountHistory fails: validate the imported history before addAccount
or, preferably, catch history-import failures and remove the newly created
account and associated metadata before rethrowing. Anchor the cleanup to the
account created by accountsDatabase.addAccount and the subsequent
importAccountHistory call, preserving successful imports. Add a regression test
covering the failure path and verifying the account is rolled back.

In `@src/stores/accounts/accounts-database.ts`:
- Around line 880-894: Update importAccountHistory so replacing comments, votes,
and edits is failure-safe: preserve each existing store and restore all prior
data/metadata if any replaceDatabaseArray operation fails, rather than allowing
Promise.all to leave partial results. Also explicitly document the public
method’s unconditional replacement behavior or reject calls for accounts with
existing history, preserving history unless replacement is intentional.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 441fa259-45dc-4ef3-ab86-4870d8764a4c

📥 Commits

Reviewing files that changed from the base of the PR and between 928afdc and fc73be6.

📒 Files selected for processing (4)
  • src/stores/accounts/accounts-actions.test.ts
  • src/stores/accounts/accounts-actions.ts
  • src/stores/accounts/accounts-database.test.ts
  • src/stores/accounts/accounts-database.ts

Comment thread src/stores/accounts/accounts-actions.ts Outdated
Comment thread src/stores/accounts/accounts-database.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4902118. Configure here.

Comment thread src/stores/accounts/accounts-database.ts
@tomcasaburi

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 7c2036fe38

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@tomcasaburi
tomcasaburi merged commit 036aace into master Jul 29, 2026
8 checks passed
@tomcasaburi
tomcasaburi deleted the fix/account-import-performance branch July 29, 2026 17:13
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