mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 13:27:57 +00:00
Runtime Upgrade ref docs and Single Block Migration example pallet (#1554)
Closes https://github.com/paritytech/polkadot-sdk-docs/issues/55 - Changes 'current storage version' terminology to less ambiguous 'in-code storage version' (suggestion by @ggwpez) - Adds a new example pallet `pallet-example-single-block-migrations` - Adds a new reference doc to replace https://docs.substrate.io/maintain/runtime-upgrades/ (temporarily living in the pallet while we wait for developer hub PR to merge) - Adds documentation for the `storage_alias` macro - Improves `trait Hooks` docs - Improves `trait GetStorageVersion` docs - Update the suggested patterns for using `VersionedMigration`, so that version unchecked migrations are never exported - Prevents accidental usage of version unchecked migrations in runtimes https://github.com/paritytech/substrate/pull/14421#discussion_r1255467895 - Unversioned migration code is kept inside `mod version_unchecked`, versioned code is kept in `pub mod versioned` - It is necessary to use modules to limit visibility because the inner migration must be `pub`. See https://github.com/rust-lang/rust/issues/30905 and https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40 for more. ### todo - [x] move to reference docs to proper place within sdk-docs (now that https://github.com/paritytech/polkadot-sdk/pull/2102 is merged) - [x] prdoc --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Juan <juangirini@gmail.com> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: command-bot <> Co-authored-by: gupnik <nikhilgupta.iitk@gmail.com>
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
//! # Runtime Runtime Upgrade and Testing
|
||||
//!
|
||||
//!
|
||||
//! Notes:
|
||||
//!
|
||||
//! - Flow of things, when does `on_runtime_upgrade` get called. Link to to `Hooks` and its diagram
|
||||
//! as source of truth.
|
||||
//! - Data migration and when it is needed.
|
||||
//! - Look into the pba-lecture.
|
||||
@@ -0,0 +1,138 @@
|
||||
//! # Runtime Upgrades
|
||||
//!
|
||||
//! At their core, blockchain logic consists of
|
||||
//!
|
||||
//! 1. on-chain state and
|
||||
//! 2. a state transition function
|
||||
//!
|
||||
//! In Substrate-based blockchains, state transition functions are referred to as
|
||||
//! [runtimes](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html).
|
||||
//!
|
||||
//! Traditionally, before Substrate, upgrading state transition functions required node
|
||||
//! operators to download new software and restart their nodes in a process called
|
||||
//! [forking](https://en.wikipedia.org/wiki/Fork_(blockchain)).
|
||||
//!
|
||||
//! Substrate-based blockchains do not require forking, and instead upgrade runtimes
|
||||
//! in a process called "Runtime Upgrades".
|
||||
//!
|
||||
//! Forkless runtime upgrades are a defining feature of the Substrate framework. Updating the
|
||||
//! runtime logic without forking the code base enables your blockchain to seemlessly evolve
|
||||
//! over time in a deterministic, rules-based manner. It also removes ambiguity for node operators
|
||||
//! and other participants in the network about what is the canonical runtime.
|
||||
//!
|
||||
//! This capability is possible due to the runtime of a blockchain existing in on-chain storage.
|
||||
//!
|
||||
//! ## Performing a Runtime Upgrade
|
||||
//!
|
||||
//! To upgrade a runtime, an [`Origin`](frame_system::RawOrigin) with the necesarry permissions
|
||||
//! (usually via governance) changes the `:code` storage. Usually, this is performed via a call to
|
||||
//! [`set_code`] (or [`set_code_without_checks`]) with the desired new runtime blob, scheduled
|
||||
//! using [`pallet_scheduler`].
|
||||
//!
|
||||
//! Prior to building the new runtime, don't forget to update the
|
||||
//! [`RuntimeVersion`](sp_version::RuntimeVersion).
|
||||
//!
|
||||
//! # Migrations
|
||||
//!
|
||||
//! It is often desirable to define logic to execute immediately after runtime upgrades (see
|
||||
//! [this diagram](frame::traits::Hooks)).
|
||||
//!
|
||||
//! Self-contained pieces of logic that execute after a runtime upgrade are called "Migrations".
|
||||
//!
|
||||
//! The typical use case of a migration is to 'migrate' pallet storage from one layout to another,
|
||||
//! for example when the encoding of a storage item is changed. However, they can also execute
|
||||
//! arbitary logic such as:
|
||||
//!
|
||||
//! - Calling arbitrary pallet methods
|
||||
//! - Mutating arbitrary on-chain state
|
||||
//! - Cleaning up some old storage items that are no longer needed
|
||||
//!
|
||||
//! ## Single Block Migrations
|
||||
//!
|
||||
//! - Execute immediately and entirely at the beginning of the block following
|
||||
//! a runtime upgrade.
|
||||
//! - Are suitable for migrations which are guaranteed to not exceed the block weight.
|
||||
//! - Are simply implementations of [`OnRuntimeUpgrade`].
|
||||
//!
|
||||
//! To learn best practices for writing single block pallet storage migrations, see the
|
||||
//! [Single Block Migration Example Pallet](pallet_example_single_block_migrations).
|
||||
//!
|
||||
//! ### Scheduling the Single Block Migrations to Run Next Runtime Upgrade
|
||||
//!
|
||||
//! Schedule migrations to run next runtime upgrade passing them as a generic parameter to your
|
||||
//! [`Executive`](frame_executive) pallet:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! /// Tuple of migrations (structs that implement `OnRuntimeUpgrade`)
|
||||
//! type Migrations = (
|
||||
//! pallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1,
|
||||
//! MyCustomMigration,
|
||||
//! // ...more migrations here
|
||||
//! );
|
||||
//! pub type Executive = frame_executive::Executive<
|
||||
//! Runtime,
|
||||
//! Block,
|
||||
//! frame_system::ChainContext<Runtime>,
|
||||
//! Runtime,
|
||||
//! AllPalletsWithSystem,
|
||||
//! Migrations, // <-- pass your migrations to Executive here
|
||||
//! >;
|
||||
//! ```
|
||||
//!
|
||||
//! ### Ensuring Single Block Migration Safety
|
||||
//!
|
||||
//! "My migration unit tests pass, so it should be safe to deploy right?"
|
||||
//!
|
||||
//! No! Unit tests execute the migration in a very simple test environment, and cannot account
|
||||
//! for the complexities of a real runtime or real on-chain state.
|
||||
//!
|
||||
//! Prior to deploying migrations, it is critical to perform additional checks to ensure that when
|
||||
//! run in our real runtime they will not brick the chain due to:
|
||||
//! - Panicing
|
||||
//! - Touching too many storage keys and resulting in an excessively large PoV
|
||||
//! - Taking too long to execute
|
||||
//!
|
||||
//! [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) has a sub-command
|
||||
//! [`on-runtime-upgrade`](https://paritytech.github.io/try-runtime-cli/try_runtime_core/commands/enum.Action.html#variant.OnRuntimeUpgrade)
|
||||
//! which is designed to help with exactly this.
|
||||
//!
|
||||
//! Developers MUST run this command before deploying migrations to ensure they will not
|
||||
//! inadvertently result in a bricked chain.
|
||||
//!
|
||||
//! It is recommended to run as part of your CI pipeline. See the
|
||||
//! [polkadot-sdk check-runtime-migration job](https://github.com/paritytech/polkadot-sdk/blob/4a293bc5a25be637c06ce950a34490706597615b/.gitlab/pipeline/check.yml#L103-L124)
|
||||
//! for an example of how to configure this.
|
||||
//!
|
||||
//! ### Note on the Manipulability of PoV Size and Execution Time
|
||||
//!
|
||||
//! While [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) can help ensure with
|
||||
//! very high certainty that a migration will succeed given **existing** on-chain state, it cannot
|
||||
//! prevent a malicious actor from manipulating state in a way that will cause the migration to take
|
||||
//! longer or produce a PoV much larger than previously measured.
|
||||
//!
|
||||
//! Therefore, it is important to write migrations in such a way that the execution time or PoV size
|
||||
//! it adds to the block cannot be easily manipulated. e.g., do not iterate over storage that can
|
||||
//! quickly or cheaply be bloated.
|
||||
//!
|
||||
//! If writing your migration in such a way is not possible, a multi block migration should be used
|
||||
//! instead.
|
||||
//!
|
||||
//! ### Other useful tools
|
||||
//!
|
||||
//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Substrate
|
||||
//! ecosystem which developers may find useful to use in addition to `try-runtime-cli` when testing
|
||||
//! their single block migrations.
|
||||
//!
|
||||
//! ## Multi Block Migrations
|
||||
//!
|
||||
//! Safely and easily execute long-running migrations across multiple blocks.
|
||||
//!
|
||||
//! Suitable for migrations which could use arbitrary amounts of block weight.
|
||||
//!
|
||||
//! TODO: Link to multi block migration example/s once PR is merged (<https://github.com/paritytech/polkadot-sdk/pull/2119>).
|
||||
//!
|
||||
//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion
|
||||
//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade
|
||||
//! [`StorageVersion`]: frame_support::traits::StorageVersion
|
||||
//! [`set_code`]: frame_system::Call::set_code
|
||||
//! [`set_code_without_checks`]: frame_system::Call::set_code_without_checks
|
||||
@@ -92,9 +92,8 @@ pub mod cli;
|
||||
// TODO: @JoshOrndorff @kianenigma https://github.com/paritytech/polkadot-sdk-docs/issues/54
|
||||
pub mod consensus_swapping;
|
||||
|
||||
/// Learn about all the advance ways to test your coordinate a rutnime upgrade and data migration.
|
||||
// TODO: @liamaharon https://github.com/paritytech/polkadot-sdk-docs/issues/55
|
||||
pub mod frame_runtime_migration;
|
||||
/// Learn about Runtime Upgrades and best practices for writing Migrations.
|
||||
pub mod frame_runtime_upgrades_and_migrations;
|
||||
|
||||
/// Learn about light nodes, how they function, and how Substrate-based chains come
|
||||
/// light-node-first out of the box.
|
||||
|
||||
Reference in New Issue
Block a user