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..5b1d61550c --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_clear_root_epoch_values.rs @@ -0,0 +1,80 @@ +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: +// - ActivityCutoff +// - Bonds +// - Kappa +// - BondsPenalty +// - Yuma3On +// - 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::ActivityCutoff::::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 = 16u64; + + let mut total_db_operations = total_simple_removals; + + let bonds_removal_res = crate::Bonds::::clear_prefix(root_netuid, u32::MAX, None); + + total_db_operations = total_db_operations.saturating_add(bonds_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..ae8992e689 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,102 @@ 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!(ActivityCutoff::::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)); + + // ------------------------------ + // 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!(!ActivityCutoff::::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!(!weight.is_zero(), "Migration weight should be non-zero"); + }); +}