From 89f228cbc4a98e3c937fd01fafcaa4095e78c251 Mon Sep 17 00:00:00 2001 From: Fredrik Simonsson Date: Fri, 9 Feb 2024 14:11:46 +0900 Subject: [PATCH] Cleanup migrations (#823) * Cleanup migrations --- node/src/rpc.rs | 2 +- node/src/service.rs | 2 +- pallets/grants/src/mock.rs | 6 +- pallets/sponsorship/src/benchmarking.rs | 82 ----- pallets/sponsorship/src/lib.rs | 32 +- pallets/sponsorship/src/migration.rs | 416 ------------------------ pallets/sponsorship/src/weights.rs | 152 +++------ runtimes/eden/src/lib.rs | 11 +- runtimes/eden/src/migrations.rs | 132 +------- runtimes/eden/src/pallets_governance.rs | 2 +- runtimes/eden/src/version.rs | 2 +- 11 files changed, 72 insertions(+), 767 deletions(-) delete mode 100644 pallets/sponsorship/src/migration.rs diff --git a/node/src/rpc.rs b/node/src/rpc.rs index c21f576103f..ea3df1bf73f 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -23,7 +23,7 @@ use std::sync::Arc; use primitives::{AccountId, Balance, Block, Nonce}; use sc_client_api::AuxStore; -pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +pub use sc_rpc::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; diff --git a/node/src/service.rs b/node/src/service.rs index 6ee27d1fa08..b658a2e3aac 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -24,7 +24,7 @@ use std::{sync::Arc, time::Duration}; // rpc use jsonrpsee::RpcModule; -pub use primitives::{AccountId, Balance, Block, BlockNumber, Hash, Header, Nonce}; +pub use primitives::{AccountId, Balance, Block, Nonce}; // Cumulus Imports use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; diff --git a/pallets/grants/src/mock.rs b/pallets/grants/src/mock.rs index 4e6cd9692bd..b34067e39f5 100644 --- a/pallets/grants/src/mock.rs +++ b/pallets/grants/src/mock.rs @@ -160,11 +160,7 @@ impl ExtBuilder { }); pallet_balances::GenesisConfig:: { - balances: self - .endowed_accounts - .into_iter() - .map(|(account_id, initial_balance)| (account_id, initial_balance)) - .collect::>(), + balances: self.endowed_accounts.into_iter().collect::>(), } .assimilate_storage(&mut storage) .unwrap_or_else(|err| { diff --git a/pallets/sponsorship/src/benchmarking.rs b/pallets/sponsorship/src/benchmarking.rs index cbb3e0a18d3..69e92b0c7d7 100644 --- a/pallets/sponsorship/src/benchmarking.rs +++ b/pallets/sponsorship/src/benchmarking.rs @@ -309,87 +309,5 @@ mod benchmarks { assert_eq!(user_detail.reserve_quota.balance(), T::Currency::minimum_balance()); } - #[benchmark] - fn migrate_users(l: Linear<1, 1_000>) { - use crate::migration::v0::{migrate_users, User as V0User, UserDetailsOf as V0UserDetailsOf}; - use frame_support::storage::generator::StorageDoubleMap; - - let pot: T::PotId = 0u32.into(); - let users: Vec = (0..l).map(|i| account("user", i, SEED)).collect(); - - for user in &users { - let user_details = V0UserDetailsOf:: { - proxy: user.clone(), - fee_quota: LimitedBalance::with_limit(3u32.into()), - reserve_quota: LimitedBalance::with_limit(6u32.into()), - }; - V0User::::insert(pot, user, user_details); - } - - let starting_key = V0User::::prefix_hash(); - - #[block] - { - migrate_users::(l as usize, starting_key); - } - - users.iter().for_each(|user| { - assert_eq!( - User::::get(pot, user), - Some(UserDetailsOf:: { - proxy: user.clone(), - fee_quota: LimitedBalance::with_limit(3u32.into()), - reserve_quota: LimitedBalance::with_limit(6u32.into()), - deposit: Zero::zero(), - }) - ); - }); - } - - #[benchmark] - fn migrate_pots(l: Linear<1, 1_000>) { - use crate::migration::v0::{migrate_pots, Pot as V0Pot, PotDetailsOf as V0PotDetailsOf}; - use frame_support::storage::generator::StorageMap; - - let caller: T::AccountId = whitelisted_caller(); - let pots: Vec = (0..l).map(|i| i.into()).collect(); - - pots.iter() - .map(|pot| { - ( - *pot, - V0PotDetailsOf:: { - sponsor: caller.clone(), - sponsorship_type: T::SponsorshipType::default(), - fee_quota: LimitedBalance::with_limit(5u32.into()), - reserve_quota: LimitedBalance::with_limit(7u32.into()), - }, - ) - }) - .for_each(|(pot, pot_details)| { - V0Pot::::insert(pot, pot_details); - }); - - let starting_key = V0Pot::::prefix_hash(); - - #[block] - { - migrate_pots::(l as usize, starting_key); - } - - pots.iter().for_each(|pot| { - assert_eq!( - Pot::::get(pot), - Some(PotDetailsOf:: { - sponsor: caller.clone(), - sponsorship_type: T::SponsorshipType::default(), - fee_quota: LimitedBalance::with_limit(5u32.into()), - reserve_quota: LimitedBalance::with_limit(7u32.into()), - deposit: Zero::zero(), - }) - ); - }); - } - impl_benchmark_test_suite!(Sponsorship, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/pallets/sponsorship/src/lib.rs b/pallets/sponsorship/src/lib.rs index ee7c6780162..7e779847692 100644 --- a/pallets/sponsorship/src/lib.rs +++ b/pallets/sponsorship/src/lib.rs @@ -18,7 +18,9 @@ #![cfg_attr(not(feature = "std"), no_std)] -use frame_support::pallet_prelude::{ensure, Decode, Encode, MaxEncodedLen, PhantomData, RuntimeDebug, TypeInfo}; +use frame_support::pallet_prelude::{ + ensure, Decode, Encode, MaxEncodedLen, PhantomData, RuntimeDebug, StorageVersion, TypeInfo, +}; use frame_support::{ dispatch::{DispatchInfo, DispatchResult, Dispatchable, GetDispatchInfo, Pays, PostDispatchInfo}, traits::{ @@ -29,8 +31,7 @@ use frame_support::{ }; use pallet_transaction_payment::OnChargeTransaction; use sp_io::hashing::blake2_256; -#[cfg(feature = "try-runtime")] -use sp_runtime::TryRuntimeError; + use sp_runtime::{ traits::{DispatchInfoOf, One, PostDispatchInfoOf, SignedExtension, TrailingZeroInput, Zero}, transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction}, @@ -43,7 +44,7 @@ use sp_std::{ }; use support::LimitedBalance; -pub use migration::STORAGE_VERSION; +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); pub use pallet::*; #[cfg(test)] @@ -55,7 +56,6 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -pub(crate) mod migration; pub mod weights; pub use weights::*; @@ -122,7 +122,7 @@ pub mod pallet { use scale_info::prelude::boxed::Box; #[pallet::pallet] - #[pallet::storage_version(migration::STORAGE_VERSION)] + #[pallet::storage_version(STORAGE_VERSION)] #[pallet::without_storage_info] pub struct Pallet(_); @@ -567,26 +567,6 @@ pub mod pallet { Ok(()) } } - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: BlockNumberFor) -> Weight { - migration::on_initialize::(n) - } - - fn on_runtime_upgrade() -> Weight { - migration::on_runtime_upgrade::() - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, TryRuntimeError> { - migration::pre_upgrade::() - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(_state: Vec) -> Result<(), TryRuntimeError> { - migration::post_upgrade::(_state) - } - } } /// The pre-sponsor call preps are the details returned from `pre_sponsor_for` that are needed diff --git a/pallets/sponsorship/src/migration.rs b/pallets/sponsorship/src/migration.rs deleted file mode 100644 index 0cadd6f438a..00000000000 --- a/pallets/sponsorship/src/migration.rs +++ /dev/null @@ -1,416 +0,0 @@ -/* - * This file is part of the Nodle Chain distributed at https://github.com/NodleCode/chain - * Copyright (C) 2020-2022 Nodle International - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use crate::{ - weights::WeightInfo, BalanceOf, Config, Pallet, Pot, PotDetailsOf, PotMigrationCursor, User, UserDetailsOf, - UserMigrationCursor, UserRegistrationCount, -}; -use codec::{Decode, Encode}; -use frame_support::{ - pallet_prelude::*, - storage::generator::{StorageDoubleMap, StorageMap}, - traits::{Get, StorageVersion}, - weights::Weight, -}; -use frame_system::pallet_prelude::BlockNumberFor; -use sp_runtime::{traits::Zero, Perbill}; -use sp_std::vec::Vec; -use support::LimitedBalance; - -/// The current storage version. -pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); - -pub(crate) mod v0 { - use super::{Pot as V1Pot, PotDetailsOf as V1PotDetailsOf, User as V1User, UserDetailsOf as V1UserDetailsOf, *}; - use frame_support::storage_alias; - use sp_runtime::traits::Saturating; - - #[derive(Encode, Decode, Debug)] - pub struct PotDetails { - pub sponsor: AccountId, - pub sponsorship_type: SponsorshipType, - pub fee_quota: LimitedBalance, - pub reserve_quota: LimitedBalance, - } - - #[derive(Encode, Decode, Debug)] - pub struct UserDetails { - pub proxy: AccountId, - pub fee_quota: LimitedBalance, - pub reserve_quota: LimitedBalance, - } - - pub type PotDetailsOf = - PotDetails<::AccountId, ::SponsorshipType, BalanceOf>; - pub type UserDetailsOf = UserDetails<::AccountId, BalanceOf>; - - #[storage_alias] - /// Details of a pot. - pub type Pot = - StorageMap, Blake2_128Concat, ::PotId, PotDetailsOf, OptionQuery>; - - #[storage_alias] - /// User details of a pot. - pub type User = StorageDoubleMap< - Pallet, - Blake2_128Concat, - ::PotId, - Blake2_128Concat, - ::AccountId, - UserDetailsOf, - OptionQuery, - >; - - pub const BLOCK_PERCENT_USAGE: u32 = 50; - - pub fn migrate_pots(max_pots: usize, starting_key: Vec) -> (Option>, Weight) { - let mut iter = Pot::::iter_from(starting_key); - - let pots = iter - .by_ref() - .take(max_pots) - .map(|(pot, details)| { - ( - pot, - V1PotDetailsOf:: { - sponsor: details.sponsor, - sponsorship_type: details.sponsorship_type, - fee_quota: details.fee_quota, - reserve_quota: details.reserve_quota, - deposit: Zero::zero(), - }, - ) - }) - .collect::>(); - - let num_of_pots = pots.len(); - - pots.into_iter() - .for_each(|(pot, details)| V1Pot::::insert(pot, details)); - - log::info!(target: "sponsorship", "migrated {} pots", num_of_pots); - - let weight = T::WeightInfo::migrate_pots(num_of_pots as u32); - if num_of_pots == max_pots { - (Some(iter.last_raw_key().to_vec()), weight) - } else { - (None, weight) - } - } - - pub fn migrate_users(max_users: usize, starting_key: Vec) -> (Option>, Weight) { - let mut iter = User::::iter_from(starting_key); - - let users = iter - .by_ref() - .take(max_users) - .map(|(pot, user, details)| { - ( - pot, - user, - V1UserDetailsOf:: { - proxy: details.proxy, - fee_quota: details.fee_quota, - reserve_quota: details.reserve_quota, - deposit: Zero::zero(), - }, - ) - }) - .collect::>(); - - let users_len = users.len(); - - users.into_iter().for_each(|(pot, user, details)| { - UserRegistrationCount::::mutate(&user, |count| { - count.saturating_inc(); - }); - V1User::::insert(pot, user, details); - }); - - log::info!(target: "sponsorship", "migrated {} user-in-pots", users_len); - - let weight = T::WeightInfo::migrate_users(users_len as u32); - if users_len == max_users { - (Some(iter.last_raw_key().to_vec()), weight) - } else { - (None, weight) - } - } - - pub fn migrate_limited(max_weight: Weight) -> Weight { - let mut weight: Weight = Zero::zero(); - - loop { - weight += min_weight::(); - - let max_pots = max_weight - .saturating_sub(weight) - .ref_time() - .checked_div(T::WeightInfo::migrate_pots(1).ref_time()) - .unwrap_or(1) as usize; - if max_pots == 0 { - break; - } - - let pot_migration_in_progress = if let Some(starting_key) = PotMigrationCursor::::get() { - let (end_cursor, migration_weight) = migrate_pots::(max_pots, starting_key); - weight += migration_weight + T::DbWeight::get().writes(1); - match end_cursor { - Some(last_key) => { - PotMigrationCursor::::put(last_key); - true - } - None => { - PotMigrationCursor::::kill(); - false - } - } - } else { - false - }; - - let max_users = max_weight - .saturating_sub(weight) - .ref_time() - .checked_div(T::WeightInfo::migrate_users(1).ref_time()) - .unwrap_or(1) as usize; - if max_users == 0 { - break; - } - - let user_migration_in_progress = if let Some(starting_key) = UserMigrationCursor::::get() { - let (end_cursor, migration_weight) = migrate_users::(max_users, starting_key); - weight += migration_weight + T::DbWeight::get().writes(1); - match end_cursor { - Some(last_key) => { - UserMigrationCursor::::put(last_key); - true - } - None => { - UserMigrationCursor::::kill(); - false - } - } - } else { - false - }; - - if !pot_migration_in_progress && !user_migration_in_progress { - weight += T::DbWeight::get().writes(1); - STORAGE_VERSION.put::>(); - break; - } - } - - weight - } - - /// Return the minimum overhead of attempting to migrate the storage. - pub fn min_weight() -> Weight { - // 2 reads: PotMigrationCursor, UserMigrationCursor - // Fixed: 40_000_000 as a pessimistic estimation for non benchmarked logic with trivial cost - // during each loop of migrate_limited - T::DbWeight::get() - .reads(2) - .saturating_add(Weight::from_parts(40_000_000_u64, 0)) - } - - /// Return the maximum overhead of attempting to migrate the storage. - pub fn max_weight() -> Weight { - T::BlockWeights::get().max_block * Perbill::from_percent(BLOCK_PERCENT_USAGE) - } -} - -/// Call this during on_initialize for the pallet. -pub fn on_initialize(_n: BlockNumberFor) -> Weight { - v0::migrate_limited::(v0::max_weight::()) -} - -/// Call this during the next runtime upgrade for this module. -pub fn on_runtime_upgrade() -> Weight { - let mut weight: Weight = T::DbWeight::get().reads(1); - - if StorageVersion::get::>() == 0 { - PotMigrationCursor::::put(Pot::::prefix_hash()); - UserMigrationCursor::::put(User::::prefix_hash()); - weight += T::DbWeight::get().reads_writes(2, 2); - - // The following invocation of migration is only needed for testing the logic during the - // try runtime. The actual migration should be called during on_initialize for the pallet. - #[cfg(feature = "try-runtime")] - while StorageVersion::get::>() == 0 { - weight += v0::migrate_limited::(v0::max_weight::()); - } - } - - weight -} - -#[cfg(feature = "try-runtime")] -use ::{ - frame_support::{Blake2_128Concat, StorageHasher}, - sp_runtime::TryRuntimeError, - sp_std::borrow::Borrow, -}; - -#[cfg(feature = "try-runtime")] -type StorageDoubleMapKey = Vec; - -#[cfg(feature = "try-runtime")] -pub(crate) fn pre_upgrade() -> Result, TryRuntimeError> { - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("Storage version is not 0") - ); - - let block_usage = v0::max_weight::(); - ensure!( - block_usage.all_gt(v0::min_weight::()), - TryRuntimeError::Other("Block usage is set too low") - ); - log::info!(target: "sponsorship", "pre_upgrade: block_usage = ({ref_time}, {proof_size})", ref_time=block_usage.ref_time(), proof_size=block_usage.proof_size()); - - let max_pots_per_block = block_usage - .saturating_sub(v0::min_weight::()) - .ref_time() - .checked_div(T::WeightInfo::migrate_pots(1).ref_time()) - .unwrap_or(1) as usize; - let max_users_per_block = block_usage - .saturating_sub(v0::min_weight::()) - .ref_time() - .checked_div(T::WeightInfo::migrate_users(1).ref_time()) - .unwrap_or(1) as usize; - ensure!( - max_pots_per_block > 0 && max_users_per_block > 0, - TryRuntimeError::Other("Migration allowed weight is too low") - ); - log::info!(target: "sponsorship", "pre_upgrade: max_pots_per_block = {max_pots_per_block}, max_users_per_block = {max_users_per_block}"); - - let pot_details = frame_support::migration::storage_key_iter::< - T::PotId, - v0::PotDetailsOf, - frame_support::Blake2_128Concat, - >(Pot::::module_prefix(), Pot::::storage_prefix()) - .collect::>(); - let user_details = frame_support::migration::storage_iter::>( - User::::module_prefix(), - User::::storage_prefix(), - ) - .collect::>(); - log::info!(target: "sponsorship", "pre_upgrade: pots = {pot_details_len}, users = {user_details_len}", pot_details_len = pot_details.len(), user_details_len = user_details.len()); - - let total_consumed_weight = v0::min_weight::() - + T::WeightInfo::migrate_pots(pot_details.len() as u32) - + T::WeightInfo::migrate_users(user_details.len() as u32) - + T::DbWeight::get().writes(1); - let blocks = total_consumed_weight - .ref_time() - .checked_div(block_usage.ref_time()) - .ok_or("Unable to calculate blocks")? - + 1; - log::info!(target: "sponsorship", "pre_upgrade: total_consumed_weight = ({ref_time}, {proof_size}), blocks = {blocks:?}", ref_time=total_consumed_weight.ref_time(), proof_size=total_consumed_weight.proof_size()); - - Ok((pot_details, user_details).encode()) -} - -#[cfg(feature = "try-runtime")] -pub(crate) fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { - ensure!( - StorageVersion::get::>() == 1, - TryRuntimeError::Other("Storage version not fixed") - ); - - let (pre_pot_details, pre_user_details): ( - Vec<(T::PotId, v0::PotDetailsOf)>, - Vec<(StorageDoubleMapKey, v0::UserDetailsOf)>, - ) = Decode::decode(&mut state.as_slice()).map_err(|_| "Unable to decode previous collection details")?; - let pot_details = Pot::::iter().collect::>(); - - ensure!( - pre_pot_details.len() == pot_details.len(), - TryRuntimeError::Other("Pot count mismatch") - ); - - for (pre, post) in pre_pot_details.iter().zip(pot_details.iter()) { - ensure!(pre.0 == post.0, TryRuntimeError::Other("Pot id mismatch")); - ensure!( - pre.1.sponsor == post.1.sponsor, - TryRuntimeError::Other("Pot sponsor mismatch") - ); - ensure!( - pre.1.sponsorship_type == post.1.sponsorship_type, - TryRuntimeError::Other("Pot sponsorship type mismatch") - ); - ensure!( - pre.1.fee_quota == post.1.fee_quota, - TryRuntimeError::Other("Pot fee quota mismatch") - ); - ensure!( - pre.1.reserve_quota == post.1.reserve_quota, - TryRuntimeError::Other("Pot reserve quota mismatch") - ); - ensure!( - post.1.deposit == Default::default(), - TryRuntimeError::Other("Pot deposit is not default") - ); - } - - let user_details = User::::iter().collect::>(); - ensure!( - pre_user_details.len() == user_details.len(), - TryRuntimeError::Other("User count mismatch") - ); - - for (pre, post) in pre_user_details.iter().zip(user_details.iter()) { - let key1_hashed = post.0.borrow().using_encoded(Blake2_128Concat::hash); - let key2_hashed = post.1.borrow().using_encoded(Blake2_128Concat::hash); - let mut final_key = Vec::new(); - final_key.extend_from_slice(key1_hashed.as_ref()); - final_key.extend_from_slice(key2_hashed.as_ref()); - - ensure!(pre.0 == final_key, TryRuntimeError::Other("User key mismatch")); - ensure!( - pre.1.proxy == post.2.proxy, - TryRuntimeError::Other("User proxy mismatch") - ); - ensure!( - pre.1.fee_quota == post.2.fee_quota, - TryRuntimeError::Other("User fee quota mismatch") - ); - ensure!( - pre.1.reserve_quota == post.2.reserve_quota, - TryRuntimeError::Other("User reserve quota mismatch") - ); - ensure!( - post.2.deposit == Default::default(), - TryRuntimeError::Other("User deposit is not default") - ); - } - - UserRegistrationCount::::iter().try_for_each(|(_user, count)| { - ensure!(count > 0, TryRuntimeError::Other("User registration count is 0")); - ensure!( - count <= pot_details.len() as u32, - TryRuntimeError::Other("User registration count is greater than number of pots") - ); - Ok::<(), TryRuntimeError>(()) - })?; - - log::info!(target: "sponsorship", "post_upgrade: pots = {}, pot_user_count = {}, users = {}", pot_details.len(), user_details.len(), UserRegistrationCount::::iter().count()); - Ok(()) -} diff --git a/pallets/sponsorship/src/weights.rs b/pallets/sponsorship/src/weights.rs index 50b88c47d1b..896b190cc99 100644 --- a/pallets/sponsorship/src/weights.rs +++ b/pallets/sponsorship/src/weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for pallet_sponsorship //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-08, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! HOSTNAME: `chain-bench-b606df9f`, CPU: `AMD EPYC 7B13` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -54,8 +54,6 @@ pub trait WeightInfo { fn update_users_limits(l: u32, ) -> Weight; fn pre_sponsor() -> Weight; fn post_sponsor() -> Weight; - fn migrate_users(l: u32, ) -> Weight; - fn migrate_pots(l: u32, ) -> Weight; } /// Weight functions for `pallet_sponsorship`. @@ -66,8 +64,8 @@ impl WeightInfo for SubstrateWeight { // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn create_pot() -> Weight { - // Minimum execution time: 40_000 nanoseconds. - Weight::from_parts(41_350_000_u64, 0) + // Minimum execution time: 32_480 nanoseconds. + Weight::from_parts(33_600_000_u64, 0) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -78,8 +76,8 @@ impl WeightInfo for SubstrateWeight { // Storage: `Sponsorship::User` (r:1 w:0) // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) fn remove_pot() -> Weight { - // Minimum execution time: 28_320 nanoseconds. - Weight::from_parts(28_980_000_u64, 0) + // Minimum execution time: 24_040 nanoseconds. + Weight::from_parts(24_850_000_u64, 0) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -88,16 +86,16 @@ impl WeightInfo for SubstrateWeight { // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn update_pot_limits() -> Weight { - // Minimum execution time: 21_490 nanoseconds. - Weight::from_parts(22_110_000_u64, 0) + // Minimum execution time: 17_880 nanoseconds. + Weight::from_parts(18_560_000_u64, 0) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn update_sponsorship_type() -> Weight { - // Minimum execution time: 18_120 nanoseconds. - Weight::from_parts(19_060_000_u64, 0) + // Minimum execution time: 14_571 nanoseconds. + Weight::from_parts(15_229_000_u64, 0) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -113,10 +111,10 @@ impl WeightInfo for SubstrateWeight { // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 1000]`. fn register_users(l: u32, ) -> Weight { - // Minimum execution time: 70_260 nanoseconds. - Weight::from_parts(70_770_000_u64, 0) - // Standard Error: 10_182 - .saturating_add(Weight::from_parts(44_597_301_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 55_000 nanoseconds. + Weight::from_parts(55_900_000_u64, 0) + // Standard Error: 10_326 + .saturating_add(Weight::from_parts(34_573_724_u64, 0).saturating_mul(l as u64)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(l as u64))) .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(l as u64))) @@ -133,10 +131,10 @@ impl WeightInfo for SubstrateWeight { // Proof: `Sponsorship::UserRegistrationCount` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `l` is `[1, 1000]`. fn remove_users(l: u32, ) -> Weight { - // Minimum execution time: 135_989 nanoseconds. - Weight::from_parts(137_530_000_u64, 0) - // Standard Error: 56_658 - .saturating_add(Weight::from_parts(119_489_290_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 114_540 nanoseconds. + Weight::from_parts(115_440_000_u64, 0) + // Standard Error: 57_987 + .saturating_add(Weight::from_parts(102_406_355_u64, 0).saturating_mul(l as u64)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(l as u64))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -150,10 +148,10 @@ impl WeightInfo for SubstrateWeight { // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `l` is `[1, 1000]`. fn update_users_limits(l: u32, ) -> Weight { - // Minimum execution time: 31_070 nanoseconds. - Weight::from_parts(31_300_000_u64, 0) - // Standard Error: 9_792 - .saturating_add(Weight::from_parts(9_190_432_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 26_490 nanoseconds. + Weight::from_parts(26_700_000_u64, 0) + // Standard Error: 9_554 + .saturating_add(Weight::from_parts(8_788_441_u64, 0).saturating_mul(l as u64)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(l as u64))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -166,8 +164,8 @@ impl WeightInfo for SubstrateWeight { // Storage: `System::Account` (r:2 w:2) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn pre_sponsor() -> Weight { - // Minimum execution time: 77_509 nanoseconds. - Weight::from_parts(78_280_000_u64, 0) + // Minimum execution time: 66_010 nanoseconds. + Weight::from_parts(67_060_000_u64, 0) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -178,37 +176,11 @@ impl WeightInfo for SubstrateWeight { // Storage: `Sponsorship::Pot` (r:0 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn post_sponsor() -> Weight { - // Minimum execution time: 69_650 nanoseconds. - Weight::from_parts(70_800_000_u64, 0) + // Minimum execution time: 59_090 nanoseconds. + Weight::from_parts(60_210_000_u64, 0) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - // Storage: `Sponsorship::User` (r:1000 w:999) - // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `Sponsorship::UserRegistrationCount` (r:999 w:999) - // Proof: `Sponsorship::UserRegistrationCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `l` is `[1, 1000]`. - fn migrate_users(l: u32, ) -> Weight { - // Minimum execution time: 22_720 nanoseconds. - Weight::from_parts(22_971_000_u64, 0) - // Standard Error: 3_023 - .saturating_add(Weight::from_parts(10_514_036_u64, 0).saturating_mul(l as u64)) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(l as u64))) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(l as u64))) - } - // Storage: `Sponsorship::Pot` (r:1000 w:999) - // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `l` is `[1, 1000]`. - fn migrate_pots(l: u32, ) -> Weight { - // Minimum execution time: 18_130 nanoseconds. - Weight::from_parts(18_710_000_u64, 0) - // Standard Error: 2_991 - .saturating_add(Weight::from_parts(5_980_964_u64, 0).saturating_mul(l as u64)) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(l as u64))) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(l as u64))) - } } impl WeightInfo for () { @@ -217,8 +189,8 @@ impl WeightInfo for () { // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn create_pot() -> Weight { - // Minimum execution time: 40_000 nanoseconds. - Weight::from_parts(41_350_000_u64, 0) + // Minimum execution time: 32_480 nanoseconds. + Weight::from_parts(33_600_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -229,8 +201,8 @@ impl WeightInfo for () { // Storage: `Sponsorship::User` (r:1 w:0) // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) fn remove_pot() -> Weight { - // Minimum execution time: 28_320 nanoseconds. - Weight::from_parts(28_980_000_u64, 0) + // Minimum execution time: 24_040 nanoseconds. + Weight::from_parts(24_850_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -239,16 +211,16 @@ impl WeightInfo for () { // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn update_pot_limits() -> Weight { - // Minimum execution time: 21_490 nanoseconds. - Weight::from_parts(22_110_000_u64, 0) + // Minimum execution time: 17_880 nanoseconds. + Weight::from_parts(18_560_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } // Storage: `Sponsorship::Pot` (r:1 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn update_sponsorship_type() -> Weight { - // Minimum execution time: 18_120 nanoseconds. - Weight::from_parts(19_060_000_u64, 0) + // Minimum execution time: 14_571 nanoseconds. + Weight::from_parts(15_229_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -264,10 +236,10 @@ impl WeightInfo for () { // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 1000]`. fn register_users(l: u32, ) -> Weight { - // Minimum execution time: 70_260 nanoseconds. - Weight::from_parts(70_770_000_u64, 0) - // Standard Error: 10_182 - .saturating_add(Weight::from_parts(44_597_301_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 55_000 nanoseconds. + Weight::from_parts(55_900_000_u64, 0) + // Standard Error: 10_326 + .saturating_add(Weight::from_parts(34_573_724_u64, 0).saturating_mul(l as u64)) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(l as u64))) .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(l as u64))) @@ -284,10 +256,10 @@ impl WeightInfo for () { // Proof: `Sponsorship::UserRegistrationCount` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `l` is `[1, 1000]`. fn remove_users(l: u32, ) -> Weight { - // Minimum execution time: 135_989 nanoseconds. - Weight::from_parts(137_530_000_u64, 0) - // Standard Error: 56_658 - .saturating_add(Weight::from_parts(119_489_290_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 114_540 nanoseconds. + Weight::from_parts(115_440_000_u64, 0) + // Standard Error: 57_987 + .saturating_add(Weight::from_parts(102_406_355_u64, 0).saturating_mul(l as u64)) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(l as u64))) .saturating_add(RocksDbWeight::get().writes(1_u64)) @@ -301,10 +273,10 @@ impl WeightInfo for () { // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `l` is `[1, 1000]`. fn update_users_limits(l: u32, ) -> Weight { - // Minimum execution time: 31_070 nanoseconds. - Weight::from_parts(31_300_000_u64, 0) - // Standard Error: 9_792 - .saturating_add(Weight::from_parts(9_190_432_u64, 0).saturating_mul(l as u64)) + // Minimum execution time: 26_490 nanoseconds. + Weight::from_parts(26_700_000_u64, 0) + // Standard Error: 9_554 + .saturating_add(Weight::from_parts(8_788_441_u64, 0).saturating_mul(l as u64)) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(l as u64))) .saturating_add(RocksDbWeight::get().writes(1_u64)) @@ -317,8 +289,8 @@ impl WeightInfo for () { // Storage: `System::Account` (r:2 w:2) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn pre_sponsor() -> Weight { - // Minimum execution time: 77_509 nanoseconds. - Weight::from_parts(78_280_000_u64, 0) + // Minimum execution time: 66_010 nanoseconds. + Weight::from_parts(67_060_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -329,35 +301,9 @@ impl WeightInfo for () { // Storage: `Sponsorship::Pot` (r:0 w:1) // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) fn post_sponsor() -> Weight { - // Minimum execution time: 69_650 nanoseconds. - Weight::from_parts(70_800_000_u64, 0) + // Minimum execution time: 59_090 nanoseconds. + Weight::from_parts(60_210_000_u64, 0) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - // Storage: `Sponsorship::User` (r:1000 w:999) - // Proof: `Sponsorship::User` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `Sponsorship::UserRegistrationCount` (r:999 w:999) - // Proof: `Sponsorship::UserRegistrationCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `l` is `[1, 1000]`. - fn migrate_users(l: u32, ) -> Weight { - // Minimum execution time: 22_720 nanoseconds. - Weight::from_parts(22_971_000_u64, 0) - // Standard Error: 3_023 - .saturating_add(Weight::from_parts(10_514_036_u64, 0).saturating_mul(l as u64)) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(l as u64))) - .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(l as u64))) - } - // Storage: `Sponsorship::Pot` (r:1000 w:999) - // Proof: `Sponsorship::Pot` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `l` is `[1, 1000]`. - fn migrate_pots(l: u32, ) -> Weight { - // Minimum execution time: 18_130 nanoseconds. - Weight::from_parts(18_710_000_u64, 0) - // Standard Error: 2_991 - .saturating_add(Weight::from_parts(5_980_964_u64, 0).saturating_mul(l as u64)) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(l as u64))) - .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(l as u64))) - } } diff --git a/runtimes/eden/src/lib.rs b/runtimes/eden/src/lib.rs index f4d348a9a2a..60631de8010 100644 --- a/runtimes/eden/src/lib.rs +++ b/runtimes/eden/src/lib.rs @@ -154,15 +154,8 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; -const TEST_ALL_STEPS: bool = cfg!(feature = "try-runtime"); -pub type Migrations = ( - pallet_collator_selection::migration::v1::MigrateToV1, - // Migrate data as designed - pallet_multisig::migrations::v1::MigrateToV1, - pallet_contracts::Migration, - // Run custom migrations - migrations::MultiMigration, -); + +pub type Migrations = (); /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, diff --git a/runtimes/eden/src/migrations.rs b/runtimes/eden/src/migrations.rs index b2475bec5d6..aeb819a073b 100644 --- a/runtimes/eden/src/migrations.rs +++ b/runtimes/eden/src/migrations.rs @@ -17,85 +17,19 @@ where + pallet_xcm::Config + pallet_preimage::Config + pallet_multisig::Config - + pallet_contracts::Config, + + pallet_contracts::Config + + pallet_uniques::Config + + pallet_nodle_uniques::Config, { fn on_runtime_upgrade() -> Weight { - // Pallets with no data to migrate, just update storage version block goes here: - - // Pallet_scheduler: 1 key - // Changed storage version to 3 and executed the v3 to v4 migration - // [2023-12-01T03:32:38Z INFO runtime::scheduler::migration] Trying to migrate 0 agendas... - // [2023-12-01T03:32:38Z INFO runtime::scheduler::migration] Migrated 0 agendas. - // *** No v3 agendas to migrate - - // The one present key is identified as - // 0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429: Raw - // scheduler.palletVersion: u16 = 0 - - // v2 -> v3 code changed: - // 5e50e0bc2c7 (Gavin Wood 2021-12-11 15:55:23 +0100 323) StorageVersion::::put(Releases::V3); - // *** Adding support for preimage, StorageMap format changed for Agenda - // Since chain contains 0 agendas it should be safe to write new storage version. - - // Onchain storage version = 4 in source code - unchanged any new data will be in the v4 format - - StorageVersion::new(4).put::>(); - - // TechnicalMembership -- 2 keys - // Storage version unchanged since 2021-09-07 - // 03b294641ef substrate/frame/membership/src/lib.rs (Qinxuan Chen 2021-09-07 20:17:26 +0800 - // No migration needed just update storage version - - // Onchain storage version = 4 in source code - unchanged any new data will be in the v4 format - - StorageVersion::new(4).put::>(); - - // TechnicalCommittee: pallet_collective:: - // Found 3 keys (0.19s) - // key: 0xed25f63942de25ac5253ba64b5eb64d1ba7fb8745735dc3be2a2c61a72c39e78 - // technicalCommittee.members: Vec list of valid keys. - // key: 0xed25f63942de25ac5253ba64b5eb64d16254e9d55588784fa2a62b726696e2b1 - // technicalCommittee.proposalCount: u32 = 329 - // key: 0xed25f63942de25ac5253ba64b5eb64d188c2f7188c6fdd1dffae2fa0d171f440 - // technicalCommittee.proposals: Vec = [] - - // Source code unchanged since 2021 - // 03b294641ef substrate/frame/membership/src/lib.rs (Qinxuan Chen 2021-09-07 20:17:26 +0800 44) const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); - // *** This commit changes from old to new frame macros, - // decl_storage!{ - // Members get(fn members): Vec; - // } - // changed to: - // #[pallet::storage] - // #[pallet::getter(fn members)] - // pub type Members, I: 'static = ()> = StorageValue<_, Vec, ValueQuery>; - // *** Migration code only included name change functions. - - // Onchain storage version = 4 in source code - unchanged any new data will be in the v4 format - - StorageVersion::new(4).put::>(); - - // https://github.com/paritytech/substrate/pull/12813 - // moves funds to inactive if we don't need that this is OK. - - // Onchain storage version = 1 in source code - unchanged any new data will be in the v1 format - - StorageVersion::new(1).put::>(); - - // Two keys already migrated. - // The call to pallet_xcm::migration::v1::MigrateToV1::::on_runtime_upgrade() fails. - // That migration code supposes that the value in the storage is of the old type which is not true, - // because two new values of the new type were inserted in the VersionNotifyTargets map which is - // the subject of that migration. One of the new values are for Moonbeam which got inserted in - // the block 3351853 which is the first block after the parachain restart and the second one is - // for Polkadot which got inserted in 3614349 16 days ago. I believe we don’t need this migration. - // If in the future there was any issue in any XCM interactions with Moonbeam we can force set the - // storage entry for that single value to use proof_size = 65536 (the new default). - StorageVersion::new(1).put::>(); - // Size of onchain storage is 0 safe to upgrade storage version // Onchain storage version = 1 in source code - unchanged any new data will be in the v1 format StorageVersion::new(1).put::>(); + // pallet_uniques adding a storage version not chaning anything + StorageVersion::new(1).put::>(); + + // Store version 0 for default + StorageVersion::new(0).put::>(); T::DbWeight::get().writes(6) } @@ -107,28 +41,8 @@ where log::info!("Pre upgrade"); ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("preimage storage version is not 0") - ); - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("pallet_xcm storage version is not 0") - ); - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("pallet_scheduler storage version is not 0") - ); - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("pallet_collective storage version is not 0") - ); - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("pallet_membership storage version is not 0") - ); - ensure!( - StorageVersion::get::>() == 0, - TryRuntimeError::Other("pallet_balances storage version is not 0") + StorageVersion::get::>() == 0, + TryRuntimeError::Other("pallet_uniques storage version is not 0") ); Ok(vec![]) @@ -136,33 +50,7 @@ where #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), TryRuntimeError> { - use frame_support::ensure; - log::info!("Post upgrade {_state:?}"); - ensure!( - StorageVersion::get::>() == 1, - TryRuntimeError::Other("preimage post upgrade storage version is not 1") - ); - ensure!( - StorageVersion::get::>() == 1, - TryRuntimeError::Other("pallet_xcm post upgrade storage version is not 1") - ); - ensure!( - StorageVersion::get::>() == 4, - TryRuntimeError::Other("pallet_scheduler post upgrade storage version is not 4") - ); - ensure!( - StorageVersion::get::>() == 4, - TryRuntimeError::Other("pallet_collective post upgrade storage version is not 4") - ); - ensure!( - StorageVersion::get::>() == 4, - TryRuntimeError::Other("pallet_membership post upgrade storage version is not 4") - ); - ensure!( - StorageVersion::get::>() == 1, - TryRuntimeError::Other("pallet_balances post upgrade storage version is not 1") - ); Ok(()) } diff --git a/runtimes/eden/src/pallets_governance.rs b/runtimes/eden/src/pallets_governance.rs index edf628b8efe..88144d45674 100644 --- a/runtimes/eden/src/pallets_governance.rs +++ b/runtimes/eden/src/pallets_governance.rs @@ -22,7 +22,7 @@ use frame_support::pallet_prelude::Weight; use frame_support::{parameter_types, traits::EitherOfDiverse, PalletId}; use frame_system::{EnsureNever, EnsureRoot}; use primitives::{AccountId, BlockNumber}; -pub use sp_runtime::{Perbill, Perquintill}; +pub use sp_runtime::Perbill; parameter_types! { pub const CompanyReservePalletId: PalletId = PalletId(*b"py/resrv"); // 5EYCAe5ijiYfha9GzQDgPVtUCYDY9B8ZgcyiANL2L34crMoR diff --git a/runtimes/eden/src/version.rs b/runtimes/eden/src/version.rs index a5df71794d7..b300fe330dc 100644 --- a/runtimes/eden/src/version.rs +++ b/runtimes/eden/src/version.rs @@ -40,7 +40,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // Version of the runtime specification. A full-node will not attempt to use its native // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, // `spec_version` and `authoring_version` are the same between Wasm and native. - spec_version: 27, + spec_version: 28, // Version of the implementation of the specification. Nodes are free to ignore this; it // serves only as an indication that the code is different; as long as the other two versions