diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index 9a7e4f6abd..a53c8d562f 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -390,7 +390,7 @@ impl Pallet { .iter() .map(|updated| updated.saturating_add(activity_cutoff) < current_block) .collect(); - log::trace!("Inactive: {:?}", inactive.clone()); + log::debug!("Inactive: {:?}", inactive.clone()); // Logical negation of inactive. let active: Vec = inactive.iter().map(|&b| !b).collect(); @@ -406,14 +406,14 @@ impl Pallet { let hotkeys: Vec<(u16, T::AccountId)> = as IterableStorageDoubleMap>::iter_prefix(netuid) .collect(); - log::trace!("hotkeys: {:?}", &hotkeys); + log::debug!("hotkeys: {:?}", &hotkeys); // Access network stake as normalized vector. let (mut total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = Self::get_stake_weights_for_network(netuid); inplace_normalize_64(&mut total_stake); let stake: Vec = vec_fixed64_to_fixed32(total_stake); - log::trace!("Normalised Stake: {:?}", &stake); + log::debug!("Normalised Stake: {:?}", &stake); // ======================= // == Validator permits == @@ -448,7 +448,7 @@ impl Pallet { // Normalize active stake. inplace_normalize(&mut active_stake); - log::trace!("Active Stake:\n{:?}\n", &active_stake); + log::debug!("Active Stake:\n{:?}\n", &active_stake); // ============= // == Weights == diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index dfb2a8c2c9..0ef0029f9f 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -998,18 +998,6 @@ pub mod pallet { #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns the vector of hotkeys controlled by this coldkey. pub type OwnedHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - #[pallet::storage] - /// (DEPRECATED) DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. - pub type Stake = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Identity, - T::AccountId, - u64, - ValueQuery, - DefaultZeroU64, - >; #[pallet::storage] // --- DMAP ( cold ) --> () | Maps coldkey to if a coldkey swap is scheduled. pub type ColdkeySwapScheduled = diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 3a0a0ecb16..812b840f50 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -63,12 +63,6 @@ mod hooks { // Populate OwnedHotkeys map for coldkey swap. Doesn't update storage vesion. // Storage version v6 -> v7 .saturating_add(migrations::migrate_populate_owned_hotkeys::migrate_populate_owned::()) - // Populate StakingHotkeys map for coldkey swap. Doesn't update storage vesion. - // Storage version v7 -> v8 - .saturating_add(migrations::migrate_populate_staking_hotkeys::migrate_populate_staking_hotkeys::()) - // Fix total coldkey stake. - // Storage version v8 -> v9 - .saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::()) // Migrate Delegate Ids on chain .saturating_add(migrations::migrate_chain_identity::migrate_set_hotkey_identities::()) // Migrate Commit-Reval 2.0 @@ -83,7 +77,9 @@ mod hooks { // Set the min burn across all subnets to a new minimum .saturating_add(migrations::migrate_set_min_burn::migrate_set_min_burn::()) // Set the min difficulty across all subnets to a new minimum - .saturating_add(migrations::migrate_set_min_difficulty::migrate_set_min_difficulty::()); + .saturating_add(migrations::migrate_set_min_difficulty::migrate_set_min_difficulty::()) + // Remove Stake map entries + .saturating_add(migrations::migrate_remove_stake_map::migrate_remove_stake_map::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs deleted file mode 100644 index cf9701f5ee..0000000000 --- a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs +++ /dev/null @@ -1,91 +0,0 @@ -use super::*; -use alloc::string::String; -use frame_support::{ - pallet_prelude::{Identity, OptionQuery}, - storage_alias, - traits::{Get, StorageVersion}, - weights::Weight, -}; -use sp_std::vec::Vec; - -// TODO (camfairchild): TEST MIGRATION -pub mod deprecated_loaded_emission_format { - use super::*; - - #[storage_alias] - pub(super) type LoadedEmission = - StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; -} - -/// Migrates and fixes the total coldkey stake. -/// -/// This function iterates through all staking hotkeys, calculates the total stake for each coldkey, -/// and updates the `TotalColdkeyStake` storage accordingly. The migration is only performed if the -/// on-chain storage version is 6. -/// -/// # Returns -/// The weight of the migration process. -pub fn do_migrate_fix_total_coldkey_stake() -> Weight { - // Initialize the weight with one read operation. - let mut weight = T::DbWeight::get().reads(1); - - // Iterate through all staking hotkeys. - for (coldkey, hotkey_vec) in StakingHotkeys::::iter() { - // Init the zero value. - let mut coldkey_stake_sum: u64 = 0; - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - - // Calculate the total stake for the current coldkey. - for hotkey in hotkey_vec { - // Cant fail on retrieval. - coldkey_stake_sum = - coldkey_stake_sum.saturating_add(Stake::::get(hotkey, coldkey.clone())); - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - } - // Update the `TotalColdkeyStake` storage with the calculated stake sum. - // Cant fail on insert. - // TotalColdkeyStake::::insert(coldkey.clone(), coldkey_stake_sum); - // weight = weight.saturating_add(T::DbWeight::get().writes(1)); - } - weight -} -// Public migrate function to be called by Lib.rs on upgrade. -pub fn migrate_fix_total_coldkey_stake() -> Weight { - let migration_name = b"fix_total_coldkey_stake_v7".to_vec(); - - // Initialize the weight with one read operation. - let mut weight = T::DbWeight::get().reads(1); - - // Check if the migration has already run - if HasMigrationRun::::get(&migration_name) { - log::info!( - "Migration '{:?}' has already run. Skipping.", - migration_name - ); - return Weight::zero(); - } - - log::info!( - "Running migration '{}'", - String::from_utf8_lossy(&migration_name) - ); - - // Run the migration - weight = weight.saturating_add(do_migrate_fix_total_coldkey_stake::()); - - // Mark the migration as completed - HasMigrationRun::::insert(&migration_name, true); - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - - // Set the storage version to 7 - StorageVersion::new(7).put::>(); - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - - log::info!( - "Migration '{:?}' completed. Storage version set to 7.", - String::from_utf8_lossy(&migration_name) - ); - - // Return the migration weight. - weight -} diff --git a/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs b/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs deleted file mode 100644 index 0245ae3c9d..0000000000 --- a/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::*; -use frame_support::{ - pallet_prelude::{Identity, OptionQuery}, - storage_alias, - traits::Get, - weights::Weight, -}; -use log::info; -use sp_std::vec::Vec; -const LOG_TARGET_1: &str = "migrate_populate_owned"; - -/// Module containing deprecated storage format for LoadedEmission -pub mod deprecated_loaded_emission_format { - use super::*; - - #[storage_alias] - pub(super) type LoadedEmission = - StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; -} - -/// Populate the StakingHotkeys map from Stake map -pub fn migrate_populate_staking_hotkeys() -> Weight { - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - let migration_name = "Populate StakingHotkeys map"; - - // Check if this migration is needed (if StakingHotkeys map is empty) - let migrate = StakingHotkeys::::iter().next().is_none(); - - // Only runs if the migration is needed - if migrate { - info!(target: LOG_TARGET_1, ">>> Starting Migration: {}", migration_name); - - let mut longest_hotkey_vector: usize = 0; - let mut longest_coldkey: Option = None; - let mut keys_touched: u64 = 0; - let mut storage_reads: u64 = 0; - let mut storage_writes: u64 = 0; - - // Iterate through all Owner entries - Stake::::iter().for_each(|(hotkey, coldkey, stake)| { - storage_reads = storage_reads.saturating_add(1); // Read from Owner storage - if stake > 0 { - let mut hotkeys = StakingHotkeys::::get(&coldkey); - storage_reads = storage_reads.saturating_add(1); // Read from StakingHotkeys storage - - // Add the hotkey if it's not already in the vector - if !hotkeys.contains(&hotkey) { - hotkeys.push(hotkey); - keys_touched = keys_touched.saturating_add(1); - - // Update longest hotkey vector info - if longest_hotkey_vector < hotkeys.len() { - longest_hotkey_vector = hotkeys.len(); - longest_coldkey = Some(coldkey.clone()); - } - - // Update the StakingHotkeys storage - StakingHotkeys::::insert(&coldkey, hotkeys); - storage_writes = storage_writes.saturating_add(1); // Write to StakingHotkeys storage - } - - // Accrue weight for reads and writes - weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1)); - } - }); - - // Log migration results - info!( - target: LOG_TARGET_1, - "Migration {} finished. Keys touched: {}, Longest hotkey vector: {}, Storage reads: {}, Storage writes: {}", - migration_name, keys_touched, longest_hotkey_vector, storage_reads, storage_writes - ); - if let Some(c) = longest_coldkey { - info!(target: LOG_TARGET_1, "Longest hotkey vector is controlled by: {:?}", c); - } - - weight - } else { - info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); - Weight::zero() - } -} diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 09201dbc4d..3b2de079e5 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -4,7 +4,6 @@ use frame_support::IterableStorageMap; use frame_support::{traits::Get, weights::Weight}; use sp_runtime::format; use substrate_fixed::types::I96F32; -use substrate_fixed::types::U64F64; use super::*; @@ -36,29 +35,30 @@ pub fn migrate_rao() -> Weight { DynamicBlock::::set(Pallet::::get_current_block_as_u64()); // Migrate all TAO to root. - Stake::::iter().for_each(|(hotkey, coldkey, stake)| { - // Increase SubnetTAO on root. - SubnetTAO::::mutate(0, |total| { - *total = total.saturating_add(stake); - }); - // Increase SubnetAlphaOut on root. - SubnetAlphaOut::::mutate(0, |total| { - *total = total.saturating_add(stake); - }); - // Set all the stake on root 0 subnet. - Alpha::::mutate((hotkey.clone(), coldkey.clone(), 0), |total| { - *total = total.saturating_add(U64F64::saturating_from_num(stake)) - }); - TotalHotkeyShares::::mutate(hotkey.clone(), 0, |total| { - *total = total.saturating_add(U64F64::saturating_from_num(stake)) - }); - // Set the total stake on the hotkey - TotalHotkeyAlpha::::mutate(hotkey.clone(), 0, |total| { - *total = total.saturating_add(stake) - }); - // 6 reads and 6 writes. - weight = weight.saturating_add(T::DbWeight::get().reads_writes(6, 6)); - }); + // This migration has already run, leaving this only for reference for now, since this is a recent migration + // Stake::::iter().for_each(|(hotkey, coldkey, stake)| { + // // Increase SubnetTAO on root. + // SubnetTAO::::mutate(0, |total| { + // *total = total.saturating_add(stake); + // }); + // // Increase SubnetAlphaOut on root. + // SubnetAlphaOut::::mutate(0, |total| { + // *total = total.saturating_add(stake); + // }); + // // Set all the stake on root 0 subnet. + // Alpha::::mutate((hotkey.clone(), coldkey.clone(), 0), |total| { + // *total = total.saturating_add(U64F64::saturating_from_num(stake)) + // }); + // TotalHotkeyShares::::mutate(hotkey.clone(), 0, |total| { + // *total = total.saturating_add(U64F64::saturating_from_num(stake)) + // }); + // // Set the total stake on the hotkey + // TotalHotkeyAlpha::::mutate(hotkey.clone(), 0, |total| { + // *total = total.saturating_add(stake) + // }); + // // 6 reads and 6 writes. + // weight = weight.saturating_add(T::DbWeight::get().reads_writes(6, 6)); + // }); // Convert subnets and give them lock. // Set global weight to 18% from the start diff --git a/pallets/subtensor/src/migrations/migrate_remove_stake_map.rs b/pallets/subtensor/src/migrations/migrate_remove_stake_map.rs new file mode 100644 index 0000000000..650c47a669 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_remove_stake_map.rs @@ -0,0 +1,62 @@ +use super::*; +use crate::HasMigrationRun; +use frame_support::{traits::Get, weights::Weight}; +use scale_info::prelude::string::String; +use sp_io::{KillStorageResult, hashing::twox_128, storage::clear_prefix}; + +pub fn migrate_remove_stake_map() -> Weight { + let migration_name = b"migrate_remove_stake_map".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) + ); + + // ------------------------------ + // Step 1: Remove Stake entries + // ------------------------------ + + let mut stake_prefix = Vec::new(); + stake_prefix.extend_from_slice(&twox_128("SubtensorModule".as_bytes())); + stake_prefix.extend_from_slice(&twox_128("Stake".as_bytes())); + + let removal_results = clear_prefix(&stake_prefix, Some(u32::MAX)); + + let removed_entries_count = match removal_results { + KillStorageResult::AllRemoved(removed) => removed as u64, + KillStorageResult::SomeRemaining(removed) => { + log::info!("Failed To Remove Some Items During {:?}", migration_name); + removed as u64 + } + }; + + weight = weight.saturating_add(T::DbWeight::get().writes(removed_entries_count)); + + log::info!( + "Removed {:?} entries from Stake map.", + removed_entries_count + ); + + // ------------------------------ + // Step 2: 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/migrate_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_total_issuance.rs index c9558f2c8d..c00bb916b8 100644 --- a/pallets/subtensor/src/migrations/migrate_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_total_issuance.rs @@ -43,10 +43,13 @@ pub fn migrate_total_issuance(test: bool) -> Weight { // Execute migration if the current storage version is 5 or if in test mode if Pallet::::on_chain_storage_version() == StorageVersion::new(5) || test { // Calculate the sum of all stake values - let stake_sum: u64 = - Stake::::iter().fold(0, |acc, (_, _, stake)| acc.saturating_add(stake)); - // Add weight for reading all stake entries - weight = weight.saturating_add(T::DbWeight::get().reads(Stake::::iter().count() as u64)); + let stake_sum: u64 = Owner::::iter() + .map(|(hotkey, _coldkey)| Pallet::::get_total_stake_for_hotkey(&hotkey)) + .fold(0, |acc, stake| acc.saturating_add(stake)); + // Add weight for reading all Owner and TotalHotkeyStake entries + weight = weight.saturating_add( + T::DbWeight::get().reads((Owner::::iter().count() as u64).saturating_mul(2)), + ); // Calculate the sum of all locked subnet values let locked_sum: u64 = diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index e16adf46aa..b8754c07bf 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -5,12 +5,11 @@ pub mod migrate_create_root_network; pub mod migrate_delete_subnet_21; pub mod migrate_delete_subnet_3; pub mod migrate_fix_is_network_member; -pub mod migrate_fix_total_coldkey_stake; pub mod migrate_identities_v2; pub mod migrate_init_total_issuance; pub mod migrate_populate_owned_hotkeys; -pub mod migrate_populate_staking_hotkeys; pub mod migrate_rao; +pub mod migrate_remove_stake_map; pub mod migrate_set_min_burn; pub mod migrate_set_min_difficulty; pub mod migrate_stake_threshold; diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 15b7ecbaf1..b949d4d191 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -63,10 +63,12 @@ impl Pallet { .iter() .map(|hotkey| { let mut total_stake: u64 = 0; - for (netuid, alpha) in Alpha::::iter_prefix((hotkey, coldkey)) { + for (netuid, _) in Alpha::::iter_prefix((hotkey, coldkey)) { + let alpha_stake = + Self::get_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid); let tao_price: I96F32 = Self::get_alpha_price(netuid); total_stake = total_stake.saturating_add( - I96F32::saturating_from_num(alpha) + I96F32::saturating_from_num(alpha_stake) .saturating_mul(tao_price) .saturating_to_num::(), ); @@ -80,7 +82,6 @@ impl Pallet { // pub fn create_account_if_non_existent(coldkey: &T::AccountId, hotkey: &T::AccountId) { if !Self::hotkey_account_exists(hotkey) { - Stake::::insert(hotkey, coldkey, 0); // This is the way to index coldkeys by a hotkey Owner::::insert(hotkey, coldkey); // Update OwnedHotkeys map diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 9b76600bb1..0a3659b6ac 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -167,7 +167,7 @@ impl Pallet { } }) .collect(); - log::trace!("alpha_stake: {:?}", alpha_stake); + log::debug!("alpha_stake: {:?}", alpha_stake); // Step 3: Calculate the global tao stake vector. // Initialize a vector to store global tao stakes for each neuron. @@ -322,7 +322,7 @@ impl Pallet { // Step 1: Retrieve the initial total stake (alpha) for the hotkey on the specified subnet. let initial_alpha: I96F32 = I96F32::saturating_from_num(Self::get_stake_for_hotkey_on_subnet(hotkey, netuid)); - log::trace!( + log::debug!( "Initial alpha for hotkey {:?} on subnet {}: {:?}", hotkey, netuid, @@ -339,13 +339,13 @@ impl Pallet { // Step 2: Retrieve the lists of parents and children for the hotkey on the subnet. let parents: Vec<(u64, T::AccountId)> = Self::get_parents(hotkey, netuid); let children: Vec<(u64, T::AccountId)> = Self::get_children(hotkey, netuid); - log::trace!( + log::debug!( "Parents for hotkey {:?} on subnet {}: {:?}", hotkey, netuid, parents ); - log::trace!( + log::debug!( "Children for hotkey {:?} on subnet {}: {:?}", hotkey, netuid, @@ -370,7 +370,7 @@ impl Pallet { // Add this child's allocation to the total alpha allocated to children. alpha_to_children = alpha_to_children.saturating_add(alpha_proportion_to_child); } - log::trace!("Total alpha allocated to children: {:?}", alpha_to_children); + log::debug!("Total alpha allocated to children: {:?}", alpha_to_children); // Step 4: Calculate the total alpha inherited from parents. for (proportion, parent) in parents { @@ -403,7 +403,7 @@ impl Pallet { // Add this parent's contribution to the total alpha inherited from parents. alpha_from_parents = alpha_from_parents.saturating_add(alpha_proportion_from_parent); } - log::trace!( + log::debug!( "Total alpha inherited from parents: {:?}", alpha_from_parents ); diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index b505cd58e9..7047a204e1 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -157,16 +157,8 @@ impl Pallet { } // 3. Swap Stake. - // Stake: MAP ( hotkey, coldkey ) --> u64 | Stake of the hotkey for the coldkey. + // StakingHotkeys: MAP ( coldkey ) --> Vec( hotkey ) for hotkey in StakingHotkeys::::get(old_coldkey) { - // Get the stake on the old (hot,coldkey) account. - let old_stake: u64 = Stake::::get(&hotkey, old_coldkey); - // Get the stake on the new (hot,coldkey) account. - let new_stake: u64 = Stake::::get(&hotkey, new_coldkey); - // Add the stake to new account. - Stake::::insert(&hotkey, new_coldkey, new_stake.saturating_add(old_stake)); - // Remove the value from the old account. - Stake::::remove(&hotkey, old_coldkey); // 3.1 Swap Alpha for netuid in Self::get_all_subnet_netuids() { // Get the stake on the old (hot,coldkey) account. diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index ffe9dca8d9..74070faaca 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -333,28 +333,6 @@ impl Pallet { } } - // 11. Swap Stake. - // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. - let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); - // Clear the entire old prefix here. - let _ = Stake::::clear_prefix(old_hotkey, stakes.len() as u32, None); - // Iterate over all the staking rows and insert them into the new hotkey. - for (coldkey, old_stake_amount) in stakes { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - - // Swap Stake value - // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. - // Get the new stake value. - let new_stake_value: u64 = Stake::::get(new_hotkey, &coldkey); - // Insert the new stake value. - Stake::::insert( - new_hotkey, - &coldkey, - new_stake_value.saturating_add(old_stake_amount), - ); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - // 12. Swap ChildKeys. // ChildKeys( parent, netuid ) --> Vec<(proportion,child)> -- the child keys of the parent. for netuid in Self::get_all_subnet_netuids() { diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index 25bac7fe95..bdfbbfbf30 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -2897,210 +2897,120 @@ fn test_set_weights_no_parent() { }); } -/// Test that drain_hotkey_emission sends childkey take fully to the childkey. +/// Test that drain_pending_emission sends childkey take fully to the nominators if childkey +/// doesn't have its own stake, independently of parent hotkey take. #[allow(clippy::assertions_on_constants)] #[test] fn test_childkey_take_drain() { - new_test_ext(1).execute_with(|| { - let subnet_owner_coldkey = U256::from(1001); - let subnet_owner_hotkey = U256::from(1002); - let coldkey = U256::from(1); - let parent = U256::from(2); - let child = U256::from(3); - let nominator = U256::from(4); - let root_id: u16 = 0; - let subnet_tempo = 10; - let stake = 100_000_000_000; - let proportion: u64 = u64::MAX; - - // Add network, register hotkeys, and setup network parameters - add_network(root_id, subnet_tempo, 0); - let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - crate::Tempo::::set(netuid, subnet_tempo); - register_ok_neuron(netuid, child, coldkey, 0); - register_ok_neuron(netuid, parent, coldkey, 1); - - // Set children - mock_set_children(&coldkey, &parent, netuid, &[(proportion, child)]); - - SubtensorModule::add_balance_to_coldkey_account( - &coldkey, - stake + ExistentialDeposit::get(), - ); - SubtensorModule::add_balance_to_coldkey_account( - &nominator, - stake + ExistentialDeposit::get(), - ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); - SubtensorModule::set_max_allowed_validators(netuid, 2); - step_block(subnet_tempo); - crate::SubnetOwnerCut::::set(0); - - // Set 20% childkey take - let max_take: u16 = 0xFFFF / 5; - SubtensorModule::set_max_childkey_take(max_take); - assert_ok!(SubtensorModule::set_childkey_take( - RuntimeOrigin::signed(coldkey), - child, - netuid, - max_take - )); - - // Set zero hotkey take for childkey - SubtensorModule::set_min_delegate_take(0); - - // Setup stakes: - // Stake from parent - // Stake from nominator to childkey - // Give 100% of parent stake to childkey - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - stake - )); - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(nominator), - child, - netuid, - stake - )); - - // Setup YUMA so that it creates emissions: - // Parent and child both set weights - // Parent and child register on root and - // Set root weights - crate::Weights::::insert(netuid, 0, vec![(0, 0xFFFF), (1, 0xFFFF)]); - crate::Weights::::insert(netuid, 1, vec![(0, 0xFFFF), (1, 0xFFFF)]); - assert_ok!(SubtensorModule::do_root_register( - RuntimeOrigin::signed(coldkey), - parent, - )); - assert_ok!(SubtensorModule::do_root_register( - RuntimeOrigin::signed(coldkey), - child, - )); - crate::Weights::::insert(root_id, 0, vec![(0, 0xFFFF), (1, 0xFFFF)]); - crate::Weights::::insert(root_id, 1, vec![(0, 0xFFFF), (1, 0xFFFF)]); - - // Verify how emission is split between keys - // - Child stake increased by its child key take only (20% * 50% = 10% of total emission) - // - Parent stake increased by 40% of total emission - // - Nominator stake increased by 50% of total emission - let child_emission = crate::Stake::::get(child, coldkey); - let parent_emission = crate::Stake::::get(parent, coldkey).saturating_sub(stake); - let nominator_emission = crate::Stake::::get(child, nominator).saturating_sub(stake); - let total_emission = child_emission + parent_emission + nominator_emission; - - assert_abs_diff_eq!(child_emission, total_emission / 10, epsilon = 500); - assert_abs_diff_eq!(parent_emission, total_emission / 10 * 4, epsilon = 500); - assert_abs_diff_eq!(nominator_emission, total_emission / 2, epsilon = 500); - }); -} + // Test cases: parent_hotkey_take + [0_u16, u16::MAX / 5].iter().for_each(|parent_hotkey_take| { + new_test_ext(1).execute_with(|| { + let parent_coldkey = U256::from(1); + let parent_hotkey = U256::from(3); + let child_coldkey = U256::from(2); + let child_hotkey = U256::from(4); + let miner_coldkey = U256::from(5); + let miner_hotkey = U256::from(6); + let nominator = U256::from(7); + let netuid: u16 = 1; + let subnet_tempo = 10; + let stake = 100_000_000_000; + let proportion: u64 = u64::MAX / 2; + + // Add network, register hotkeys, and setup network parameters + add_network(netuid, subnet_tempo, 0); + register_ok_neuron(netuid, child_hotkey, child_coldkey, 0); + register_ok_neuron(netuid, parent_hotkey, parent_coldkey, 1); + register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 1); + SubtensorModule::add_balance_to_coldkey_account( + &parent_coldkey, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::add_balance_to_coldkey_account( + &nominator, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_max_allowed_validators(netuid, 2); + step_block(subnet_tempo); + SubnetOwnerCut::::set(0); -/// Test that drain_hotkey_emission sends childkey take fully to the childkey with validator take enabled. -#[test] -fn test_childkey_take_drain_validator_take() { - new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let parent = U256::from(2); - let child = U256::from(3); - let nominator = U256::from(4); - let netuid: u16 = 1; - let root_id: u16 = 0; - let subnet_tempo = 10; - let hotkey_tempo = 20; - let stake = 100_000_000_000; - let proportion: u64 = u64::MAX; - - // Add network, register hotkeys, and setup network parameters - add_network(root_id, subnet_tempo, 0); - add_network(netuid, subnet_tempo, 0); - register_ok_neuron(netuid, child, coldkey, 0); - register_ok_neuron(netuid, parent, coldkey, 1); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey, - stake + ExistentialDeposit::get(), - ); - SubtensorModule::add_balance_to_coldkey_account( - &nominator, - stake + ExistentialDeposit::get(), - ); - SubtensorModule::set_weights_set_rate_limit(netuid, 0); - SubtensorModule::set_max_allowed_validators(netuid, 2); - step_block(subnet_tempo); - crate::SubnetOwnerCut::::set(0); + // Set children + mock_set_children_no_epochs(netuid, &parent_hotkey, &[(proportion, child_hotkey)]); - // Set children - mock_set_children(&coldkey, &parent, netuid, &[(proportion, child)]); + // Set 20% childkey take + let max_take: u16 = 0xFFFF / 5; + SubtensorModule::set_max_childkey_take(max_take); + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(child_coldkey), + child_hotkey, + netuid, + max_take + )); - // Set 20% childkey take - let max_take: u16 = 0xFFFF / 5; - SubtensorModule::set_max_childkey_take(max_take); - assert_ok!(SubtensorModule::set_childkey_take( - RuntimeOrigin::signed(coldkey), - child, - netuid, - max_take - )); + // Set hotkey take for parent + SubtensorModule::set_max_delegate_take(*parent_hotkey_take); + Delegates::::insert(parent_hotkey, *parent_hotkey_take); - // Set 20% hotkey take for childkey - // Set 20% hotkey take for parent - SubtensorModule::set_max_delegate_take(max_take); + // Set 0% for childkey-as-a-delegate take + Delegates::::insert(child_hotkey, 0); - // Setup stakes: - // Stake from parent - // Stake from nominator to childkey - // Give 100% of parent stake to childkey - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - stake - )); - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(nominator), - child, - netuid, - stake - )); + // Setup stakes: + // Stake from parent + // Stake from nominator to childkey + // Parent gives 50% of stake to childkey + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(parent_coldkey), + parent_hotkey, + netuid, + stake + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(nominator), + child_hotkey, + netuid, + stake + )); - // Setup YUMA so that it creates emissions: - // Parent and child both set weights - // Parent and child register on root and - // Set root weights - crate::Weights::::insert(netuid, 0, vec![(0, 0xFFFF), (1, 0xFFFF)]); - crate::Weights::::insert(netuid, 1, vec![(0, 0xFFFF), (1, 0xFFFF)]); - assert_ok!(SubtensorModule::do_root_register( - RuntimeOrigin::signed(coldkey), - parent, - )); - assert_ok!(SubtensorModule::do_root_register( - RuntimeOrigin::signed(coldkey), - child, - )); - crate::Weights::::insert(root_id, 0, vec![(0, 0xFFFF), (1, 0xFFFF)]); - crate::Weights::::insert(root_id, 1, vec![(0, 0xFFFF), (1, 0xFFFF)]); - - // Prevent further subnet epochs - crate::Tempo::::set(netuid, u16::MAX); - crate::Tempo::::set(root_id, u16::MAX); - - // Run run_coinbase until PendingHotkeyEmission is drained for both child and parent - step_block((hotkey_tempo * 2) as u16); - - // Verify how emission is split between keys - // - Child stake increased by its child key take (20% * 50% = 10% of total emission) plus childkey's delegate take (10%) - // - Parent stake increased by 40% of total emission - // - Nominator stake increased by 40% of total emission - let child_emission = crate::Stake::::get(child, coldkey); - let parent_emission = crate::Stake::::get(parent, coldkey).saturating_sub(stake); - let nominator_emission = crate::Stake::::get(child, nominator).saturating_sub(stake); - let total_emission = child_emission + parent_emission + nominator_emission; - - assert_abs_diff_eq!(child_emission, total_emission / 5, epsilon = 500); - assert_abs_diff_eq!(parent_emission, total_emission / 10 * 4, epsilon = 500); - assert_abs_diff_eq!(nominator_emission, total_emission / 10 * 4, epsilon = 500); + // Setup YUMA so that it creates emissions + Weights::::insert(netuid, 0, vec![(2, 0xFFFF)]); + Weights::::insert(netuid, 1, vec![(2, 0xFFFF)]); + BlockAtRegistration::::set(netuid, 0, 1); + BlockAtRegistration::::set(netuid, 1, 1); + BlockAtRegistration::::set(netuid, 2, 1); + LastUpdate::::set(netuid, vec![2, 2, 2]); + Kappa::::set(netuid, u16::MAX / 5); + ActivityCutoff::::set(netuid, u16::MAX); // makes all stake active + ValidatorPermit::::insert(netuid, vec![true, true, false]); + + // Run run_coinbase to hit subnet epoch + let child_stake_before = SubtensorModule::get_total_stake_for_coldkey(&child_coldkey); + let parent_stake_before = SubtensorModule::get_total_stake_for_coldkey(&parent_coldkey); + let nominator_stake_before = SubtensorModule::get_total_stake_for_coldkey(&nominator); + + step_block(subnet_tempo); + + // Verify how emission is split between keys + // - Child stake remains 0 + // - Childkey take is 20% of its total emission that rewards both inherited from + // parent stake and nominated stake, which all goes to nominators. Because child + // validator emission is 50% of total emission, 20% of it is 10% of total emission + // and it all goes to nominator. If childkey take was 0%, then only 5% would go to + // the nominator, so the final solit is: + // - Parent stake increases by 45% of total emission + // - Nominator stake increases by 55% of total emission + let child_emission = + SubtensorModule::get_total_stake_for_coldkey(&child_coldkey) - child_stake_before; + let parent_emission = + SubtensorModule::get_total_stake_for_coldkey(&parent_coldkey) - parent_stake_before; + let nominator_emission = + SubtensorModule::get_total_stake_for_coldkey(&nominator) - nominator_stake_before; + let total_emission = child_emission + parent_emission + nominator_emission; + + assert_abs_diff_eq!(child_emission, 0, epsilon = 10); + assert_abs_diff_eq!(parent_emission, total_emission * 9 / 20, epsilon = 10); + assert_abs_diff_eq!(nominator_emission, total_emission * 11 / 20, epsilon = 10); + }); }); } diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 315f9e5128..2b2feae4b8 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -98,21 +98,6 @@ fn test_migration_delete_subnet_21() { }) } -fn run_migration_and_check(migration_name: &'static str) -> frame_support::weights::Weight { - // Execute the migration and store its weight - let weight: frame_support::weights::Weight = - crate::migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::( - ); - - // Check if the migration has been marked as completed - assert!(HasMigrationRun::::get( - migration_name.as_bytes().to_vec() - )); - - // Return the weight of the executed migration - weight -} - #[test] fn test_migrate_commit_reveal_2() { new_test_ext(1).execute_with(|| { @@ -200,194 +185,195 @@ fn test_migrate_commit_reveal_2() { }); } +// Leaving in for reference. Will remove later. // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::migration::test_migrate_rao --exact --show-output --nocapture -#[test] -fn test_migrate_rao() { - new_test_ext(1).execute_with(|| { - // Setup initial state - let netuid_0: u16 = 0; - let netuid_1: u16 = 1; - let netuid_2: u16 = 2; - let netuid_3: u16 = 3; - let hotkey1 = U256::from(1); - let hotkey2 = U256::from(2); - let coldkey1 = U256::from(3); - let coldkey2 = U256::from(4); - let coldkey3 = U256::from(5); - let stake_amount: u64 = 1_000_000_000; - let lock_amount: u64 = 500; - NetworkMinLockCost::::set(500); - - // Add networks root and alpha - add_network(netuid_0, 1, 0); - add_network(netuid_1, 1, 0); - add_network(netuid_2, 1, 0); - add_network(netuid_3, 1, 0); - - // Set subnet lock - SubnetLocked::::insert(netuid_1, lock_amount); - - // Add some initial stake - EmissionValues::::insert(netuid_1, 1_000_000_000); - EmissionValues::::insert(netuid_2, 2_000_000_000); - EmissionValues::::insert(netuid_3, 3_000_000_000); - - Owner::::insert(hotkey1, coldkey1); - Owner::::insert(hotkey2, coldkey2); - Stake::::insert(hotkey1, coldkey1, stake_amount); - Stake::::insert(hotkey1, coldkey2, stake_amount); - Stake::::insert(hotkey2, coldkey2, stake_amount); - Stake::::insert(hotkey2, coldkey3, stake_amount); - - // Verify initial conditions - assert_eq!(SubnetTAO::::get(netuid_0), 0); - assert_eq!(SubnetTAO::::get(netuid_1), 0); - assert_eq!(SubnetAlphaOut::::get(netuid_0), 0); - assert_eq!(SubnetAlphaOut::::get(netuid_1), 0); - assert_eq!(SubnetAlphaIn::::get(netuid_0), 0); - assert_eq!(SubnetAlphaIn::::get(netuid_1), 0); - assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_0), 0); - assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_1), 0); - assert_eq!(TotalHotkeyAlpha::::get(hotkey1, netuid_0), 0); - assert_eq!(TotalHotkeyAlpha::::get(hotkey2, netuid_1), 0); - - // Run migration - crate::migrations::migrate_rao::migrate_rao::(); - - // Verify root subnet (netuid 0) state after migration - assert_eq!(SubnetTAO::::get(netuid_0), 4 * stake_amount); // Root has everything - assert_eq!(SubnetTAO::::get(netuid_1), 1_000_000_000); // Always 1000000000 - assert_eq!(SubnetAlphaIn::::get(netuid_0), 1_000_000_000); // Always 1_000_000_000 - assert_eq!(SubnetAlphaIn::::get(netuid_1), 1_000_000_000); // Always 1_000_000_000 - assert_eq!(SubnetAlphaOut::::get(netuid_0), 4 * stake_amount); // Root has everything. - assert_eq!(SubnetAlphaOut::::get(netuid_1), 0); // No stake outstanding. - - // Assert share information for hotkey1 on netuid_0 - assert_eq!( - TotalHotkeyShares::::get(hotkey1, netuid_0), - 2 * stake_amount - ); // Shares - // Assert no shares for hotkey1 on netuid_1 - assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_1), 0); // No shares - // Assert alpha for hotkey1 on netuid_0 - assert_eq!( - TotalHotkeyAlpha::::get(hotkey1, netuid_0), - 2 * stake_amount - ); // Alpha - // Assert no alpha for hotkey1 on netuid_1 - assert_eq!(TotalHotkeyAlpha::::get(hotkey1, netuid_1), 0); // No alpha. - // Assert share information for hotkey2 on netuid_0 - assert_eq!( - TotalHotkeyShares::::get(hotkey2, netuid_0), - 2 * stake_amount - ); // Shares - // Assert no shares for hotkey2 on netuid_1 - assert_eq!(TotalHotkeyShares::::get(hotkey2, netuid_1), 0); // No shares - // Assert alpha for hotkey2 on netuid_0 - assert_eq!( - TotalHotkeyAlpha::::get(hotkey2, netuid_0), - 2 * stake_amount - ); // Alpha - // Assert no alpha for hotkey2 on netuid_1 - assert_eq!(TotalHotkeyAlpha::::get(hotkey2, netuid_1), 0); // No alpha. - - // Assert stake balances for hotkey1 and coldkey1 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, &coldkey1, netuid_0 - ), - stake_amount - ); - // Assert stake balances for hotkey1 and coldkey2 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, &coldkey2, netuid_0 - ), - stake_amount - ); - // Assert stake balances for hotkey2 and coldkey2 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, &coldkey2, netuid_0 - ), - stake_amount - ); - // Assert stake balances for hotkey2 and coldkey3 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, &coldkey3, netuid_0 - ), - stake_amount - ); - // Assert total stake for hotkey1 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_0), - 2 * stake_amount - ); - // Assert total stake for hotkey2 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey2, netuid_0), - 2 * stake_amount - ); - // Increase stake for hotkey1 and coldkey1 on netuid_0 - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &coldkey1, - netuid_0, - stake_amount, - ); - // Assert updated stake for hotkey1 and coldkey1 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, &coldkey1, netuid_0 - ), - 2 * stake_amount - ); - // Assert updated total stake for hotkey1 on netuid_0 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_0), - 3 * stake_amount - ); - // Increase stake for hotkey1 and coldkey1 on netuid_1 - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &coldkey1, - netuid_1, - stake_amount, - ); - // Assert updated stake for hotkey1 and coldkey1 on netuid_1 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, &coldkey1, netuid_1 - ), - stake_amount - ); - // Assert updated total stake for hotkey1 on netuid_1 - assert_eq!( - SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_1), - stake_amount - ); - - // Run the coinbase - let emission: u64 = 1_000_000_000; - SubtensorModule::run_coinbase(I96F32::from_num(emission)); - close( - SubnetTaoInEmission::::get(netuid_1), - emission / 6, - 100, - ); - close( - SubnetTaoInEmission::::get(netuid_2), - 2 * (emission / 6), - 100, - ); - close( - SubnetTaoInEmission::::get(netuid_3), - 3 * (emission / 6), - 100, - ); - }); -} +// #[test] +// fn test_migrate_rao() { +// new_test_ext(1).execute_with(|| { +// // Setup initial state +// let netuid_0: u16 = 0; +// let netuid_1: u16 = 1; +// let netuid_2: u16 = 2; +// let netuid_3: u16 = 3; +// let hotkey1 = U256::from(1); +// let hotkey2 = U256::from(2); +// let coldkey1 = U256::from(3); +// let coldkey2 = U256::from(4); +// let coldkey3 = U256::from(5); +// let stake_amount: u64 = 1_000_000_000; +// let lock_amount: u64 = 500; +// NetworkMinLockCost::::set(500); + +// // Add networks root and alpha +// add_network(netuid_0, 1, 0); +// add_network(netuid_1, 1, 0); +// add_network(netuid_2, 1, 0); +// add_network(netuid_3, 1, 0); + +// // Set subnet lock +// SubnetLocked::::insert(netuid_1, lock_amount); + +// // Add some initial stake +// EmissionValues::::insert(netuid_1, 1_000_000_000); +// EmissionValues::::insert(netuid_2, 2_000_000_000); +// EmissionValues::::insert(netuid_3, 3_000_000_000); + +// Owner::::insert(hotkey1, coldkey1); +// Owner::::insert(hotkey2, coldkey2); +// Stake::::insert(hotkey1, coldkey1, stake_amount); +// Stake::::insert(hotkey1, coldkey2, stake_amount); +// Stake::::insert(hotkey2, coldkey2, stake_amount); +// Stake::::insert(hotkey2, coldkey3, stake_amount); + +// // Verify initial conditions +// assert_eq!(SubnetTAO::::get(netuid_0), 0); +// assert_eq!(SubnetTAO::::get(netuid_1), 0); +// assert_eq!(SubnetAlphaOut::::get(netuid_0), 0); +// assert_eq!(SubnetAlphaOut::::get(netuid_1), 0); +// assert_eq!(SubnetAlphaIn::::get(netuid_0), 0); +// assert_eq!(SubnetAlphaIn::::get(netuid_1), 0); +// assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_0), 0); +// assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_1), 0); +// assert_eq!(TotalHotkeyAlpha::::get(hotkey1, netuid_0), 0); +// assert_eq!(TotalHotkeyAlpha::::get(hotkey2, netuid_1), 0); + +// // Run migration +// crate::migrations::migrate_rao::migrate_rao::(); + +// // Verify root subnet (netuid 0) state after migration +// assert_eq!(SubnetTAO::::get(netuid_0), 4 * stake_amount); // Root has everything +// assert_eq!(SubnetTAO::::get(netuid_1), 1_000_000_000); // Always 1000000000 +// assert_eq!(SubnetAlphaIn::::get(netuid_0), 1_000_000_000); // Always 1_000_000_000 +// assert_eq!(SubnetAlphaIn::::get(netuid_1), 1_000_000_000); // Always 1_000_000_000 +// assert_eq!(SubnetAlphaOut::::get(netuid_0), 4 * stake_amount); // Root has everything. +// assert_eq!(SubnetAlphaOut::::get(netuid_1), 0); // No stake outstanding. + +// // Assert share information for hotkey1 on netuid_0 +// assert_eq!( +// TotalHotkeyShares::::get(hotkey1, netuid_0), +// 2 * stake_amount +// ); // Shares +// // Assert no shares for hotkey1 on netuid_1 +// assert_eq!(TotalHotkeyShares::::get(hotkey1, netuid_1), 0); // No shares +// // Assert alpha for hotkey1 on netuid_0 +// assert_eq!( +// TotalHotkeyAlpha::::get(hotkey1, netuid_0), +// 2 * stake_amount +// ); // Alpha +// // Assert no alpha for hotkey1 on netuid_1 +// assert_eq!(TotalHotkeyAlpha::::get(hotkey1, netuid_1), 0); // No alpha. +// // Assert share information for hotkey2 on netuid_0 +// assert_eq!( +// TotalHotkeyShares::::get(hotkey2, netuid_0), +// 2 * stake_amount +// ); // Shares +// // Assert no shares for hotkey2 on netuid_1 +// assert_eq!(TotalHotkeyShares::::get(hotkey2, netuid_1), 0); // No shares +// // Assert alpha for hotkey2 on netuid_0 +// assert_eq!( +// TotalHotkeyAlpha::::get(hotkey2, netuid_0), +// 2 * stake_amount +// ); // Alpha +// // Assert no alpha for hotkey2 on netuid_1 +// assert_eq!(TotalHotkeyAlpha::::get(hotkey2, netuid_1), 0); // No alpha. + +// // Assert stake balances for hotkey1 and coldkey1 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, &coldkey1, netuid_0 +// ), +// stake_amount +// ); +// // Assert stake balances for hotkey1 and coldkey2 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, &coldkey2, netuid_0 +// ), +// stake_amount +// ); +// // Assert stake balances for hotkey2 and coldkey2 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey2, &coldkey2, netuid_0 +// ), +// stake_amount +// ); +// // Assert stake balances for hotkey2 and coldkey3 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey2, &coldkey3, netuid_0 +// ), +// stake_amount +// ); +// // Assert total stake for hotkey1 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_0), +// 2 * stake_amount +// ); +// // Assert total stake for hotkey2 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey2, netuid_0), +// 2 * stake_amount +// ); +// // Increase stake for hotkey1 and coldkey1 on netuid_0 +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, +// &coldkey1, +// netuid_0, +// stake_amount, +// ); +// // Assert updated stake for hotkey1 and coldkey1 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, &coldkey1, netuid_0 +// ), +// 2 * stake_amount +// ); +// // Assert updated total stake for hotkey1 on netuid_0 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_0), +// 3 * stake_amount +// ); +// // Increase stake for hotkey1 and coldkey1 on netuid_1 +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, +// &coldkey1, +// netuid_1, +// stake_amount, +// ); +// // Assert updated stake for hotkey1 and coldkey1 on netuid_1 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey1, &coldkey1, netuid_1 +// ), +// stake_amount +// ); +// // Assert updated total stake for hotkey1 on netuid_1 +// assert_eq!( +// SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid_1), +// stake_amount +// ); + +// // Run the coinbase +// let emission: u64 = 1_000_000_000; +// SubtensorModule::run_coinbase(I96F32::from_num(emission)); +// close( +// SubnetTaoInEmission::::get(netuid_1), +// emission / 6, +// 100, +// ); +// close( +// SubnetTaoInEmission::::get(netuid_2), +// 2 * (emission / 6), +// 100, +// ); +// close( +// SubnetTaoInEmission::::get(netuid_3), +// 3 * (emission / 6), +// 100, +// ); +// }); +// } // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::migration::test_migrate_subnet_volume --exact --show-output #[test] diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index a1bf93c51f..e5ed95f41d 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -1939,76 +1939,93 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { #[test] fn test_mining_emission_distribution_validator_valiminer_miner() { new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let validator = 2; - let validator_miner = 3; - let miner = U256::from(4); + let validator_coldkey = U256::from(1); + let validator_hotkey = U256::from(2); + let validator_miner_coldkey = U256::from(3); + let validator_miner_hotkey = U256::from(4); + let miner_coldkey = U256::from(5); + let miner_hotkey = U256::from(6); let netuid: u16 = 1; - let root_id: u16 = 0; - let root_tempo = 9; // neet root epoch to happen before subnet tempo let subnet_tempo = 10; let stake = 100_000_000_000; // Add network, register hotkeys, and setup network parameters - add_network(root_id, root_tempo, 0); add_network(netuid, subnet_tempo, 0); - register_ok_neuron(netuid, validator.into(), coldkey, 0); - register_ok_neuron(netuid, validator_miner.into(), coldkey, 1); - register_ok_neuron(netuid, miner, coldkey, 2); + register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0); + register_ok_neuron(netuid, validator_miner_hotkey, validator_miner_coldkey, 1); + register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 2); SubtensorModule::add_balance_to_coldkey_account( - &coldkey, - 3 * stake + ExistentialDeposit::get(), + &validator_coldkey, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::add_balance_to_coldkey_account( + &validator_miner_coldkey, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::add_balance_to_coldkey_account( + &miner_coldkey, + stake + ExistentialDeposit::get(), ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); step_block(subnet_tempo); - crate::SubnetOwnerCut::::set(0); - // All stake is active - crate::ActivityCutoff::::set(netuid, u16::MAX); + SubnetOwnerCut::::set(0); // There are two validators and three neurons - crate::MaxAllowedUids::::set(netuid, 3); + MaxAllowedUids::::set(netuid, 3); SubtensorModule::set_max_allowed_validators(netuid, 2); // Setup stakes: // Stake from validator // Stake from valiminer - crate::Stake::::set(U256::from(validator), coldkey, stake); - crate::Stake::::set(U256::from(validator_miner), coldkey, stake); - - // Setup YUMA so that it creates emissions: - // Validator 1 sets weight for valiminer |- to achieve equal incentive for both miners - // Valiminer sets weights for the second miner | - // Validator registers on root and - // Sets root weights - // Last weight update is after block at registration - crate::Weights::::insert(netuid, 0, vec![(1, 0xFFFF)]); - crate::Weights::::insert(netuid, 1, vec![(2, 0xFFFF)]); - assert_ok!(SubtensorModule::do_root_register( - RuntimeOrigin::signed(coldkey), - U256::from(validator), + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(validator_coldkey), + validator_hotkey, + netuid, + stake + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(validator_miner_coldkey), + validator_miner_hotkey, + netuid, + stake )); - crate::Weights::::insert(root_id, 0, vec![(0, 0xFFFF), (1, 0xFFFF)]); - crate::BlockAtRegistration::::set(netuid, 0, 1); - crate::BlockAtRegistration::::set(netuid, 1, 1); - crate::LastUpdate::::set(netuid, vec![2, 2, 2]); - crate::Kappa::::set(netuid, u16::MAX / 5); + + // Setup YUMA so that it creates emissions + Weights::::insert(netuid, 0, vec![(1, 0xFFFF)]); + Weights::::insert(netuid, 1, vec![(2, 0xFFFF)]); + BlockAtRegistration::::set(netuid, 0, 1); + BlockAtRegistration::::set(netuid, 1, 1); + BlockAtRegistration::::set(netuid, 2, 1); + LastUpdate::::set(netuid, vec![2, 2, 2]); + Kappa::::set(netuid, u16::MAX / 5); + ActivityCutoff::::set(netuid, u16::MAX); // makes all stake active + ValidatorPermit::::insert(netuid, vec![true, true, false]); // Run run_coinbase until emissions are drained - step_block(subnet_tempo * 4); + let validator_stake_before = + SubtensorModule::get_total_stake_for_coldkey(&validator_coldkey); + let valiminer_stake_before = + SubtensorModule::get_total_stake_for_coldkey(&validator_miner_coldkey); + let miner_stake_before = SubtensorModule::get_total_stake_for_coldkey(&miner_coldkey); + + step_block(subnet_tempo); // Verify how emission is split between keys - // - 50% goes to miners and 50% goes to validators + // - Owner cut is zero => 50% goes to miners and 50% goes to validators // - Validator gets 25% because there are two validators // - Valiminer gets 25% as a validator and 25% as miner // - Miner gets 25% as miner - let validator_emission = crate::Stake::::get(U256::from(validator), coldkey) - stake; + let validator_emission = SubtensorModule::get_total_stake_for_coldkey(&validator_coldkey) + - validator_stake_before; let valiminer_emission = - crate::Stake::::get(U256::from(validator_miner), coldkey) - stake; - let miner_emission = crate::Stake::::get(miner, coldkey); + SubtensorModule::get_total_stake_for_coldkey(&validator_miner_coldkey) + - valiminer_stake_before; + let miner_emission = + SubtensorModule::get_total_stake_for_coldkey(&miner_coldkey) - miner_stake_before; let total_emission = validator_emission + valiminer_emission + miner_emission; - assert_eq!(validator_emission, total_emission / 4); - assert_eq!(valiminer_emission, total_emission / 2); - assert_eq!(miner_emission, total_emission / 4); + assert_abs_diff_eq!(validator_emission, total_emission / 4, epsilon = 10); + assert_abs_diff_eq!(valiminer_emission, total_emission / 2, epsilon = 10); + assert_abs_diff_eq!(miner_emission, total_emission / 4, epsilon = 10); }); } @@ -2161,17 +2178,17 @@ fn test_stake_below_min_validate() { amount_staked, }); - let info: crate::DispatchInfo = - crate::DispatchInfoOf::<::RuntimeCall>::default(); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); - let extension = crate::SubtensorSignedExtension::::new(); + let extension = SubtensorSignedExtension::::new(); // Submit to the signed extension validate function let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); // Should fail due to insufficient stake assert_err!( result_no_stake, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::StakeAmountTooLow.into() )) ); @@ -2190,7 +2207,7 @@ fn test_stake_below_min_validate() { // Still doesn't pass, but with a different reason (balance too low) assert_err!( result_low_balance, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::BalanceTooLow.into() )) ); @@ -2244,17 +2261,17 @@ fn test_add_stake_limit_validate() { allow_partial: false, }); - let info: crate::DispatchInfo = - crate::DispatchInfoOf::<::RuntimeCall>::default(); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); - let extension = crate::SubtensorSignedExtension::::new(); + let extension = SubtensorSignedExtension::::new(); // Submit to the signed extension validate function let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); // Should fail due to slippage assert_err!( result_no_stake, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::SlippageTooHigh.into() )) ); @@ -2304,17 +2321,17 @@ fn test_remove_stake_limit_validate() { allow_partial: false, }); - let info: crate::DispatchInfo = - crate::DispatchInfoOf::<::RuntimeCall>::default(); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); - let extension = crate::SubtensorSignedExtension::::new(); + let extension = SubtensorSignedExtension::::new(); // Submit to the signed extension validate function let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); // Should fail due to slippage assert_err!( result_no_stake, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::SlippageTooHigh.into() )) ); @@ -2393,17 +2410,17 @@ fn test_stake_low_liquidity_validate() { amount_staked, }); - let info: crate::DispatchInfo = - crate::DispatchInfoOf::<::RuntimeCall>::default(); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); - let extension = crate::SubtensorSignedExtension::::new(); + let extension = SubtensorSignedExtension::::new(); // Submit to the signed extension validate function let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); // Should fail due to insufficient stake assert_err!( result_no_stake, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::InsufficientLiquidity.into() )) ); @@ -2448,17 +2465,17 @@ fn test_unstake_low_liquidity_validate() { amount_unstaked: alpha, }); - let info: crate::DispatchInfo = - crate::DispatchInfoOf::<::RuntimeCall>::default(); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); - let extension = crate::SubtensorSignedExtension::::new(); + let extension = SubtensorSignedExtension::::new(); // Submit to the signed extension validate function let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); // Should fail due to insufficient stake assert_err!( result_no_stake, - crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + TransactionValidityError::Invalid(InvalidTransaction::Custom( CustomTransactionError::InsufficientLiquidity.into() )) ); diff --git a/pallets/subtensor/src/tests/swap_coldkey.rs b/pallets/subtensor/src/tests/swap_coldkey.rs index 7d6754f6cb..8f7b024e4c 100644 --- a/pallets/subtensor/src/tests/swap_coldkey.rs +++ b/pallets/subtensor/src/tests/swap_coldkey.rs @@ -68,29 +68,6 @@ fn test_swap_subnet_owner() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_stake --exact --nocapture -#[test] -fn test_swap_stake() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let stake = 100; - - StakingHotkeys::::insert(old_coldkey, vec![hotkey]); - Stake::::insert(hotkey, old_coldkey, stake); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); - - assert!(!Stake::::contains_key(hotkey, old_coldkey)); - assert_eq!(Stake::::get(hotkey, new_coldkey), stake); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_total_coldkey_stake --exact --show-output #[test] fn test_swap_total_coldkey_stake() { @@ -494,16 +471,36 @@ fn test_swap_with_max_hotkeys() { #[test] fn test_swap_effect_on_delegated_stake() { new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let old_coldkey = U256::from(1); let new_coldkey = U256::from(2); let delegator = U256::from(3); let hotkey = U256::from(4); - let stake = 10_000; + let stake = 100_000_000_000; StakingHotkeys::::insert(old_coldkey, vec![hotkey]); StakingHotkeys::::insert(delegator, vec![hotkey]); - Stake::::insert(hotkey, old_coldkey, stake); - Stake::::insert(hotkey, delegator, stake); + SubtensorModule::create_account_if_non_existent(&old_coldkey, &hotkey); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake); + SubtensorModule::add_balance_to_coldkey_account(&delegator, stake); + + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(old_coldkey), + hotkey, + netuid, + stake + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(delegator), + hotkey, + netuid, + stake + )); + let coldkey_stake_before = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); + let delegator_stake_before = SubtensorModule::get_total_stake_for_coldkey(&delegator); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -512,9 +509,21 @@ fn test_swap_effect_on_delegated_stake() { &mut weight )); - assert_eq!(Stake::::get(hotkey, new_coldkey), stake); - assert_eq!(Stake::::get(hotkey, delegator), stake); - assert_eq!(Stake::::get(hotkey, old_coldkey), 0); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), + coldkey_stake_before, + epsilon = 500 + ); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_coldkey(&delegator), + delegator_stake_before, + epsilon = 500 + ); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), + 0, + epsilon = 500 + ); }); } diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index 4e02258708..dab1675074 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -419,30 +419,6 @@ fn test_swap_loaded_emission() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_stake --exact --nocapture -#[test] -fn test_swap_stake() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake_amount = 100u64; - let mut weight = Weight::zero(); - - Stake::::insert(old_hotkey, coldkey, stake_amount); - - assert_ok!(SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight - )); - - assert!(!Stake::::contains_key(old_hotkey, coldkey)); - assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_staking_hotkeys --exact --nocapture #[test] fn test_swap_staking_hotkeys() { @@ -453,7 +429,6 @@ fn test_swap_staking_hotkeys() { let mut weight = Weight::zero(); let netuid = 1; - Stake::::insert(old_hotkey, coldkey, 100); StakingHotkeys::::insert(coldkey, vec![old_hotkey]); Alpha::::insert((old_hotkey, coldkey, netuid), U64F64::from_num(100)); @@ -470,24 +445,47 @@ fn test_swap_staking_hotkeys() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_multiple_coldkeys --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey::test_swap_hotkey_with_multiple_coldkeys --exact --show-output --nocapture #[test] fn test_swap_hotkey_with_multiple_coldkeys() { new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey1 = U256::from(3); let coldkey2 = U256::from(4); let mut weight = Weight::zero(); - let netuid = 1; + let stake = 1_000_000_000; - Stake::::insert(old_hotkey, coldkey1, 100); - Stake::::insert(old_hotkey, coldkey2, 200); StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); StakingHotkeys::::insert(coldkey2, vec![old_hotkey]); + SubtensorModule::create_account_if_non_existent(&coldkey1, &old_hotkey); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey1, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey2, + stake + ExistentialDeposit::get(), + ); - Alpha::::insert((old_hotkey, coldkey1, netuid), U64F64::from_num(100)); - Alpha::::insert((old_hotkey, coldkey2, netuid), U64F64::from_num(200)); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey1), + old_hotkey, + netuid, + stake + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey2), + old_hotkey, + netuid, + stake / 2 + )); + let stake1_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey1); + let stake2_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey2); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -496,36 +494,19 @@ fn test_swap_hotkey_with_multiple_coldkeys() { &mut weight )); - assert_eq!(Stake::::get(new_hotkey, coldkey1), 100); - assert_eq!(Stake::::get(new_hotkey, coldkey2), 200); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&coldkey1), + stake1_before + ); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&coldkey2), + stake2_before + ); assert!(StakingHotkeys::::get(coldkey1).contains(&new_hotkey)); assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_existing_stake --exact --nocapture -#[test] -fn test_swap_hotkey_with_existing_stake() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - Stake::::insert(old_hotkey, coldkey, 100); - Stake::::insert(new_hotkey, coldkey, 50); - - assert_ok!(SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight - )); - - assert_eq!(Stake::::get(new_hotkey, coldkey), 150); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_multiple_subnets --exact --nocapture #[test] fn test_swap_hotkey_with_multiple_subnets() { @@ -560,22 +541,43 @@ fn test_swap_hotkey_with_multiple_subnets() { #[test] fn test_swap_staking_hotkeys_multiple_coldkeys() { new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey1 = U256::from(3); let coldkey2 = U256::from(4); + let staker5 = U256::from(5); let mut weight = Weight::zero(); - let netuid = 1; + let stake = 1_000_000_000; // Set up initial state - Stake::::insert(old_hotkey, coldkey1, 100); - Stake::::insert(old_hotkey, coldkey2, 200); - - Alpha::::insert((old_hotkey, coldkey1, netuid), U64F64::from_num(100)); - Alpha::::insert((old_hotkey, coldkey2, netuid), U64F64::from_num(200)); - StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); - StakingHotkeys::::insert(coldkey2, vec![old_hotkey, U256::from(5)]); + StakingHotkeys::::insert(coldkey2, vec![old_hotkey, staker5]); + + SubtensorModule::create_account_if_non_existent(&coldkey1, &old_hotkey); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey1, + stake + ExistentialDeposit::get(), + ); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey2, + stake + ExistentialDeposit::get(), + ); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey1), + old_hotkey, + netuid, + stake + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey2), + old_hotkey, + netuid, + stake + )); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -591,7 +593,7 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { // Check if new_hotkey replaced old_hotkey for coldkey2 as well assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); assert!(!StakingHotkeys::::get(coldkey2).contains(&old_hotkey)); - assert!(StakingHotkeys::::get(coldkey2).contains(&U256::from(5))); + assert!(StakingHotkeys::::get(coldkey2).contains(&staker5)); // Other hotkeys should remain }); } @@ -600,6 +602,10 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { #[test] fn test_swap_hotkey_with_no_stake() { new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey = U256::from(3); @@ -620,8 +626,8 @@ fn test_swap_hotkey_with_no_stake() { assert_eq!(Owner::::get(new_hotkey), coldkey); // Ensure no unexpected changes in Stake - assert!(!Stake::::contains_key(old_hotkey, coldkey)); - assert!(!Stake::::contains_key(new_hotkey, coldkey)); + assert!(!Alpha::::contains_key((old_hotkey, coldkey, netuid))); + assert!(!Alpha::::contains_key((new_hotkey, coldkey, netuid))); }); } @@ -940,7 +946,6 @@ fn test_swap_stake_success() { let mut weight = Weight::zero(); // Initialize staking variables for old_hotkey - Stake::::insert(old_hotkey, coldkey, 0); TotalHotkeyAlpha::::insert(old_hotkey, netuid, amount); TotalHotkeyShares::::insert(old_hotkey, netuid, U64F64::from_num(shares)); Alpha::::insert((old_hotkey, coldkey, netuid), U64F64::from_num(amount)); @@ -977,21 +982,22 @@ fn test_swap_stake_old_hotkey_not_exist() { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey = U256::from(3); - let stake_amount = 1000u64; + let alpha_share = U64F64::from_num(1234); let mut weight = Weight::zero(); + let netuid = 1; // Initialize Stake for old_hotkey - Stake::::insert(old_hotkey, coldkey, stake_amount); + Alpha::::insert((old_hotkey, coldkey, netuid), alpha_share); // Ensure old_hotkey has a stake - assert!(Stake::::contains_key(old_hotkey, coldkey)); + assert!(Alpha::::contains_key((old_hotkey, coldkey, netuid))); // Perform the swap SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify that new_hotkey has the stake and old_hotkey does not - assert!(Stake::::contains_key(new_hotkey, coldkey)); - assert!(!Stake::::contains_key(old_hotkey, coldkey)); + assert!(Alpha::::contains_key((new_hotkey, coldkey, netuid))); + assert!(!Alpha::::contains_key((old_hotkey, coldkey, netuid))); }); }