feat: preserve stores on schema version or rollup address change#24631
Open
mverzilli wants to merge 25 commits into
Open
feat: preserve stores on schema version or rollup address change#24631mverzilli wants to merge 25 commits into
mverzilli wants to merge 25 commits into
Conversation
Replaces wipe-on-mismatch with store selection keyed on (l1ChainId, rollupAddress, schemaVersion) for both PXE backends.
…) identity instead of wiped
…ress first boot Gate the schema-mismatch throw on a successfully parsed version file so a first boot with a zero rollup address (storedVersion (0, ZERO) vs (N, ZERO)) resets and opens instead of throwing forever. Split rollup-address mismatch handling into its own RollupAddressMismatchPolicy (default 'reset') so the validator HA signer keeps silent reset-on-rollup-change while schema mismatches stay fail-closed. For partitioned lmdb-v2 stores, use a sibling '<name>-stores' directory instead of nesting inside the legacy env dir, so an old binary's rollup-mismatch rm -rf of the legacy dir cannot destroy per-identity stores; force all three mismatch policies to 'throw' when partitionByIdentity is set.
… layout Update the database-version README reset conditions, the store-selection design doc (sibling <name>-stores layout, three throw policies, HA-signer reset default), and the migration note (ts fence, per-backend on-disk data location).
…let data-root constant
mverzilli
commented
Jul 9, 2026
Comment on lines
+14
to
+16
| Previously, connecting a PXE or embedded wallet to a different or redeployed rollup, or bumping the store schema version, wiped the existing on-disk store in place. That meant master account keys could be destroyed simply by pointing a wallet at a different network. A store now exists per `(l1ChainId, rollupAddress, schemaVersion)` identity, and switching networks (or upgrading) selects the matching store instead of overwriting the previous one. | ||
|
|
||
| **Impact**: The first start after upgrading to this version begins with a fresh, empty store; the pre-upgrade data is not deleted. In the browser (sqlite-opfs) the old store stays in OPFS but is not visible to the new `listStores()` utility; on node (lmdb-v2) pre-upgrade data stays at `<dataDirectory>/<name>` while new per-identity stores live under `<dataDirectory>/<name>-stores/`. That covers the server PXE and the CLI wallet; the embedded node wallet previously stored data in cwd-relative, rollup-address-suffixed directories instead (`pxe_data_<rollupAddress>/pxe_data` for the PXE store, `wallet_data_<rollupAddress>/wallet_data` for the wallet store): if you used it before this release, that is where your old data lives. The embedded wallet now defaults its data root to `aztec-wallet-data/`. Browser apps can enumerate and clean up stores for networks no longer in use with the new `listStores()` / `deleteStore()` utilities: |
Contributor
Author
There was a problem hiding this comment.
Suggested change
| Previously, connecting a PXE or embedded wallet to a different or redeployed rollup, or bumping the store schema version, wiped the existing on-disk store in place. That meant master account keys could be destroyed simply by pointing a wallet at a different network. A store now exists per `(l1ChainId, rollupAddress, schemaVersion)` identity, and switching networks (or upgrading) selects the matching store instead of overwriting the previous one. | |
| **Impact**: The first start after upgrading to this version begins with a fresh, empty store; the pre-upgrade data is not deleted. In the browser (sqlite-opfs) the old store stays in OPFS but is not visible to the new `listStores()` utility; on node (lmdb-v2) pre-upgrade data stays at `<dataDirectory>/<name>` while new per-identity stores live under `<dataDirectory>/<name>-stores/`. That covers the server PXE and the CLI wallet; the embedded node wallet previously stored data in cwd-relative, rollup-address-suffixed directories instead (`pxe_data_<rollupAddress>/pxe_data` for the PXE store, `wallet_data_<rollupAddress>/wallet_data` for the wallet store): if you used it before this release, that is where your old data lives. The embedded wallet now defaults its data root to `aztec-wallet-data/`. Browser apps can enumerate and clean up stores for networks no longer in use with the new `listStores()` / `deleteStore()` utilities: | |
| Previously, connecting a PXE or embedded wallet to a different or redeployed rollup, or bumping the store schema version, wiped the existing on-disk store in place. That meant master account keys could be destroyed simply by pointing a wallet at a different network. A store now exists per `(l1ChainId, rollupAddress, schemaVersion)` identity, and switching networks (or upgrading) selects the matching store instead of overwriting the previous one. | |
| **Impact**: The first start after upgrading to this version begins with a fresh, empty store; the pre-upgrade data is not deleted. On Node.js environments (lmdb-v2) pre-upgrade data stays at `<dataDirectory>/<name>` while new per-identity stores live under `<dataDirectory>/<name>-stores/`. The embedded Node.js wallet previously stored data in cwd-relative, rollup-address-suffixed directories instead (`pxe_data_<rollupAddress>/pxe_data` for the PXE store, `wallet_data_<rollupAddress>/wallet_data` for the wallet store): if you used it before this release, that is where your old data lives. The embedded wallet now defaults its data root to `aztec-wallet-data/`. Browser apps can enumerate and clean up stores for networks no longer in use with the new `listStores()` / `deleteStore()` utilities: |
mverzilli
commented
Jul 9, 2026
| import { deleteStore, listStores } from '@aztec/kv-store/sqlite-opfs'; | ||
|
|
||
| const names = await listStores(); | ||
| await deleteStore(names[0]); // the store must be closed first |
Contributor
Author
There was a problem hiding this comment.
Suggested change
| await deleteStore(names[0]); // the store must be closed first | |
| await deleteStore(names[0]); |
mverzilli
commented
Jul 9, 2026
Comment on lines
+51
to
+52
| * Belt-and-braces invariant check: the identity is part of the physical store name, so the recorded version | ||
| * can only disagree if there is a store-naming bug. Refuses to open on mismatch; never clears. |
Contributor
Author
There was a problem hiding this comment.
Suggested change
| * Belt-and-braces invariant check: the identity is part of the physical store name, so the recorded version | |
| * can only disagree if there is a store-naming bug. Refuses to open on mismatch; never clears. | |
| * Invariant check: the identity is part of the physical store name, so the recorded version can only | |
| * disagree if there is a store-naming bug. Refuses to open on mismatch. |
…ng to zero Opening a persistent sqlite-opfs store (or composing its identity slug) with a missing l1ChainId, rollupAddress, or schemaVersion silently fell back to the zero identity, which could route two logically different callers to the same physical store. Require the full identity and throw instead. Files: yarn-project/kv-store/src/store_identity.ts, yarn-project/kv-store/src/store_identity.test.ts, yarn-project/kv-store/src/sqlite-opfs/index.ts, yarn-project/kv-store/src/sqlite-opfs/create_store.test.ts
IdentityStoreConfig previously allowed l1ChainId and rollupAddress to be omitted, in which case the identity-partitioned store fell back to the zero identity. Make both fields required so callers can no longer open a PXE data store without a complete identity. Files: yarn-project/pxe/src/entrypoints/server/store.ts, yarn-project/pxe/src/entrypoints/server/utils.ts, yarn-project/pxe/src/entrypoints/server/store.test.ts
…tity The embedded wallet's wallet_data store held account secrets and aliases, which are not tied to any particular network, yet it was keyed by (l1ChainId, rollupAddress, schemaVersion) like the PXE data store. That meant switching networks silently swapped in a different (empty) wallet store. Key wallet_data by schema version alone (wallet_data_v1) so it stays the same store across networks. Files: yarn-project/wallets/src/embedded/wallet_db.ts, yarn-project/wallets/src/embedded/entrypoints/node.ts, yarn-project/wallets/src/embedded/entrypoints/browser.ts
…note Files: docs/docs-developers/docs/resources/migration_notes.md
…wallet_data_v1 location
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
(wip)
Closes F-809