Skip to main content

Module migrate

Module migrate 

Source
Expand description

Schema-epoch in-place migration runtime.

Schema epochs and in-place migration helpers use the header’s schema_epoch: u32, which lets accounts self-identify the ABI version they were written in. When a program later loads an account written at an older epoch, the runtime consults a declared migration chain, applies each edge in sequence atomically with a schema_epoch bump, and only then hands the caller a typed Ref<'_, T> of the current shape.

§Design rules

  • In-place. no allocation, no CPI. Migration rewrites the account body (within its existing byte range) and the 16-byte Hopper header.
  • Atomic per edge under transaction-abort semantics. Each edge bumps the header’s schema_epoch only after its body mutation fully succeeded, so a completed edge is always consistent. A migrator that errors after partially writing the body, however, leaves a hybrid body under the old epoch. The returned error must propagate to instruction failure (the Solana runtime then rolls every byte back). Callers must not swallow migration errors and continue using the account.
  • Idempotent. re-running an already-applied edge is a no-op (the header epoch mismatch returns MigrationMismatch).
  • Deterministic. edges are applied in strict

Structs§

MigrationEdge
One step in a layout’s migration chain.

Traits§

LayoutMigration
Layouts opt into in-place migration by providing a MIGRATIONS constant. The default (empty slice) means “no migrations declared” and any mismatch between header and AccountLayout::SCHEMA_EPOCH is a hard failure.

Functions§

apply_pending_migrations
Apply all pending migrations needed to bring the account at current_epoch up to AccountLayout::SCHEMA_EPOCH.
ensure_fits_with_rent
Grow account to at least min_len bytes, topping up the rent-exempt minimum (from the LIVE rent sysvar) out of payer when the account’s balance falls short, the payer must then be writable and a signer; a well-funded account needs no payer at all. A no-op when the allocation already fits. Growth is capped by Solana’s MAX_PERMITTED_DATA_INCREASE, enforced by resize.
migrate_layout
Typed, in-place, cross-VERSION layout migration: Old → New.
migrate_layout_resizing
migrate_layout that resizes the account to fit the new shape, with a payer-funded rent top-up, the one migration capability the in-place form defers to a separate realloc.
validate_header_for_epoch_migration
Header identity check for an epoch-migration candidate: disc, version, and layout id must match T exactly and the allocation must fit T, while the stored schema epoch may LAG T::SCHEMA_EPOCH, that lag is exactly what the epoch chain heals, but may never exceed it (a from-the-future account is refused, never “migrated”). Returns the stored EFFECTIVE epoch (a pre-epoch zero header reads as epoch 1).