Skip to content

Add storage migration framework with versioned schema keys - #568

Merged
Kingsman-99 merged 2 commits into
Stellar-split:mainfrom
edwarddavid929-png:feat/storage-migration-framework
Jul 30, 2026
Merged

Add storage migration framework with versioned schema keys#568
Kingsman-99 merged 2 commits into
Stellar-split:mainfrom
edwarddavid929-png:feat/storage-migration-framework

Conversation

@edwarddavid929-png

Copy link
Copy Markdown
Contributor

Introduce a schema_version (u32, instance storage) that tracks the contract's on-chain storage shape, plus a SuperAdmin-only migrate() entry point that runs any pending migration_vN steps in order and bumps the version once each transformation completes.

Every entry point that funnels through the shared guard helpers (require_admin, require_admin_role, require_not_paused, check_not_paused, require_not_frozen) now panics with "MigrationRequired" while schema_version is behind the version the current Wasm build expects. migrate() is the only entry point exempt, since it is what performs the upgrade; it authenticates via a new schema-guard-free require_admin_role_unguarded helper to avoid a bootstrapping deadlock. pause/unpause/add_allowed_token/ remove_allowed_token inline their own admin check rather than calling the shared helpers, so they get an explicit guard call too. Fresh deployments stamp schema_version at CURRENT_SCHEMA_VERSION during initialize(), since there is no legacy data to migrate.

Two concrete migrations demonstrate the mechanics end-to-end: v1->v2 backfills a new per-invoice InvoiceMeta note record for every existing invoice, and v2->v3 renames that record's storage key. Added integration tests simulate a contract rolled back to v1 (as a stand-in for one upgraded from an older Wasm build) and walk it through migrate() to the current schema, checking that guarded entry points are blocked beforehand and that invoice data survives the upgrade.
Closes #350

edwarddavid929-png and others added 2 commits July 30, 2026 01:15
Introduce a schema_version (u32, instance storage) that tracks the
contract's on-chain storage shape, plus a SuperAdmin-only migrate()
entry point that runs any pending migration_vN steps in order and
bumps the version once each transformation completes.

Every entry point that funnels through the shared guard helpers
(require_admin, require_admin_role, require_not_paused,
check_not_paused, require_not_frozen) now panics with
"MigrationRequired" while schema_version is behind the version the
current Wasm build expects. migrate() is the only entry point exempt,
since it is what performs the upgrade; it authenticates via a new
schema-guard-free require_admin_role_unguarded helper to avoid a
bootstrapping deadlock. pause/unpause/add_allowed_token/
remove_allowed_token inline their own admin check rather than calling
the shared helpers, so they get an explicit guard call too. Fresh
deployments stamp schema_version at CURRENT_SCHEMA_VERSION during
initialize(), since there is no legacy data to migrate.

Two concrete migrations demonstrate the mechanics end-to-end:
v1->v2 backfills a new per-invoice InvoiceMeta note record for every
existing invoice, and v2->v3 renames that record's storage key. Added
integration tests simulate a contract rolled back to v1 (as a stand-in
for one upgraded from an older Wasm build) and walk it through
migrate() to the current schema, checking that guarded entry points
are blocked beforehand and that invoice data survives the upgrade.
@Kingsman-99
Kingsman-99 merged commit aa89dbf into Stellar-split:main Jul 30, 2026
1 of 4 checks passed
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.

Implement a storage migration framework with versioned schema keys

2 participants