From afeaf488246415e4f7e0f65962513a98b825230d Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Tue, 20 May 2025 15:03:48 +0400 Subject: [PATCH 1/3] Add migration for obsolete root epoch values. --- pallets/subtensor/src/macros/hooks.rs | 4 +- .../migrate_clear_root_epoch_values.rs | 98 ++++++++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + pallets/subtensor/src/tests/migration.rs | 121 +++++++++++++++++- 4 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index a0e2fc6e72..2a13507494 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -115,7 +115,9 @@ mod hooks { // Reset max burn .saturating_add(migrations::migrate_reset_max_burn::migrate_reset_max_burn::()) // Migrate ColdkeySwapScheduled structure to new format - .saturating_add(migrations::migrate_coldkey_swap_scheduled::migrate_coldkey_swap_scheduled::()); + .saturating_add(migrations::migrate_coldkey_swap_scheduled::migrate_coldkey_swap_scheduled::()) + // Clear epoch storage values for root netuid + .saturating_add(migrations::migrate_clear_root_epoch_values::migrate_clear_root_epoch_values::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs b/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs new file mode 100644 index 0000000000..a9ba3379d0 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs @@ -0,0 +1,98 @@ +use crate::Pallet as Subtensor; +use crate::{Config, HasMigrationRun}; +use alloc::string::String; +use frame_support::{traits::Get, weights::Weight}; + +// List of cleared maps for root netuid: +// - SubnetworkN +// - Tempo +// - ActivityCutoff +// - Bonds +// - Keys +// - MaxAllowedValidators +// - SubnetOwnerHotkey +// - Kappa +// - BondsPenalty +// - Yuma3On +// - BlockAtRegistration +// - Rank +// - Trust +// - Active +// - Emission +// - Consensus +// - Incentive +// - Dividends +// - LastUpdate +// - PruningScores +// - ValidatorTrust +// - ValidatorPermit +// - StakeWeight +pub fn migrate_clear_root_epoch_values() -> Weight { + let migration_name = b"migrate_clear_root_epoch_values".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + // Clear root epoch values + let root_netuid = Subtensor::::get_root_netuid(); + + crate::SubnetworkN::::remove(root_netuid); + crate::Tempo::::remove(root_netuid); + crate::ActivityCutoff::::remove(root_netuid); + crate::MaxAllowedValidators::::remove(root_netuid); + crate::SubnetOwnerHotkey::::remove(root_netuid); + + crate::Kappa::::remove(root_netuid); + crate::BondsPenalty::::remove(root_netuid); + crate::Yuma3On::::remove(root_netuid); + crate::Rank::::remove(root_netuid); + crate::Trust::::remove(root_netuid); + + crate::Active::::remove(root_netuid); + crate::Emission::::remove(root_netuid); + crate::Consensus::::remove(root_netuid); + crate::Incentive::::remove(root_netuid); + crate::Dividends::::remove(root_netuid); + + crate::LastUpdate::::remove(root_netuid); + crate::PruningScores::::remove(root_netuid); + crate::ValidatorTrust::::remove(root_netuid); + crate::ValidatorPermit::::remove(root_netuid); + crate::StakeWeight::::remove(root_netuid); + + let total_simple_removals = 20u64; + + let mut total_db_operations = total_simple_removals; + + let bonds_removal_res = crate::Bonds::::clear_prefix(root_netuid, u32::MAX, None); + let keys_removal_res = crate::Keys::::clear_prefix(root_netuid, u32::MAX, None); + let regblocks_removal_res = + crate::BlockAtRegistration::::clear_prefix(root_netuid, u32::MAX, None); + + total_db_operations = total_db_operations.saturating_add(bonds_removal_res.backend.into()); + total_db_operations = total_db_operations.saturating_add(keys_removal_res.backend.into()); + total_db_operations = total_db_operations.saturating_add(regblocks_removal_res.backend.into()); + weight = weight.saturating_add(T::DbWeight::get().writes(total_db_operations)); + + // Mark Migration as Completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully.", + String::from_utf8_lossy(&migration_name) + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 5c6347034f..661ad77359 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -4,6 +4,7 @@ use sp_io::KillStorageResult; use sp_io::hashing::twox_128; use sp_io::storage::clear_prefix; pub mod migrate_chain_identity; +pub mod migrate_clear_root_epoch_values; pub mod migrate_coldkey_swap_scheduled; pub mod migrate_commit_reveal_v2; pub mod migrate_create_root_network; diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 1dfac06ad5..a5566df069 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -6,7 +6,7 @@ use alloc::collections::BTreeMap; use approx::assert_abs_diff_eq; use codec::{Decode, Encode}; use frame_support::{ - StorageHasher, Twox64Concat, assert_ok, + StorageDoubleMap, StorageHasher, Twox64Concat, assert_ok, storage::unhashed::{get, get_raw, put, put_raw}, traits::{StorageInstance, StoredMap}, weights::Weight, @@ -820,3 +820,122 @@ fn test_migrate_remove_commitments_rate_limit() { assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); } + +#[test] +fn test_migrate_clear_root_epoch_values() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // Step 1: Simulate Old Storage Entry + // ------------------------------ + const MIGRATION_NAME: &str = "migrate_clear_root_epoch_values"; + + let root_netuid = Pallet::::get_root_netuid(); + + SubnetworkN::::insert(root_netuid, 0); + Tempo::::insert(root_netuid, 0); + ActivityCutoff::::insert(root_netuid, 0); + MaxAllowedValidators::::insert(root_netuid, 0); + SubnetOwnerHotkey::::insert(root_netuid, U256::from(1)); + + Kappa::::insert(root_netuid, 0); + BondsPenalty::::insert(root_netuid, 0); + Yuma3On::::insert(root_netuid, false); + Rank::::insert(root_netuid, Vec::::new()); + Trust::::insert(root_netuid, Vec::::new()); + + Active::::insert(root_netuid, Vec::::new()); + Emission::::insert(root_netuid, Vec::::new()); + Consensus::::insert(root_netuid, Vec::::new()); + Incentive::::insert(root_netuid, Vec::::new()); + Dividends::::insert(root_netuid, Vec::::new()); + + LastUpdate::::insert(root_netuid, Vec::::new()); + PruningScores::::insert(root_netuid, Vec::::new()); + ValidatorTrust::::insert(root_netuid, Vec::::new()); + ValidatorPermit::::insert(root_netuid, Vec::::new()); + StakeWeight::::insert(root_netuid, Vec::::new()); + + Bonds::::insert(root_netuid, root_netuid, Vec::<(u16, u16)>::new()); + Keys::::insert(root_netuid, root_netuid, U256::from(1)); + BlockAtRegistration::::insert(root_netuid, root_netuid, 0); + + assert!( + !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should not have run yet" + ); + + assert!(SubnetworkN::::contains_key(root_netuid)); + assert!(Tempo::::contains_key(root_netuid)); + assert!(ActivityCutoff::::contains_key(root_netuid)); + assert!(MaxAllowedValidators::::contains_key(root_netuid)); + assert!(SubnetOwnerHotkey::::contains_key(root_netuid)); + + assert!(Kappa::::contains_key(root_netuid)); + assert!(BondsPenalty::::contains_key(root_netuid)); + assert!(Yuma3On::::contains_key(root_netuid)); + assert!(Rank::::contains_key(root_netuid)); + assert!(Trust::::contains_key(root_netuid)); + + assert!(Active::::contains_key(root_netuid)); + assert!(Emission::::contains_key(root_netuid)); + assert!(Consensus::::contains_key(root_netuid)); + assert!(Incentive::::contains_key(root_netuid)); + assert!(Dividends::::contains_key(root_netuid)); + + assert!(LastUpdate::::contains_key(root_netuid)); + assert!(PruningScores::::contains_key(root_netuid)); + assert!(ValidatorTrust::::contains_key(root_netuid)); + assert!(ValidatorPermit::::contains_key(root_netuid)); + assert!(StakeWeight::::contains_key(root_netuid)); + + assert!(Bonds::::contains_prefix(root_netuid)); + assert!(Keys::::contains_prefix(root_netuid)); + assert!(BlockAtRegistration::::contains_prefix(root_netuid)); + + // ------------------------------ + // Step 2: Run the Migration + // ------------------------------ + let weight = + crate::migrations::migrate_clear_root_epoch_values::migrate_clear_root_epoch_values::< + Test, + >(); + + assert!( + HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), + "Migration should be marked as completed" + ); + + // ------------------------------ + // Step 3: Verify Migration Effects + // ------------------------------ + assert!(!SubnetworkN::::contains_key(root_netuid)); + assert!(!Tempo::::contains_key(root_netuid)); + assert!(!ActivityCutoff::::contains_key(root_netuid)); + assert!(!MaxAllowedValidators::::contains_key(root_netuid)); + assert!(!SubnetOwnerHotkey::::contains_key(root_netuid)); + + assert!(!Kappa::::contains_key(root_netuid)); + assert!(!BondsPenalty::::contains_key(root_netuid)); + assert!(!Yuma3On::::contains_key(root_netuid)); + assert!(!Rank::::contains_key(root_netuid)); + assert!(!Trust::::contains_key(root_netuid)); + + assert!(!Active::::contains_key(root_netuid)); + assert!(!Emission::::contains_key(root_netuid)); + assert!(!Consensus::::contains_key(root_netuid)); + assert!(!Incentive::::contains_key(root_netuid)); + assert!(!Dividends::::contains_key(root_netuid)); + + assert!(!LastUpdate::::contains_key(root_netuid)); + assert!(!PruningScores::::contains_key(root_netuid)); + assert!(!ValidatorTrust::::contains_key(root_netuid)); + assert!(!ValidatorPermit::::contains_key(root_netuid)); + assert!(!StakeWeight::::contains_key(root_netuid)); + + assert!(!Bonds::::contains_prefix(root_netuid)); + assert!(!Keys::::contains_prefix(root_netuid)); + assert!(!BlockAtRegistration::::contains_prefix(root_netuid)); + + assert!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +} From 8086f8ce6a1228ea1341e717a717cc4506ea7335 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Wed, 21 May 2025 14:54:02 +0400 Subject: [PATCH 2/3] Apply review suggestions --- .../migrate_clear_root_epoch_values.rs | 20 +------------------ pallets/subtensor/src/tests/migration.rs | 20 ------------------- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs b/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs index a9ba3379d0..5b1d61550c 100644 --- a/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs +++ b/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs @@ -4,17 +4,11 @@ use alloc::string::String; use frame_support::{traits::Get, weights::Weight}; // List of cleared maps for root netuid: -// - SubnetworkN -// - Tempo // - ActivityCutoff // - Bonds -// - Keys -// - MaxAllowedValidators -// - SubnetOwnerHotkey // - Kappa // - BondsPenalty // - Yuma3On -// - BlockAtRegistration // - Rank // - Trust // - Active @@ -47,42 +41,30 @@ pub fn migrate_clear_root_epoch_values() -> Weight { // Clear root epoch values let root_netuid = Subtensor::::get_root_netuid(); - crate::SubnetworkN::::remove(root_netuid); - crate::Tempo::::remove(root_netuid); crate::ActivityCutoff::::remove(root_netuid); - crate::MaxAllowedValidators::::remove(root_netuid); - crate::SubnetOwnerHotkey::::remove(root_netuid); - crate::Kappa::::remove(root_netuid); crate::BondsPenalty::::remove(root_netuid); crate::Yuma3On::::remove(root_netuid); crate::Rank::::remove(root_netuid); crate::Trust::::remove(root_netuid); - crate::Active::::remove(root_netuid); crate::Emission::::remove(root_netuid); crate::Consensus::::remove(root_netuid); crate::Incentive::::remove(root_netuid); crate::Dividends::::remove(root_netuid); - crate::LastUpdate::::remove(root_netuid); crate::PruningScores::::remove(root_netuid); crate::ValidatorTrust::::remove(root_netuid); crate::ValidatorPermit::::remove(root_netuid); crate::StakeWeight::::remove(root_netuid); - let total_simple_removals = 20u64; + let total_simple_removals = 16u64; let mut total_db_operations = total_simple_removals; let bonds_removal_res = crate::Bonds::::clear_prefix(root_netuid, u32::MAX, None); - let keys_removal_res = crate::Keys::::clear_prefix(root_netuid, u32::MAX, None); - let regblocks_removal_res = - crate::BlockAtRegistration::::clear_prefix(root_netuid, u32::MAX, None); total_db_operations = total_db_operations.saturating_add(bonds_removal_res.backend.into()); - total_db_operations = total_db_operations.saturating_add(keys_removal_res.backend.into()); - total_db_operations = total_db_operations.saturating_add(regblocks_removal_res.backend.into()); weight = weight.saturating_add(T::DbWeight::get().writes(total_db_operations)); // Mark Migration as Completed diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index a5566df069..ae8992e689 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -864,33 +864,23 @@ fn test_migrate_clear_root_epoch_values() { "Migration should not have run yet" ); - assert!(SubnetworkN::::contains_key(root_netuid)); - assert!(Tempo::::contains_key(root_netuid)); assert!(ActivityCutoff::::contains_key(root_netuid)); - assert!(MaxAllowedValidators::::contains_key(root_netuid)); - assert!(SubnetOwnerHotkey::::contains_key(root_netuid)); - assert!(Kappa::::contains_key(root_netuid)); assert!(BondsPenalty::::contains_key(root_netuid)); assert!(Yuma3On::::contains_key(root_netuid)); assert!(Rank::::contains_key(root_netuid)); assert!(Trust::::contains_key(root_netuid)); - assert!(Active::::contains_key(root_netuid)); assert!(Emission::::contains_key(root_netuid)); assert!(Consensus::::contains_key(root_netuid)); assert!(Incentive::::contains_key(root_netuid)); assert!(Dividends::::contains_key(root_netuid)); - assert!(LastUpdate::::contains_key(root_netuid)); assert!(PruningScores::::contains_key(root_netuid)); assert!(ValidatorTrust::::contains_key(root_netuid)); assert!(ValidatorPermit::::contains_key(root_netuid)); assert!(StakeWeight::::contains_key(root_netuid)); - assert!(Bonds::::contains_prefix(root_netuid)); - assert!(Keys::::contains_prefix(root_netuid)); - assert!(BlockAtRegistration::::contains_prefix(root_netuid)); // ------------------------------ // Step 2: Run the Migration @@ -908,33 +898,23 @@ fn test_migrate_clear_root_epoch_values() { // ------------------------------ // Step 3: Verify Migration Effects // ------------------------------ - assert!(!SubnetworkN::::contains_key(root_netuid)); - assert!(!Tempo::::contains_key(root_netuid)); assert!(!ActivityCutoff::::contains_key(root_netuid)); - assert!(!MaxAllowedValidators::::contains_key(root_netuid)); - assert!(!SubnetOwnerHotkey::::contains_key(root_netuid)); - assert!(!Kappa::::contains_key(root_netuid)); assert!(!BondsPenalty::::contains_key(root_netuid)); assert!(!Yuma3On::::contains_key(root_netuid)); assert!(!Rank::::contains_key(root_netuid)); assert!(!Trust::::contains_key(root_netuid)); - assert!(!Active::::contains_key(root_netuid)); assert!(!Emission::::contains_key(root_netuid)); assert!(!Consensus::::contains_key(root_netuid)); assert!(!Incentive::::contains_key(root_netuid)); assert!(!Dividends::::contains_key(root_netuid)); - assert!(!LastUpdate::::contains_key(root_netuid)); assert!(!PruningScores::::contains_key(root_netuid)); assert!(!ValidatorTrust::::contains_key(root_netuid)); assert!(!ValidatorPermit::::contains_key(root_netuid)); assert!(!StakeWeight::::contains_key(root_netuid)); - assert!(!Bonds::::contains_prefix(root_netuid)); - assert!(!Keys::::contains_prefix(root_netuid)); - assert!(!BlockAtRegistration::::contains_prefix(root_netuid)); assert!(!weight.is_zero(), "Migration weight should be non-zero"); }); From 49a0d87f08965fa6b5bec114a481dc25a7f7c9d6 Mon Sep 17 00:00:00 2001 From: Shamil Gadelshin Date: Thu, 29 May 2025 14:51:42 +0400 Subject: [PATCH 3/3] Bump spec version. --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 39a8b5dbe9..219b1673e3 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -209,7 +209,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 270, + spec_version: 272, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,