referrerpolicy=no-referrer-when-downgrade

polkadot_sdk_docs/reference_docs/
frame_runtime_upgrades_and_migrations.rs

1//! # Runtime Upgrades
2//!
3//! At their core, blockchain logic consists of
4//!
5//! 1. on-chain state,
6//! 2. a state transition function.
7//!
8//! In Substrate-based blockchains, state transition functions are referred to as
9//! [runtimes](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html).
10//!
11//! Traditionally, before Substrate, upgrading state transition functions required node
12//! operators to download new software and restart their nodes in a process called
13//! [forking](https://en.wikipedia.org/wiki/Fork_(blockchain)).
14//!
15//! Substrate-based blockchains do not require forking, and instead upgrade runtimes
16//! in a process called "Runtime Upgrades".
17//!
18//! Forkless runtime upgrades are a defining feature of the Substrate framework. Updating the
19//! runtime logic without forking the code base enables your blockchain to seamlessly evolve
20//! over time in a deterministic, rules-based manner. It also removes ambiguity for node operators
21//! and other participants in the network about what is the canonical runtime.
22//!
23//! This capability is possible due to the runtime of a blockchain existing in on-chain storage.
24//!
25//! ## Performing a Runtime Upgrade
26//!
27//! To upgrade a runtime, an [`Origin`](frame_system::RawOrigin) with the necessary permissions
28//! (usually via governance) changes the `:code` storage. Usually, this is performed via a call to
29//! [`set_code`] (or [`set_code_without_checks`]) with the desired new runtime blob, scheduled
30//! using [`pallet_scheduler`].
31//!
32//! Prior to building the new runtime, don't forget to update the
33//! [`RuntimeVersion`](sp_version::RuntimeVersion).
34//!
35//! # Migrations
36//!
37//! It is often desirable to define logic to execute immediately after runtime upgrades (see
38//! [this diagram](frame::traits::Hooks)).
39//!
40//! Self-contained pieces of logic that execute after a runtime upgrade are called "Migrations".
41//!
42//! The typical use case of a migration is to 'migrate' pallet storage from one layout to another,
43//! for example when the encoding of a storage item is changed. However, they can also execute
44//! arbitrary logic such as:
45//!
46//! - Calling arbitrary pallet methods.
47//! - Mutating arbitrary on-chain state.
48//! - Cleaning up some old storage items that are no longer needed.
49//!
50//! ## Single Block Migrations
51//!
52//! - Execute immediately and entirely at the beginning of the block following
53//! a runtime upgrade.
54//! - Are suitable for migrations which are guaranteed to not exceed the block weight.
55//! - Are simply implementations of [`OnRuntimeUpgrade`].
56//!
57//! To learn best practices for writing single block pallet storage migrations, see the
58//! [Single Block Migration Example Pallet](pallet_example_single_block_migrations).
59//!
60//! ### Scheduling the Single Block Migrations to Run Next Runtime Upgrade
61//!
62//! Schedule migrations to run next runtime upgrade passing them as a parameter to your
63//! [`Config`](frame_system) pallet:
64//!
65//! ```ignore
66//! /// Tuple of migrations (structs that implement `OnRuntimeUpgrade`)
67//! type Migrations = (
68//! 	pallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1,
69//! 	MyCustomMigration,
70//! 	// ...more migrations here
71//! );
72//! impl frame_system::Config for Runtime {
73//! 	type SingleBlockMigrations = Migrations;
74//! }
75//! ```
76//!
77//! ### Ensuring Single Block Migration Safety
78//!
79//! "My migration unit tests pass, so it should be safe to deploy right?"
80//!
81//! No! Unit tests execute the migration in a very simple test environment, and cannot account
82//! for the complexities of a real runtime or real on-chain state.
83//!
84//! Prior to deploying migrations, it is critical to perform additional checks to ensure that when
85//! run in our real runtime they will not brick the chain due to:
86//! - Panicking.
87//! - Touching too many storage keys and resulting in an excessively large PoV.
88//! - Taking too long to execute.
89//!
90//! [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) has a sub-command
91//! [`on-runtime-upgrade`](https://paritytech.github.io/try-runtime-cli/try_runtime_core/commands/enum.Action.html#variant.OnRuntimeUpgrade)
92//! which is designed to help with exactly this.
93//!
94//! Developers MUST run this command before deploying migrations to ensure they will not
95//! inadvertently result in a bricked chain.
96//!
97//! It is recommended to run as part of your CI pipeline. See the
98//! [polkadot-sdk check-runtime-migration job](https://github.com/paritytech/polkadot-sdk/blob/4a293bc5a25be637c06ce950a34490706597615b/.gitlab/pipeline/check.yml#L103-L124)
99//! for an example of how to configure this.
100//!
101//! ### Note on the Manipulability of PoV Size and Execution Time
102//!
103//! While [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) can help ensure with
104//! very high certainty that a migration will succeed given **existing** on-chain state, it cannot
105//! prevent a malicious actor from manipulating state in a way that will cause the migration to take
106//! longer or produce a PoV much larger than previously measured.
107//!
108//! Therefore, it is important to write migrations in such a way that the execution time or PoV size
109//! it adds to the block cannot be easily manipulated. e.g., do not iterate over storage that can
110//! quickly or cheaply be bloated.
111//!
112//! If writing your migration in such a way is not possible, a multi block migration should be used
113//! instead.
114//!
115//! ### Other useful tools
116//!
117//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Substrate
118//! ecosystem which developers may find useful to use in addition to `try-runtime-cli` when testing
119//! their single block migrations.
120//!
121//! ## Multi Block Migrations
122//!
123//! Safely and easily execute long-running migrations across multiple blocks.
124//!
125//! Suitable for migrations which could use arbitrary amounts of block weight.
126//!
127//! See the
128//! [multi-block-migrations example](https://github.com/paritytech/polkadot-sdk/tree/0d7d2177807ec6b3094f4491a45b0bc0d74d3c8b/substrate/frame/examples/multi-block-migrations)
129//! for reference.
130//!
131//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade
132//! [`StorageVersion`]: frame_support::traits::StorageVersion
133//! [`set_code`]: frame_system::Call::set_code
134//! [`set_code_without_checks`]: frame_system::Call::set_code_without_checks