From e547869cf217381d0689eac6f58c84a7d3313631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=CC=81=20Molina?= Date: Tue, 19 Sep 2023 01:56:53 +0200 Subject: [PATCH] feat: add hooks --- Cargo.lock | 99 ++++++++++++++------------- Cargo.toml | 11 +-- README.md | 77 +++++++++++++++++++++ procedural/Cargo.toml | 3 +- procedural/src/lib.rs | 156 ++++++++++++++++++++++++++++++++++-------- src/lib.rs | 11 ++- 6 files changed, 266 insertions(+), 91 deletions(-) create mode 100644 README.md diff --git a/Cargo.lock b/Cargo.lock index ff0cd68..7ded717 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" dependencies = [ "memchr", ] @@ -130,7 +130,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -187,6 +187,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "bitvec" version = "1.0.1" @@ -577,9 +583,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "ecdsa" @@ -698,7 +704,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -761,7 +767,7 @@ name = "frame-support" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "environmental", "frame-metadata", "frame-support-procedural", @@ -805,7 +811,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -817,7 +823,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -827,7 +833,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0 dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -918,7 +924,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1329,9 +1335,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -1367,7 +1373,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1381,7 +1387,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1392,7 +1398,7 @@ checksum = "c12469fc165526520dff2807c2975310ab47cf7190a45b99b49a7dc8befab17b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1403,7 +1409,7 @@ checksum = "b8fb85ec1620619edf2984a7693497d4ec88a9665d8b87e942856884c92dbf2a" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1423,11 +1429,11 @@ checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memfd" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.37.23", + "rustix 0.38.13", ] [[package]] @@ -1465,18 +1471,13 @@ name = "migratable" version = "0.0.1" dependencies = [ "frame-support", - "frame-support-procedural", "frame-system", "impl-trait-for-tuples", "log", "migratable-procedural", "parity-scale-codec", - "proc-macro-crate", - "proc-macro2", - "quote", "sp-runtime", "sp-std", - "syn 2.0.35", ] [[package]] @@ -1485,7 +1486,8 @@ version = "0.0.1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "sp-std", + "syn 2.0.37", ] [[package]] @@ -1722,7 +1724,7 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1835,7 +1837,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1855,7 +1857,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -1936,7 +1938,7 @@ version = "0.36.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", @@ -1946,15 +1948,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", + "linux-raw-sys 0.4.7", "windows-sys 0.48.0", ] @@ -2089,7 +2090,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2221,7 +2222,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2257,7 +2258,7 @@ version = "21.0.0" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" dependencies = [ "array-bytes", - "bitflags", + "bitflags 1.3.2", "blake2", "bounded-collections", "bs58", @@ -2316,7 +2317,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0 dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2326,7 +2327,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0 dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2461,7 +2462,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2577,7 +2578,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2677,9 +2678,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.35" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bf04c28bee9043ed9ea1e41afc0552288d3aba9c6efdd78903b802926f4879" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -2715,7 +2716,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -2808,7 +2809,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] [[package]] @@ -3005,7 +3006,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", "wasm-bindgen-shared", ] @@ -3027,7 +3028,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3378,5 +3379,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.35", + "syn 2.0.37", ] diff --git a/Cargo.toml b/Cargo.toml index e11b62d..34711a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,15 +12,10 @@ description = "Library for performing storage migrations in Substrate pallets" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -syn = "2.0.32" -proc-macro2 = "1.0.64" -quote = "1.0.33" -proc-macro-crate = "1.3.1" -log = { version = "0.4", default-features = false } -codec = { package = "parity-scale-codec", version = "3.6.5", default-features = false, features = ["derive", "max-encoded-len"] } +log = "0.4" +parity-scale-codec = { version = "3.6", default-features = false, features = ["derive", "max-encoded-len"] } migratable-procedural = { path = "./procedural", default-features = false } frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } -frame-support-procedural = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } @@ -29,7 +24,7 @@ impl-trait-for-tuples = "0.2" [features] default = ["std"] std = [ - "codec/std", + "parity-scale-codec/std", "frame-support/std", "frame-system/std", "sp-runtime/std", diff --git a/README.md b/README.md new file mode 100644 index 0000000..c78ba07 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Migratable + +This project is a library used to have `pallet-contracts`-like migration schema for Substrate pallets. + + +## Setup + +1) Add the following statements: + - `#[migratable::pallet]` in the pallet's module. + - `#[migratable::config]` in the pallet's configuration. + - `#[migratable::hooks]` in the pallet's hooks. + +2) Implement the following hooks. They can be left empty: + - `on_idle`. + - `integrity_test`. + +3) Make sure you add the corresponding storage version with the `#[pallet::storage_version()]` statement. + +```rust +#[migratable::pallet] +#[frame_support::pallet] +pub mod pallet { + // -- snip -- + + #[migratable::config] + #[pallet::config] + pub trait Config: frame_system::Config { + // -- snip -- + } + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[migratable::hooks] + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_idle(_block: BlockNumberFor, mut _remaining_weight: Weight) -> Weight { + Weight::zero() + } + fn integrity_test() {} + } +} +``` + +4) When instantiating the pallet, make sure to add the migrations that apply. Some examples [here](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/contracts/src/migration). + +```rust +impl my_pallet::Config for Runtime { + // -- snip -- + + type Migrations = ( + my_pallet::migration::v2::Migration, + my_pallet::migration::v3::Migration, + my_pallet::migration::v4::Migration, + // add as many as needed + ); +} +``` + +5) Add the pallet's `Migration` struct to `Executive`: + +```rust +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + // make sure to add here the migration + ( + my_pallet::pallet::Migration, + ), +>; +``` \ No newline at end of file diff --git a/procedural/Cargo.toml b/procedural/Cargo.toml index 3081573..408235e 100644 --- a/procedural/Cargo.toml +++ b/procedural/Cargo.toml @@ -15,6 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -syn = { version = "2.0.32", features = ["full"] } +syn = { version = "2.0", features = ["full"] } proc-macro2 = "1.0.64" quote = "1.0.33" +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } diff --git a/procedural/src/lib.rs b/procedural/src/lib.rs index 4171bcb..737728e 100644 --- a/procedural/src/lib.rs +++ b/procedural/src/lib.rs @@ -1,22 +1,124 @@ -use quote::quote; -use syn::{parse_quote, parse_macro_input}; +use quote::{quote, ToTokens}; +use syn::{parse_macro_input, parse_quote}; + +const ON_IDLE_HOOK: &str = "on_idle"; +const INTEGRITY_TEST_HOOK: &str = "integrity_test"; + +#[proc_macro_attribute] +pub fn hooks( + _attr: proc_macro::TokenStream, + item: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let mut input = parse_macro_input!(item as syn::ItemImpl); + let custom_code_set: sp_std::collections::btree_set::BTreeSet<&str> = [ + ON_IDLE_HOOK, + INTEGRITY_TEST_HOOK, + ] + .iter() + .cloned() + .collect(); + // check the required functions are present + let implemented_fn = input.items.iter().filter(|item| { + if let syn::ImplItem::Fn(method) = item { + if custom_code_set.contains(method.sig.ident.to_string().as_str()) { + true + } else { false } + } else { false } + }).collect::>(); + if implemented_fn.len() != 2 { + let required_hooks = custom_code_set.iter().map(|k| *k).collect::>().join(", "); + panic!("You must define the following hooks: {}", required_hooks); + }; + // modify the actual hooks + for item in &mut input.items { + if let syn::ImplItem::Fn(method) = item { + let fn_name = method.sig.ident.to_string(); + if custom_code_set.contains(&fn_name.as_str()) { + let curr_impl = method.block.to_token_stream(); + match fn_name.as_str() { + ON_IDLE_HOOK => { + // get the second attribute's name + if let Some(syn::FnArg::Typed(remaining_weight_attr)) = method.sig.inputs.last() { + if let syn::Pat::Ident(remaining_weight_ident) = *remaining_weight_attr.pat.clone() { + let remaining_weight_name = remaining_weight_ident.ident; + let new_code = quote!( + { + let mut weight_sum = #remaining_weight_name.clone(); + loop { + let (result, weight) = Migration::::migrate(#remaining_weight_name); + #remaining_weight_name.saturating_reduce(weight); + + match result { + // There is not enough weight to perform a migration, or make any progress, we + // just return the remaining weight. + migratable::MigrateResult::NoMigrationPerformed | migratable::MigrateResult::InProgress { steps_done: 0 } => return #remaining_weight_name, + // Migration is still in progress, we can start the next step. + migratable::MigrateResult::InProgress { .. } => continue, + // Either no migration is in progress, or we are done with all migrations, we + // can do some more other work with the remaining weight. + migratable::MigrateResult::Completed | migratable::MigrateResult::NoMigrationInProgress => break, + } + }; + weight_sum.saturating_reduce(#remaining_weight_name); + weight_sum + } + ); + // mutate the block to include the new code + method.block = parse_quote! { + { + let migration_weight = #new_code; + let mut weight = #curr_impl; + weight.saturating_add(migration_weight); + weight + } + }; + } else { + panic!("on_idle hook does not have the second parameter correctly defined"); + } + } else { + panic!("on_idle hook is not properly defined"); + } + }, + INTEGRITY_TEST_HOOK => { + let new_code = quote!( + Migration::::integrity_test(); + ); + method.block = parse_quote! { + { + #new_code + #curr_impl + } + }; + }, + _ => {} + } + } else { + panic!("\"{}\" not found in pallet hooks", fn_name); + } + } + } + let modified_impl = quote! { + #input + }; + modified_impl.into() +} /// Adds the `Migrations` type to `Config` #[proc_macro_attribute] pub fn config( - _attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, + _attr: proc_macro::TokenStream, + item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - let mut input = parse_macro_input!(item as syn::ItemTrait); - let migrations = quote!( + let mut input = parse_macro_input!(item as syn::ItemTrait); + let migrations = quote!( /// The sequence of migration steps that will be applied during a migration. type Migrations: migratable::MigrateSequence; ); - input.items.push(parse_quote! { #migrations }); - let output = quote! { + input.items.push(parse_quote! { #migrations }); + let output = quote! { #input }; - output.into() + output.into() } /// Adds the following to the pallet module: @@ -27,13 +129,13 @@ pub fn pallet( _attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - let mut input = parse_macro_input!(item as syn::ItemMod); - let content = &mut input.content.as_mut().unwrap().1; + let mut input = parse_macro_input!(item as syn::ItemMod); + let content = &mut input.content.as_mut().unwrap().1; - // add storage - let storage = quote!( + // add storage + let storage = quote!( /// A migration can span across multiple blocks. This storage defines a cursor to track the - /// progress of the migration, enabling us to resume from the last completed position. + /// progress of the migration, enabling us to resume from the last completed position. #[pallet::storage] pub type MigrationInProgress = StorageValue< _, @@ -41,22 +143,22 @@ pub fn pallet( frame_support::storage::types::OptionQuery, >; ); - content.push(parse_quote! { #storage }); + content.push(parse_quote! { #storage }); - // add migration struct - let migration = quote!( + // add migration struct + let migration = quote!( /// Performs all necessary migrations based on `StorageVersion`. - /// - /// If `TEST_ALL_STEPS == true` and `try-runtime` is enabled, this will run all the migrations - /// inside `on_runtime_upgrade`. This should be set to false in tests that want to ensure the step - /// by step migratable works. - struct Migration(core::marker::PhantomData); + /// + /// If `TEST_ALL_STEPS == true` and `try-runtime` is enabled, this will run all the migrations + /// inside `on_runtime_upgrade`. This should be set to false in tests that want to ensure the step + /// by step migratable works. + pub struct Migration(core::marker::PhantomData); ); content.push(parse_quote! { #migration }); - // add migration logic - let expand = generate_mod_expand(); - content.push(parse_quote! { #expand }); + // add migration logic + let expand = generate_mod_expand(); + content.push(parse_quote! { #expand }); let output = quote! { #input @@ -178,14 +280,14 @@ fn generate_mod_expand() -> proc_macro2::TokenStream { use migratable::weights::WeightInfo; impl Migration { /// Verify that each migratable's step of the [`Config::Migrations`] sequence fits into - /// `Cursor`. + /// `Cursor`. pub(crate) fn integrity_test() { let max_weight = ::BlockWeights::get().max_block; T::Migrations::integrity_test(max_weight) } /// Migrate - /// Return the weight used and whether or not a migratable is in progress + /// Return the weight used and whether or not a migratable is in progress pub(crate) fn migrate(weight_limit: frame_support::weights::Weight) -> (migratable::MigrateResult, frame_support::weights::Weight) { let name = >::name(); let mut weight_left = weight_limit; diff --git a/src/lib.rs b/src/lib.rs index 3d2be71..238b655 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] + //! Multi-block Migration framework. //! //! This module allows us to define a migratable as a sequence of [`MigrationStep`]s that can be @@ -40,14 +42,13 @@ //! While the migratable is in progress, all dispatchables except `migrate`, are blocked, and returns //! a `MigrationInProgress` error. -pub use migratable_procedural::{config, pallet}; +pub use migratable_procedural::{config, hooks, pallet}; pub mod weights; -pub use log; - extern crate alloc; -use codec::{Codec, Decode}; +pub use log; +use parity_scale_codec::{Codec, Decode}; use frame_support::{ pallet_prelude::{BoundedVec, Encode, MaxEncodedLen, StorageVersion, Weight}, traits::ConstU32, @@ -61,7 +62,6 @@ use sp_std::prelude::*; const PROOF_ENCODE: &str = "Tuple::max_encoded_len() < Cursor::max_encoded_len()` is verified in `Self::integrity_test()`; qed"; const PROOF_DECODE: &str = "We encode to the same type in this trait only. No other code touches this item; qed"; -const LOG_TARGET: &str = "migratable"; fn invalid_version(version: StorageVersion) -> ! { panic!("Required migratable {version:?} not supported by this runtime. This is a bug."); @@ -140,7 +140,6 @@ impl MigrationStep for NoopMigration { Weight::zero() } fn step(&mut self) -> (IsFinished, Weight) { - log::debug!(target: LOG_TARGET, "Noop migratable for version {}", N); (IsFinished::Yes, Weight::zero()) } }