use super::*; use frame_support::{ storage_alias, traits::{Get, GetStorageVersion, StorageVersion}, weights::Weight, }; use log::{info, warn}; use sp_std::vec::Vec; use subtensor_runtime_common::NetUid; /// Constant for logging purposes const LOG_TARGET: &str = "loadedemissionmigration"; const LOG_TARGET_1: &str = "fixtotalstakestorage"; /// Module containing deprecated storage format pub mod deprecated_loaded_emission_format { use super::*; type AccountIdOf = ::AccountId; #[storage_alias] pub(super) type LoadedEmission = StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; } /// Migrates the LoadedEmission storage to a new format /// /// # Arguments /// /// * `T` - The runtime configuration trait /// /// # Returns /// /// * `Weight` - The computational weight of this operation /// /// # Example /// /// ```ignore /// let weight = migrate_to_v1_separate_emission::(); /// ``` pub fn migrate_to_v1_separate_emission() -> Weight { use deprecated_loaded_emission_format as old; // Initialize weight counter let mut weight = T::DbWeight::get().reads_writes(1, 0); // Get current on-chain storage version let onchain_version = Pallet::::on_chain_storage_version(); // Only proceed if current version is less than 1 if onchain_version < 1 { info!( target: LOG_TARGET, ">>> Updating the LoadedEmission to a new format {onchain_version:?}" ); // Collect all network IDs (netuids) from old LoadedEmission storage let curr_loaded_emission: Vec = old::LoadedEmission::::iter_keys().collect(); // Remove any undecodable entries for netuid in curr_loaded_emission { weight.saturating_accrue(T::DbWeight::get().reads(1)); if old::LoadedEmission::::try_get(netuid).is_err() { weight.saturating_accrue(T::DbWeight::get().writes(1)); old::LoadedEmission::::remove(netuid); warn!("Was unable to decode old loaded_emission for netuid {netuid}"); } } // Translate old storage values to new format LoadedEmission::::translate::, u64)>, _>( |netuid: NetUid, netuid_emissions: Vec<(AccountIdOf, u64)>| -> Option, u64, u64)>> { info!(target: LOG_TARGET, " Do migration of netuid: {netuid:?}..."); // Convert old format (server, validator_emission) to new format (server, server_emission, validator_emission) // Assume all loaded emission is validator emissions let new_netuid_emissions = netuid_emissions .into_iter() .map(|(server, validator_emission)| (server, 0_u64, validator_emission)) .collect(); // Update weight for read and write operations weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); Some(new_netuid_emissions) }, ); // Update storage version to 1 StorageVersion::new(1).put::>(); weight.saturating_accrue(T::DbWeight::get().writes(1)); weight } else { info!(target: LOG_TARGET_1, "Migration to v1 already completed!"); Weight::zero() } } // TODO: Add unit tests for this migration // TODO: Consider adding error handling for edge cases // TODO: Verify that all possible states of the old format are handled correctly