From 37e032e69a2a8c37a6c0d0d30dba43c1ea0ded50 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Wed, 20 May 2026 21:00:38 -0400 Subject: [PATCH 1/2] Disable TI checks in try-runtime --- pallets/subtensor/src/macros/hooks.rs | 1 - .../migrations/migrate_init_total_issuance.rs | 2 - pallets/subtensor/src/utils/try_state.rs | 57 ------------------- 3 files changed, 60 deletions(-) diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 205ae92267..557947ec66 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -182,7 +182,6 @@ mod hooks { #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { - Self::check_total_issuance()?; // Disabled: https://github.com/opentensor/subtensor/pull/1166 // Self::check_total_stake()?; Ok(()) diff --git a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs index 665c340076..a4fa157f57 100644 --- a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs @@ -155,8 +155,6 @@ pub mod initialise_total_issuance { /// This function is only compiled when the "try-runtime" feature is enabled. #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { - // Verify that all accounting invariants are satisfied after the migration - crate::Pallet::::check_total_issuance()?; Ok(()) } } diff --git a/pallets/subtensor/src/utils/try_state.rs b/pallets/subtensor/src/utils/try_state.rs index 8f43148d9f..605548ea6e 100644 --- a/pallets/subtensor/src/utils/try_state.rs +++ b/pallets/subtensor/src/utils/try_state.rs @@ -1,63 +1,6 @@ -use frame_support::traits::fungible::Inspect; -use frame_system::pallet_prelude::BlockNumberFor; - use super::*; impl Pallet { - /// Checks [`TotalIssuance`] equals the sum of currency issuance, total stake, and total subnet - /// locked. - #[allow(clippy::arithmetic_side_effects, clippy::expect_used)] - pub(crate) fn check_total_issuance() -> Result<(), sp_runtime::TryRuntimeError> { - // Get the total currency issuance - let currency_issuance = ::Currency::total_issuance(); - let total_issuance = TotalIssuance::::get(); - - log::info!("=== Try runtime check_total_issuance ==="); - log::info!(" currency_issuance: {}", currency_issuance); - log::info!(" total_issuance: {}", total_issuance); - - // If balances total issuance is greater than 21M, we're on devnet or testnet, ignore - // this check, TI is off for multiple reasons. - if currency_issuance > 21_000_000_000_000_000_u64.into() { - return Ok(()); - } - - // If there's an exact match, it means we are past imbalances upgrade - if currency_issuance == total_issuance { - return Ok(()); - } - - // Calculate the expected total issuance - let expected_total_issuance = - currency_issuance.saturating_add(TotalStake::::get().into()); - - // Verify the diff between calculated TI and actual TI is less than delta - // Allow greater tolerance for non-mainnet - let genesis_hash = frame_system::Pallet::::block_hash(BlockNumberFor::::zero()); - let genesis_bytes = genesis_hash.as_ref(); - let mainnet_genesis = - hex_literal::hex!("2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03"); - let delta = if genesis_bytes == mainnet_genesis { - TaoBalance::from(1000) - } else { - TaoBalance::from(1_000_000_000_000_u64) - }; - - let diff = if total_issuance > expected_total_issuance { - total_issuance.checked_sub(&expected_total_issuance) - } else { - expected_total_issuance.checked_sub(&total_issuance) - } - .expect("LHS > RHS"); - - ensure!( - diff <= delta, - "TotalIssuance diff greater than allowable delta", - ); - - Ok(()) - } - /// Checks the sum of all stakes matches the [`TotalStake`]. #[allow(dead_code)] pub(crate) fn check_total_stake() -> Result<(), sp_runtime::TryRuntimeError> { From 89d348d5387d9e11c228f72e62b1d4c5e18ecfa8 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Wed, 20 May 2026 22:10:35 -0400 Subject: [PATCH 2/2] Add migration to remove deprecated conviction maps --- pallets/subtensor/src/macros/hooks.rs | 4 +- ...grate_remove_deprecated_conviction_maps.rs | 105 ++++++++++++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 pallets/subtensor/src/migrations/migrate_remove_deprecated_conviction_maps.rs diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 205ae92267..f222fbc1d1 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -176,7 +176,9 @@ mod hooks { // Mint missing SubnetTAO and SubnetLocked into subnet accounts to make TotalIssuance match in balances and subtensor .saturating_add(migrations::migrate_subnet_balances::migrate_subnet_balances::()) // Fix testnet Subtensor TotalIssuance after the EVM fees issue. - .saturating_add(migrations::migrate_fix_total_issuance_evm_fees::migrate_fix_total_issuance_evm_fees::()); + .saturating_add(migrations::migrate_fix_total_issuance_evm_fees::migrate_fix_total_issuance_evm_fees::()) + // Remove deprecated conviction lock storage. + .saturating_add(migrations::migrate_remove_deprecated_conviction_maps::migrate_remove_deprecated_conviction_maps::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_remove_deprecated_conviction_maps.rs b/pallets/subtensor/src/migrations/migrate_remove_deprecated_conviction_maps.rs new file mode 100644 index 0000000000..cb6ca56f9b --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_remove_deprecated_conviction_maps.rs @@ -0,0 +1,105 @@ +use super::*; +use codec::{Decode, DecodeWithMemTracking, Encode}; +use frame_support::{ + pallet_prelude::{Blake2_128Concat, Identity, NMapKey, OptionQuery, ValueQuery}, + storage_alias, + traits::Get, + weights::Weight, +}; +use scale_info::{TypeInfo, prelude::string::String}; +use substrate_fixed::types::U64F64; + +pub mod deprecated { + use super::*; + + /// Deprecated lock state for a coldkey on a subnet. + #[crate::freeze_struct("13703236126f1b2b")] + #[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo)] + pub struct LockState { + /// Locked amount, stays constant unless user makes changes. + pub locked_mass: AlphaBalance, + /// Unlocked amount, gradually decays over time. + pub unlocked_mass: AlphaBalance, + /// Matured decaying score. + pub conviction: U64F64, + /// Block number of last roll-forward. + pub last_update: u64, + } + + #[storage_alias] + pub type Lock = StorageNMap< + Pallet, + ( + NMapKey>, + NMapKey, + NMapKey>, + ), + LockState, + OptionQuery, + >; + + #[storage_alias] + pub type HotkeyLock = StorageDoubleMap< + Pallet, + Identity, + NetUid, + Blake2_128Concat, + AccountIdOf, + LockState, + OptionQuery, + >; + + #[storage_alias] + pub type MaturityRate = StorageValue, u64, ValueQuery>; + + #[storage_alias] + pub type UnlockRate = StorageValue, u64, ValueQuery>; +} + +/// This migration removes the conviction v1 maps that were deprecated before they were +/// deployed on mainnet. They existed briefly on testnet and contain some values that need +/// to be cleaned before deploying conviction v2. +pub fn migrate_remove_deprecated_conviction_maps() -> Weight { + let migration_name = b"migrate_remove_deprecated_conviction_maps".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + String::from_utf8_lossy(&migration_name) + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + let lock_removal = deprecated::Lock::::clear(u32::MAX, None); + weight = weight.saturating_add( + T::DbWeight::get().reads_writes(lock_removal.loops as u64, lock_removal.backend as u64), + ); + + let hotkey_lock_removal = deprecated::HotkeyLock::::clear(u32::MAX, None); + weight = weight.saturating_add(T::DbWeight::get().reads_writes( + hotkey_lock_removal.loops as u64, + hotkey_lock_removal.backend as u64, + )); + + deprecated::MaturityRate::::kill(); + deprecated::UnlockRate::::kill(); + weight = weight.saturating_add(T::DbWeight::get().writes(2)); + + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully. Removed Lock entries: {:?}, HotkeyLock entries: {:?}.", + String::from_utf8_lossy(&migration_name), + lock_removal.backend, + hotkey_lock_removal.backend, + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index caad4b0851..f582a631fc 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -38,6 +38,7 @@ pub mod migrate_rate_limit_keys; pub mod migrate_rate_limiting_last_blocks; pub mod migrate_remove_add_stake_burn_rate_limit; pub mod migrate_remove_commitments_rate_limit; +pub mod migrate_remove_deprecated_conviction_maps; pub mod migrate_remove_network_modality; pub mod migrate_remove_old_identity_maps; pub mod migrate_remove_stake_map;