@@ -3959,7 +3959,29 @@ To add a GitHub workflow for building the runtime:
39593959 ??? interface "`basic.yml`"
39603960
39613961 ```yml
3962- Error fetching snippet from https://raw.githubusercontent.com/chevdor/srtool-actions/refs/heads/master/examples/01_basic.yml
3962+ name: Srtool build
3963+
3964+ on: push
3965+
3966+ jobs:
3967+ srtool:
3968+ runs-on: ubuntu-latest
3969+ strategy:
3970+ matrix:
3971+ chain: ["asset-hub-kusama", "asset-hub-westend"]
3972+ steps:
3973+ - uses: actions/checkout@v3
3974+ - name: Srtool build
3975+ id: srtool_build
3976+ 3977+ with:
3978+ chain: ${{ matrix.chain }}
3979+ runtime_dir: polkadot-parachains/${{ matrix.chain }}-runtime
3980+ - name: Summary
3981+ run: |
3982+ echo '${{ steps.srtool_build.outputs.json }}' | jq . > ${{ matrix.chain }}-srtool-digest.json
3983+ cat ${{ matrix.chain }}-srtool-digest.json
3984+ echo "Runtime location: ${{ steps.srtool_build.outputs.wasm }}"
39633985 ```
39643986
396539874. Modify the settings in the sample action
@@ -5555,7 +5577,111 @@ pub struct CurrentAndPreviousValue {
55555577
55565578- Migration:
55575579```rust
5558- Error fetching snippet from https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2409-1/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs
5580+ use frame_support::{
5581+ storage_alias,
5582+ traits::{Get, UncheckedOnRuntimeUpgrade},
5583+ };
5584+
5585+ #[cfg(feature = "try-runtime")]
5586+ use alloc::vec::Vec;
5587+
5588+ /// Collection of storage item formats from the previous storage version.
5589+ ///
5590+ /// Required so we can read values in the v0 storage format during the migration.
5591+ mod v0 {
5592+ use super::*;
5593+
5594+ /// V0 type for [`crate::Value`].
5595+ #[storage_alias]
5596+ pub type Value<T: crate::Config> = StorageValue<crate::Pallet<T>, u32>;
5597+ }
5598+
5599+ /// Implements [`UncheckedOnRuntimeUpgrade`], migrating the state of this pallet from V0 to V1.
5600+ ///
5601+ /// In V0 of the template [`crate::Value`] is just a `u32`. In V1, it has been upgraded to
5602+ /// contain the struct [`crate::CurrentAndPreviousValue`].
5603+ ///
5604+ /// In this migration, update the on-chain storage for the pallet to reflect the new storage
5605+ /// layout.
5606+ pub struct InnerMigrateV0ToV1<T: crate::Config>(core::marker::PhantomData<T>);
5607+
5608+ impl<T: crate::Config> UncheckedOnRuntimeUpgrade for InnerMigrateV0ToV1<T> {
5609+ /// Return the existing [`crate::Value`] so we can check that it was correctly set in
5610+ /// `InnerMigrateV0ToV1::post_upgrade`.
5611+ #[cfg(feature = "try-runtime")]
5612+ fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
5613+ use codec::Encode;
5614+
5615+ // Access the old value using the `storage_alias` type
5616+ let old_value = v0::Value::<T>::get();
5617+ // Return it as an encoded `Vec<u8>`
5618+ Ok(old_value.encode())
5619+ }
5620+
5621+ /// Migrate the storage from V0 to V1.
5622+ ///
5623+ /// - If the value doesn't exist, there is nothing to do.
5624+ /// - If the value exists, it is read and then written back to storage inside a
5625+ /// [`crate::CurrentAndPreviousValue`].
5626+ fn on_runtime_upgrade() -> frame_support::weights::Weight {
5627+ // Read the old value from storage
5628+ if let Some(old_value) = v0::Value::<T>::take() {
5629+ // Write the new value to storage
5630+ let new = crate::CurrentAndPreviousValue { current: old_value, previous: None };
5631+ crate::Value::<T>::put(new);
5632+ // One read + write for taking the old value, and one write for setting the new value
5633+ T::DbWeight::get().reads_writes(1, 2)
5634+ } else {
5635+ // No writes since there was no old value, just one read for checking
5636+ T::DbWeight::get().reads(1)
5637+ }
5638+ }
5639+
5640+ /// Verifies the storage was migrated correctly.
5641+ ///
5642+ /// - If there was no old value, the new value should not be set.
5643+ /// - If there was an old value, the new value should be a [`crate::CurrentAndPreviousValue`].
5644+ #[cfg(feature = "try-runtime")]
5645+ fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
5646+ use codec::Decode;
5647+ use frame_support::ensure;
5648+
5649+ let maybe_old_value = Option::<u32>::decode(&mut &state[..]).map_err(|_| {
5650+ sp_runtime::TryRuntimeError::Other("Failed to decode old value from storage")
5651+ })?;
5652+
5653+ match maybe_old_value {
5654+ Some(old_value) => {
5655+ let expected_new_value =
5656+ crate::CurrentAndPreviousValue { current: old_value, previous: None };
5657+ let actual_new_value = crate::Value::<T>::get();
5658+
5659+ ensure!(actual_new_value.is_some(), "New value not set");
5660+ ensure!(
5661+ actual_new_value == Some(expected_new_value),
5662+ "New value not set correctly"
5663+ );
5664+ },
5665+ None => {
5666+ ensure!(crate::Value::<T>::get().is_none(), "New value unexpectedly set");
5667+ },
5668+ };
5669+ Ok(())
5670+ }
5671+ }
5672+
5673+ /// [`UncheckedOnRuntimeUpgrade`] implementation [`InnerMigrateV0ToV1`] wrapped in a
5674+ /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), which ensures that:
5675+ /// - The migration only runs once when the on-chain storage version is 0
5676+ /// - The on-chain storage version is updated to `1` after the migration executes
5677+ /// - Reads/Writes from checking/settings the on-chain storage version are accounted for
5678+ pub type MigrateV0ToV1<T> = frame_support::migrations::VersionedMigration<
5679+ 0, // The migration will only execute when the on-chain storage version is 0
5680+ 1, // The on-chain storage version will be set to 1 after the migration is complete
5681+ InnerMigrateV0ToV1<T>,
5682+ crate::pallet::Pallet<T>,
5683+ <T as frame_system::Config>::DbWeight,
5684+ >;
55595685```
55605686
55615687### Migration Organization
0 commit comments