From 5291a9ef3276fc08a6ea98daa3d2e0f1c8ab5a5f Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 11:42:55 -0500 Subject: [PATCH 1/7] add coinbase dynamic mechanism tests --- .../subtensor/src/coinbase/run_coinbase.rs | 203 +- pallets/subtensor/src/tests/alpha.rs | 1665 ----------------- pallets/subtensor/src/tests/coinbase.rs | 298 +-- pallets/subtensor/src/tests/mod.rs | 2 - pallets/subtensor/src/tests/staking2.rs | 8 +- 5 files changed, 305 insertions(+), 1871 deletions(-) delete mode 100644 pallets/subtensor/src/tests/alpha.rs diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 9b65d2a78..b4afd305b 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -18,32 +18,69 @@ pub struct WeightsTlockPayload { } impl Pallet { - /// The `coinbase` function performs a four-part emission distribution process involving - /// subnets, epochs, hotkeys, and nominators. - /// - /// It is divided into several steps, each handling a specific part of the distribution: - /// - /// Step 1: Compute the block-wise emission for each subnet. - /// This involves calculating how much (TAO) should be emitted into each subnet using the root - /// epoch function. - /// - /// Step 2: Accumulate the subnet block emission. - /// After calculating the block-wise emission, these values are accumulated to keep track of how - /// much each subnet should emit before the next distribution phase. This accumulation is a - /// running total that gets updated each block. - /// - /// Step 3: Distribute the accumulated emissions through epochs. - /// Subnets periodically distribute their accumulated emissions to hotkeys (active - /// validators/miners) in the network on a `tempo` --- the time between epochs. This step runs - /// Yuma consensus to determine how emissions are split among hotkeys based on their - /// contributions and roles. The accumulation of hotkey emissions is done through the - /// `accumulate_hotkey_emission` function. The function splits the rewards for a hotkey amongst - /// itself and its `parents`. The parents are the hotkeys that are delegating their stake to the - /// hotkey. - /// - /// Step 4: Further distribute emissions from hotkeys to nominators. - /// Finally, the emissions received by hotkeys are further distributed to their nominators, who - /// are stakeholders that support the hotkeys. + + + pub fn get_dynamic_tao_emission( netuid: u16, subnet_emission: u64, tao_block_emission: u64, alpha_block_emission: u64 ) -> (u64, u64, u64) { + + // Compute tao_in, as proportion of block emission from subnet emission + let tao_in_proportion: I96F32 = I96F32::from_num(subnet_emission).checked_div( I96F32::from_num( tao_block_emission ) ).unwrap_or( I96F32::from_num(0) ); + log::debug!("{:?} - tao_in_proportion: {:?}", netuid, tao_in_proportion); + + // Get alpha price for subnet. + let alpha_price: I96F32 = Self::get_alpha_price( netuid ); + log::debug!("{:?} - alpha_price: {:?}", netuid, alpha_price); + + // Switch on relationship between alpha price and tao_in + let tao_in_emission: I96F32; + let alpha_in_emission: I96F32; + let alpha_out_emission: I96F32; + if alpha_price <= tao_in_proportion { + log::debug!("{:?} - alpha_price: {:?} <= tao_in_proportion: {:?}", netuid, alpha_price, tao_in_proportion); + // If price if less than tao_in, multiply alpha_price by total block_emission to get tao_emission. + tao_in_emission = alpha_price.saturating_mul( I96F32::from_num( tao_block_emission ) ); + + // Alpha in alpha block emission. + alpha_in_emission = I96F32::from_num( alpha_block_emission ) ; + + // Set Alpha in emission. + alpha_out_emission = I96F32::from_num( 2 * alpha_block_emission).saturating_sub( alpha_in_emission ); + } else { + log::debug!("{:?} - alpha_price: {:?} > tao_in_proportion: {:?}", netuid, alpha_price, tao_in_proportion); + // If price is greater than tao_in, multiply back tao_in by tao_block_emission. + tao_in_emission = I96F32::from_num( subnet_emission ); + + // We attain alpha_in emission by dividing tao_in by alpha price and multiplying by alpha_block_emission + alpha_in_emission = I96F32::from_num( alpha_block_emission ).saturating_mul( tao_in_proportion.checked_div(alpha_price).unwrap_or(I96F32::from_num(0)) ); + + // Set Alpha in emission. + alpha_out_emission = I96F32::from_num(2).saturating_mul(I96F32::from_num(alpha_block_emission)).saturating_sub( alpha_in_emission ); + } + + // Compute alpha out emission as 2 x alpha_block_emission - alpha_in_emission + log::debug!("{:?} - tao_in_emission: {:?}", netuid, tao_in_emission); + log::debug!("{:?} - alpha_in_emission: {:?}", netuid, alpha_in_emission); + log::debug!("{:?} - alpha_in_emission: {:?}", netuid, alpha_out_emission); + + (tao_in_emission.to_num::(), alpha_in_emission.to_num::(), alpha_out_emission.to_num::()) + } + + + pub fn get_root_divs_in_alpha( netuid: u16, alpha_out_emission: I96F32 ) -> I96F32 { + // Get total TAO on root. + let total_root_tao: I96F32 = I96F32::from_num( SubnetTAO::::get( 0 ) ); + // Get total ALPHA on subnet. + let total_alpha_issuance: I96F32 = I96F32::from_num(Self::get_alpha_issuance( netuid )); + // Get tao_weight + let tao_weight: I96F32 = total_root_tao.saturating_mul( Self::get_tao_weight( netuid ) ); + // Get root proportional dividends. + let root_proportion: I96F32 = tao_weight.checked_div( tao_weight.saturating_add( total_alpha_issuance ) ).unwrap_or( I96F32::from_num( 0.0 ) ); + // Get root proportion of alpha_out dividends. + let root_divs_in_alpha: I96F32 = root_proportion.saturating_mul( alpha_out_emission ).saturating_mul( I96F32::from_num( 0.41 ) ); + // Return + root_divs_in_alpha + } + + pub fn run_coinbase() { // --- 0. Get current block. let current_block: u64 = Self::get_current_block_as_u64(); @@ -109,102 +146,74 @@ impl Pallet { if *netuid == 0 {continue;} // 6.1. Get subnet mechanism ID let mechid: u16 = SubnetMechanism::::get(*netuid); - log::debug!("Netuid: {:?}, Mechanism ID: {:?}", netuid, mechid); + log::debug!("{:?} - mechid: {:?}", netuid, mechid); // 6.2: Get the subnet emission TAO. - let mut tao_emission: I96F32 = I96F32::from_num(*tao_in_map.get(&netuid).unwrap_or(&0)); - log::debug!("Subnet emission TAO for netuid {:?}: {:?}", netuid, tao_emission); + let subnet_emission: u64 = *tao_in_map.get(&netuid).unwrap_or(&0); + log::debug!("{:?} subnet_emission: {:?}", netuid, subnet_emission ); if mechid == 0 { // The mechanism is Stable (FOR TESTING PURPOSES ONLY) // 6.2.1 Increase Tao in the subnet "reserves" unconditionally. - SubnetTAO::::mutate(*netuid, |total| { *total = total.saturating_add(tao_emission.to_num::()) }); + SubnetTAO::::mutate(*netuid, |total| { *total = total.saturating_add( subnet_emission ) }); // 6.2.2 Increase total stake across all subnets. - TotalStake::::mutate(|total| *total = total.saturating_add(tao_emission.to_num::())); + TotalStake::::mutate(|total| *total = total.saturating_add( subnet_emission )); // 6.2.3 Increase total issuance of Tao. - TotalIssuance::::mutate(|total| *total = total.saturating_add(tao_emission.to_num::())); + TotalIssuance::::mutate(|total| *total = total.saturating_add( subnet_emission )); // 6.2.4 Increase this subnet pending emission. - PendingEmission::::mutate(*netuid, |total| { *total = total.saturating_add(tao_emission.to_num::()) }); + PendingEmission::::mutate(*netuid, |total| { *total = total.saturating_add( subnet_emission ) }); // 6.2.5 Go to next subnet. continue } - // Dynamic TAO below: - // 6.3: Get the alpha emission per block as a function of supply. - let alpha_emission: I96F32 = I96F32::from_num(Self::get_block_emission_for_issuance( Self::get_alpha_issuance(*netuid) ).unwrap_or(0)); - log::debug!("netuid {:?}: alpha_emission: {:?}", netuid, tao_emission); - // 6.4: Get tao_in, which is number between (0, 1), percent of block emission in tao. - let tao_in: I96F32 = tao_emission / I96F32::from_num(block_emission); - log::debug!("Emission proportion {:?}: {:?}", netuid, tao_in); - // 6.5: Get alpha price as function of tao_reserve and alpha_reserve. - let alpha_price: I96F32 = I96F32::from_num(SubnetTAO::::get(*netuid)).checked_div(I96F32::from_num(SubnetAlphaIn::::get(*netuid))).unwrap_or(I96F32::from_num(0)); - log::debug!("Alpha price for netuid {:?}: {:?}", netuid, alpha_price); - // 6.5: Compute alpha_in from tao_in and alpha_price. - let alpha_in: I96F32; - if alpha_price <= tao_in { - // 6.5.1: Set tao_in proportion to alpha_price. - tao_emission = alpha_price * block_emission; - log::debug!("Set tao_in to alpha_price: {:?}", tao_emission); - // 6.5.2: Set alpha_in to a hard 1 (max value) - alpha_in = I96F32::from_num(1); - log::debug!("Set alpha_in to max value: {:?}", alpha_in); - } else { - // 6.5.2: tao_in remains unchanged - tao_emission = tao_in * block_emission; - log::debug!("tao_in remains unchanged: {:?}", tao_emission); - // 6.5.3: alpha_in is computed based on tao_in and price to keep price fixed. - alpha_in = I96F32::from_num(tao_in).checked_div(alpha_price).unwrap_or(I96F32::from_num(0)); - log::debug!("Computed alpha_in based on tao_in and alpha_price: {:?}", alpha_in); - } - // 6.6: Compute Alpha_in_issuance based on current issuance amount. - let alpha_in_emission: I96F32 = alpha_emission.saturating_mul(alpha_in); - SubnetAlphaInEmission::::insert( *netuid, alpha_in_emission.to_num::()); - log::debug!("Computed alpha_in_emission: {:?}", alpha_in_emission); - // 6.7: Inject Alpha into the pool reserves here: alpha_in. + // Get the total_alpha_emission for the block + let alpha_block_emission: u64 = Self::get_block_emission_for_issuance( Self::get_alpha_issuance( *netuid ) ).unwrap_or( 0 ); + + // Compute emission into pool. + let (tao_in_emission, alpha_in_emission, alpha_out_emission):( u64, u64, u64 ) = Self::get_dynamic_tao_emission( + *netuid, + subnet_emission, + block_emission.to_num::(), + alpha_block_emission + ); + + // Set state vars. + SubnetTaoInEmission::::insert( *netuid, tao_in_emission ); + SubnetAlphaInEmission::::insert( *netuid, alpha_in_emission ); + SubnetAlphaOutEmission::::insert( *netuid, alpha_out_emission ); + + // Increase counters. SubnetAlphaIn::::mutate(*netuid, |total| { - *total = total.saturating_add(alpha_in_emission.to_num::()); + *total = total.saturating_add( alpha_in_emission ); + log::debug!("Injected alpha_in into SubnetAlphaIn: {:?}", *total); + }); + SubnetAlphaOut::::mutate(*netuid, |total| { + *total = total.saturating_add( alpha_out_emission ); log::debug!("Injected alpha_in into SubnetAlphaIn: {:?}", *total); }); - // 6.7: Compute Alpha_out_issuance based on alpha_in_issuance - let mut alpha_out_emission: I96F32 = 2 * alpha_emission - alpha_in_emission; - SubnetAlphaOutEmission::::insert( *netuid, alpha_out_emission.to_num::()); - SubnetAlphaOut::::mutate(netuid, |total| { *total = total.saturating_add( alpha_out_emission.to_num::() ) }); - log::debug!("Computed alpha_out_emission: {:?}", alpha_out_emission); - // 6.9: Increase Tao in the subnet reserve conditionally. SubnetTAO::::mutate(*netuid, |total| { - *total = total.saturating_add(tao_emission.to_num::()); + *total = total.saturating_add( tao_in_emission ); log::debug!("Increased Tao in SubnetTAO: {:?}", *total); }); - SubnetTaoInEmission::::insert( *netuid, tao_emission.to_num::()); - // 6.10: Increase total stake counter. TotalStake::::mutate(|total| { - *total = total.saturating_add(tao_emission.to_num::()); + *total = total.saturating_add( tao_in_emission ); log::debug!("Increased TotalStake: {:?}", *total); }); - // 6.11: Increase total Tao issuance counter. TotalIssuance::::mutate(|total| { - *total = total.saturating_add(tao_emission.to_num::()); + *total = total.saturating_add( tao_in_emission ); log::debug!("Increased TotalIssuance: {:?}", *total); }); - // Get total TAO on root. - let total_root_tao: I96F32 = I96F32::from_num(SubnetTAO::::get( 0 )); - // Get total ALPHA on subnet. - let total_alpha_issuance: I96F32 = I96F32::from_num(Self::get_alpha_issuance(*netuid)); - // Get tao_weight - let tao_weight: I96F32 = Self::get_tao_weight( *netuid ); - // Get root proportional dividends. - let root_proportion: I96F32 = (total_root_tao * tao_weight) / ((total_root_tao * tao_weight) + total_alpha_issuance); - // Get root proportion of alpha_out dividends. - let root_proportion_of_alpha_out: I96F32 = root_proportion * alpha_out_emission * I96F32::from_num( 0.41 ); - // Subtract root proporiton from alpha_out_emission - alpha_out_emission -= root_proportion_of_alpha_out; - // Sell root proportion of alpha_out through the pool into TAO. - let root_alpha_as_tao: u64 = Self::swap_alpha_for_tao( *netuid, root_proportion_of_alpha_out.to_num::() ); - // Accumulate root tao dividends into the accumulator. + + // Get proportion of alpha out emission as root divs. + let root_emission_in_alpha: I96F32 = Self::get_root_divs_in_alpha( *netuid, I96F32::from_num(alpha_out_emission) ); + // Subtract root divs from alpha divs. + let pending_alpha_emission: I96F32 = I96F32::from_num( alpha_out_emission ).saturating_sub( root_emission_in_alpha ); + // Sell root emission through the pool. + let root_emission_in_tao: u64 = Self::swap_alpha_for_tao( *netuid, root_emission_in_alpha.to_num::() ); + // Accumulate root divs for subnet. PendingRootDivs::::mutate( *netuid, |total| { - *total = total.saturating_add(root_alpha_as_tao); + *total = total.saturating_add( root_emission_in_tao ); }); - // 6.8: Inject Alpha out for distribution later. + // Accumulate alpha emission in pending. PendingEmission::::mutate(*netuid, |total| { - *total = total.saturating_add(alpha_out_emission.to_num::()); - log::debug!("Injected alpha_out_emission into PendingEmission: {:?}", *total); + *total = total.saturating_add( pending_alpha_emission.to_num::() ); }); } diff --git a/pallets/subtensor/src/tests/alpha.rs b/pallets/subtensor/src/tests/alpha.rs deleted file mode 100644 index cf719038d..000000000 --- a/pallets/subtensor/src/tests/alpha.rs +++ /dev/null @@ -1,1665 +0,0 @@ -// use sp_core::U256; -// use substrate_fixed::types::I96F32; - -use super::mock::*; - -// Test titles and descriptions for exhaustive testing of stake_into_subnet function: - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test test_stake_into_subnet_dynamic_mechanism -- test_stake_into_subnet_dynamic_mechanism --exact --nocapture -#[test] -fn test_stake_into_subnet_dynamic_mechanism() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let tao_to_stake = 1_000_000_000; // 1 TAO - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Add balance to coldkey account - // SubtensorModule::add_balance_to_coldkey_account(&coldkey, tao_to_stake); - - // // Perform staking - // let alpha_staked = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, tao_to_stake); - - // // Verify correct alpha calculation - // let expected_k = - // I96F32::from_num(initial_subnet_alpha) * I96F32::from_num(initial_subnet_tao); - // let expected_alpha_staked = I96F32::from_num(initial_subnet_alpha) - // - (expected_k / I96F32::from_num(initial_subnet_tao + tao_to_stake)); - // let expected_alpha_staked_u64 = expected_alpha_staked.to_num::(); - // assert_eq!( - // alpha_staked, expected_alpha_staked_u64, - // "Alpha staked calculation is incorrect" - // ); - - // // Check subnet alpha and TAO updates - // let new_subnet_alpha = SubnetAlphaIn::::get(netuid); - // let new_subnet_tao = SubnetTAO::::get(netuid); - // assert_eq!( - // new_subnet_alpha, - // initial_subnet_alpha - expected_alpha_staked_u64 - 1, - // "Subnet alpha not updated correctly" - // ); - // assert_eq!( - // new_subnet_tao, - // initial_subnet_tao + tao_to_stake, - // "Subnet TAO not updated correctly" - // ); - - // // Ensure global and per-account storage updates - // assert_eq!( - // TotalStake::::get(), - // tao_to_stake, - // "Total stake not updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // tao_to_stake, - // "Stake for hotkey-coldkey pair not updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // expected_alpha_staked_u64, - // "Total hotkey alpha not updated correctly" - // ); - // // (DEPRECATED) assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // expected_alpha_staked_u64, - // // "Total coldkey alpha not updated correctly" - // // ); - // assert_eq!( - // Alpha::::get((&hotkey, &coldkey, netuid)), - // expected_alpha_staked_u64, - // "Alpha for hotkey-coldkey pair not updated correctly" - // ); - - // // Check StakingHotkeys update - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys not updated correctly" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_stable_mechanism --exact --nocapture -#[test] -fn test_stake_into_subnet_stable_mechanism() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let tao_to_stake = 1_000_000_000; // 1 TAO - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Add balance to coldkey account - // SubtensorModule::add_balance_to_coldkey_account(&coldkey, tao_to_stake); - - // // Perform staking - // let alpha_staked = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, tao_to_stake); - - // // Verify alpha staked equals TAO staked - // assert_eq!( - // alpha_staked, tao_to_stake, - // "Alpha staked should equal TAO staked in stable mechanism" - // ); - - // // Check subnet alpha is set to initial - // let new_subnet_alpha = SubnetAlphaIn::::get(netuid); - // assert_eq!( - // new_subnet_alpha, initial_subnet_alpha, - // "Subnet alpha should be zero in stable mechanism" - // ); - - // // Check subnet TAO update - // let new_subnet_tao = SubnetTAO::::get(netuid); - // assert_eq!( - // new_subnet_tao, - // initial_subnet_tao + tao_to_stake, - // "Subnet TAO not updated correctly" - // ); - - // // Ensure global and per-account storage updates - // assert_eq!( - // TotalStake::::get(), - // tao_to_stake, - // "Total stake not updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // tao_to_stake, - // "Stake for hotkey-coldkey pair not updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // alpha_staked, - // "Total hotkey alpha not updated correctly" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // alpha_staked, - // // "Total coldkey alpha not updated correctly" - // // );(DEPRECATED) - // assert_eq!( - // Alpha::::get((&hotkey, &coldkey, netuid)), - // alpha_staked, - // "Alpha for hotkey-coldkey pair not updated correctly" - // ); - - // // Check StakingHotkeys update - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys not updated correctly" - // ); - - // // Check SubnetAlphaOut update - // let subnet_alpha_out = SubnetAlphaOut::::get(netuid); - // assert_eq!( - // subnet_alpha_out, - // initial_subnet_alpha + alpha_staked, - // "SubnetAlphaOut not updated correctly" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_zero_amount --exact --nocapture -#[test] -fn test_stake_into_subnet_zero_amount() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let tao_to_stake = 0; // Staking zero amount - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Record initial values - // let initial_total_stake = TotalStake::::get(); - // let initial_stake = Stake::::get(hotkey, coldkey); - // let initial_total_hotkey_alpha = TotalHotkeyAlpha::::get(hotkey, netuid); - // // let initial_total_coldkey_alpha = TotalColdkeyAlpha::::get(coldkey, netuid); (DEPRECATED) - // let initial_alpha = Alpha::::get((&hotkey, &coldkey, netuid)); - // let _initial_staking_hotkeys = StakingHotkeys::::get(coldkey); - - // // Perform staking - // let alpha_staked = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, tao_to_stake); - - // // Verify alpha staked is zero - // assert_eq!( - // alpha_staked, 0, - // "Alpha staked should be zero when staking zero amount" - // ); - - // // Check that all storage items remain unchanged - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao, - // "Subnet TAO should not change" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid), - // initial_subnet_alpha, - // "Subnet Alpha In should not change" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha, - // "Subnet Alpha Out should not change" - // ); - // assert_eq!( - // TotalStake::::get(), - // initial_total_stake, - // "Total stake should not change" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // initial_stake, - // "Stake for hotkey-coldkey pair should not change" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // initial_total_hotkey_alpha, - // "Total hotkey alpha should not change" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // initial_total_coldkey_alpha, - // // "Total coldkey alpha should not change" - // // )(DEPRECATED); - // assert_eq!( - // Alpha::::get((&hotkey, &coldkey, netuid)), - // initial_alpha, - // "Alpha for hotkey-coldkey pair should not change" - // ); - // // This changes because we created a new connection. - // assert_eq!( - // StakingHotkeys::::get(coldkey), - // [hotkey], - // "StakingHotkeys should include the hotkey" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_max_amount --exact --nocapture -#[test] -fn test_stake_into_subnet_max_amount() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let max_tao = u64::MAX; - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 1_000_000_000; // 1 TAO - // let initial_subnet_alpha = 500_000; // 0.5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Record initial values - // let initial_total_stake = TotalStake::::get(); - // let initial_stake = Stake::::get(hotkey, coldkey); - // let initial_total_hotkey_alpha = TotalHotkeyAlpha::::get(hotkey, netuid); - // // let initial_total_coldkey_alpha = TotalColdkeyAlpha::::get(coldkey, netuid);(DEPRECATED) - // let initial_alpha = Alpha::::get((&hotkey, &coldkey, netuid)); - - // // Perform staking with maximum amount - // let alpha_staked = SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, max_tao); - - // // Verify alpha staked is equal to max_tao (for stable mechanism) - // assert_eq!( - // alpha_staked, max_tao, - // "Alpha staked should be equal to max TAO for stable mechanism" - // ); - - // // Check storage updates - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao.saturating_add(max_tao), - // "Subnet TAO should increase by max_tao" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid), - // initial_subnet_alpha, - // "Subnet Alpha In should not change for stable mechanism" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha.saturating_add(max_tao), - // "Subnet Alpha Out should increase by max_tao" - // ); - // assert_eq!( - // TotalStake::::get(), - // initial_total_stake.saturating_add(max_tao), - // "Total stake should increase by max_tao" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // initial_stake.saturating_add(max_tao), - // "Stake for hotkey-coldkey pair should increase by max_tao" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // initial_total_hotkey_alpha.saturating_add(max_tao), - // "Total hotkey alpha should increase by max_tao" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // initial_total_coldkey_alpha.saturating_add(max_tao), - // // "Total coldkey alpha should increase by max_tao" - // // );(DEPRECATED) - // assert_eq!( - // Alpha::::get((&hotkey, &coldkey, netuid)), - // initial_alpha.saturating_add(max_tao), - // "Alpha for hotkey-coldkey pair should increase by max_tao" - // ); - - // // Verify StakingHotkeys is updated - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys should contain the hotkey" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_multiple_stakes --exact --nocapture -#[test] -fn test_stake_into_subnet_multiple_stakes() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let stake_amount = 1_000_000; // 1 TAO - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 1_000_000_000; // 1000 TAO - // let initial_subnet_alpha = 500_000_000; // 500 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Record initial values - // let initial_total_stake = TotalStake::::get(); - // let initial_stake = Stake::::get(hotkey, coldkey); - // let initial_total_hotkey_alpha = TotalHotkeyAlpha::::get(hotkey, netuid); - // let initial_total_coldkey_alpha = TotalColdkeyAlpha::::get(coldkey, netuid); - // let initial_alpha = Alpha::::get((&hotkey, &coldkey, netuid)); - - // // Perform multiple stakes - // let num_stakes = 5; - // let mut total_alpha_staked = 0; - - // for _ in 0..num_stakes { - // let alpha_staked = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, stake_amount); - // total_alpha_staked += alpha_staked; - // } - - // // Verify cumulative effects - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao + (stake_amount * num_stakes as u64), - // "Subnet TAO should increase by total staked amount" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid), - // initial_subnet_alpha, - // "Subnet Alpha In should not change for stable mechanism" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha + total_alpha_staked, - // "Subnet Alpha Out should increase by total alpha staked" - // ); - // assert_eq!( - // TotalStake::::get(), - // initial_total_stake + (stake_amount * num_stakes as u64), - // "Total stake should increase by total staked amount" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // initial_stake + (stake_amount * num_stakes as u64), - // "Stake for hotkey-coldkey pair should increase by total staked amount" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // initial_total_hotkey_alpha + total_alpha_staked, - // "Total hotkey alpha should increase by total alpha staked" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // initial_total_coldkey_alpha + total_alpha_staked, - // // "Total coldkey alpha should increase by total alpha staked" - // // );(DEPRECATED) - // assert_eq!( - // Alpha::::get((&hotkey, &coldkey, netuid)), - // initial_alpha + total_alpha_staked, - // "Alpha for hotkey-coldkey pair should increase by total alpha staked" - // ); - - // // Verify StakingHotkeys is updated - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys should contain the hotkey" - // ); - // assert_eq!( - // staking_hotkeys.len(), - // 1, - // "StakingHotkeys should only contain one entry" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_different_subnets --exact --nocapture -#[test] -fn test_stake_into_subnet_different_subnets() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let stake_amount = 1_000_000; // 1 TAO - - // // Set up two subnets with different mechanisms - // let netuid1 = 1; - // let netuid2 = 2; - // SubnetMechanism::::insert(netuid1, 0); // Stable mechanism - // SubnetMechanism::::insert(netuid2, 1); // Dynamic mechanism - - // // Initialize subnets with some existing TAO and Alpha - // let initial_subnet_tao = 1_000_000_000; // 1000 TAO - // let initial_subnet_alpha = 500_000_000; // 500 Alpha - // for netuid in [netuid1, netuid2].iter() { - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - // } - - // // Stake into subnet 1 (Stable mechanism) - // let alpha_staked1 = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid1, stake_amount); - - // // Verify subnet 1 effects - // assert_eq!( - // SubnetTAO::::get(netuid1), - // initial_subnet_tao + stake_amount, - // "Subnet 1 TAO should increase by staked amount" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid1), - // initial_subnet_alpha, - // "Subnet 1 Alpha In should not change for stable mechanism" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid1), - // initial_subnet_alpha + alpha_staked1, - // "Subnet 1 Alpha Out should increase by alpha staked" - // ); - // assert_eq!( - // alpha_staked1, stake_amount, - // "For stable mechanism, alpha staked should equal TAO staked" - // ); - - // // Stake into subnet 2 (Dynamic mechanism) - // let alpha_staked2 = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid2, stake_amount); - - // // Verify subnet 2 effects - // assert_eq!( - // SubnetTAO::::get(netuid2), - // initial_subnet_tao + stake_amount, - // "Subnet 2 TAO should increase by staked amount" - // ); - // assert!( - // SubnetAlphaIn::::get(netuid2) < initial_subnet_alpha, - // "Subnet 2 Alpha In should decrease for dynamic mechanism" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid2), - // initial_subnet_alpha + alpha_staked2, - // "Subnet 2 Alpha Out should increase by alpha staked" - // ); - // assert!( - // alpha_staked2 < stake_amount, - // "For dynamic mechanism, alpha staked should be less than TAO staked" - // ); - - // // Verify isolated effects - // assert_eq!( - // SubnetTAO::::get(netuid1), - // initial_subnet_tao + stake_amount, - // "Subnet 1 TAO should remain unchanged after staking in subnet 2" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid1), - // initial_subnet_alpha + alpha_staked1, - // "Subnet 1 Alpha Out should remain unchanged after staking in subnet 2" - // ); - - // // Verify global effects - // assert_eq!( - // TotalStake::::get(), - // stake_amount * 2, - // "Total stake should increase by total staked amount across both subnets" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // stake_amount * 2, - // "Stake for hotkey-coldkey pair should increase by total staked amount" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid1), - // alpha_staked1, - // "Total hotkey alpha for subnet 1 should match alpha staked in subnet 1" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid2), - // alpha_staked2, - // "Total hotkey alpha for subnet 2 should match alpha staked in subnet 2" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid1), - // // alpha_staked1, - // // "Total coldkey alpha for subnet 1 should match alpha staked in subnet 1" - // // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid2), - // // alpha_staked2, - // // "Total coldkey alpha for subnet 2 should match alpha staked in subnet 2" - // // );(DEPRECATED) - - // // Verify StakingHotkeys is updated - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys should contain the hotkey" - // ); - // assert_eq!( - // staking_hotkeys.len(), - // 1, - // "StakingHotkeys should only contain one entry" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_hotkey_coldkey_combination --exact --nocapture -#[test] -fn test_stake_into_subnet_hotkey_coldkey_combination() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let stake_amount = 1_000_000; // 1 TAO - // SubnetMechanism::::insert(netuid, 0); // Stable mechanism - - // let hotkey1 = U256::from(1); - // let hotkey2 = U256::from(2); - // let coldkey1 = U256::from(3); - // let coldkey2 = U256::from(4); - - // // Stake with hotkey1-coldkey1 combination - // let alpha_staked1 = - // SubtensorModule::stake_into_subnet(&hotkey1, &coldkey1, netuid, stake_amount); - // assert_eq!( - // alpha_staked1, stake_amount, - // "Alpha staked should equal TAO staked for stable mechanism" - // ); - // assert_eq!( - // Alpha::::get((hotkey1, coldkey1, netuid)), - // stake_amount, - // "Alpha storage should be updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey1, coldkey1), - // stake_amount, - // "Stake storage should be updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey1, netuid), - // stake_amount, - // "TotalHotkeyAlpha should be updated" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey1, netuid), - // // stake_amount, - // // "TotalColdkeyAlpha should be updated" - // // );(DEPRECATED) - - // // Verify StakingHotkeys for coldkey1 - // let staking_hotkeys1 = StakingHotkeys::::get(coldkey1); - // assert!( - // staking_hotkeys1.contains(&hotkey1), - // "StakingHotkeys should contain hotkey1 for coldkey1" - // ); - // assert_eq!( - // staking_hotkeys1.len(), - // 1, - // "StakingHotkeys should only contain one entry for coldkey1" - // ); - - // // Stake with hotkey2-coldkey1 combination - // let alpha_staked2 = - // SubtensorModule::stake_into_subnet(&hotkey2, &coldkey1, netuid, stake_amount); - // assert_eq!( - // alpha_staked2, stake_amount, - // "Alpha staked should equal TAO staked for stable mechanism" - // ); - // assert_eq!( - // Alpha::::get((hotkey2, coldkey1, netuid)), - // stake_amount, - // "Alpha storage should be updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey2, coldkey1), - // stake_amount, - // "Stake storage should be updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey2, netuid), - // stake_amount, - // "TotalHotkeyAlpha should be updated" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey1, netuid), - // // stake_amount * 2, - // // "TotalColdkeyAlpha should be updated" - // // );(DEPRECATED) - - // // Verify updated StakingHotkeys for coldkey1 - // let updated_staking_hotkeys1 = StakingHotkeys::::get(coldkey1); - // assert!( - // updated_staking_hotkeys1.contains(&hotkey1), - // "StakingHotkeys should still contain hotkey1 for coldkey1" - // ); - // assert!( - // updated_staking_hotkeys1.contains(&hotkey2), - // "StakingHotkeys should now contain hotkey2 for coldkey1" - // ); - // assert_eq!( - // updated_staking_hotkeys1.len(), - // 2, - // "StakingHotkeys should contain two entries for coldkey1" - // ); - - // // Stake with hotkey1-coldkey2 combination - // let alpha_staked3 = - // SubtensorModule::stake_into_subnet(&hotkey1, &coldkey2, netuid, stake_amount); - // assert_eq!( - // alpha_staked3, stake_amount, - // "Alpha staked should equal TAO staked for stable mechanism" - // ); - // assert_eq!( - // Alpha::::get((hotkey1, coldkey2, netuid)), - // stake_amount, - // "Alpha storage should be updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey1, coldkey2), - // stake_amount, - // "Stake storage should be updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey1, netuid), - // stake_amount * 2, - // "TotalHotkeyAlpha should be updated" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey2, netuid), - // // stake_amount, - // // "TotalColdkeyAlpha should be updated" - // // );(DEPRECATED) - - // // Verify StakingHotkeys for coldkey2 - // let staking_hotkeys2 = StakingHotkeys::::get(coldkey2); - // assert!( - // staking_hotkeys2.contains(&hotkey1), - // "StakingHotkeys should contain hotkey1 for coldkey2" - // ); - // assert_eq!( - // staking_hotkeys2.len(), - // 1, - // "StakingHotkeys should only contain one entry for coldkey2" - // ); - - // // Verify total stakes - // assert_eq!( - // TotalStake::::get(), - // stake_amount * 3, - // "Total stake should be the sum of all stakes" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_edge_cases --exact --nocapture -#[test] -fn test_stake_into_subnet_edge_cases() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Test with very large existing alpha and TAO in subnet - // SubnetMechanism::::insert(netuid, 1); // Dynamic mechanism - // SubnetTAO::::insert(netuid, u64::MAX / 2); - // let large_stake = u64::MAX / 1000; // 1 billion - // SubnetAlphaIn::::insert(netuid, large_stake ); - // let alpha_staked_large = SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, large_stake); - // log::debug!(target: "subtensor", "Alpha staked large: {:?}", alpha_staked_large); - // assert!(alpha_staked_large > 0, "Alpha staked should be non-zero for large stake"); - // assert!(alpha_staked_large < large_stake, "Alpha staked should be less than TAO staked for dynamic mechanism"); - - // // Reset subnet values - // SubnetTAO::::insert(netuid, 0); - // SubnetAlphaIn::::insert(netuid, 0); - - // // Test potential precision loss - // SubnetTAO::::insert(netuid, u64::MAX); - // SubnetAlphaIn::::insert(netuid, u64::MAX / 2); - // let precision_stake = u64::MAX / 2; - // let alpha_staked_precision = SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, precision_stake); - // assert!(alpha_staked_precision > 0, "Alpha staked should be non-zero for large stake with potential precision loss"); - // assert!(alpha_staked_precision < precision_stake, "Alpha staked should be less than TAO staked for dynamic mechanism with potential precision loss"); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_storage_consistency --exact --nocapture -#[test] -fn test_stake_into_subnet_storage_consistency() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let stake_amount = 1_000_000; // 1 million - - // // Initial storage values - // let initial_subnet_tao = SubnetTAO::::get(netuid); - // let initial_subnet_alpha_in = SubnetAlphaIn::::get(netuid); - // let initial_subnet_alpha_out = SubnetAlphaOut::::get(netuid); - // let initial_total_stake = TotalStake::::get(); - // let initial_alpha = Alpha::::get((hotkey, coldkey, netuid)); - // let initial_stake = Stake::::get(hotkey, coldkey); - // // let initial_total_coldkey_alpha = TotalColdkeyAlpha::::get(coldkey, netuid); (DEPRECATED) - // let initial_total_hotkey_alpha = TotalHotkeyAlpha::::get(hotkey, netuid); - - // // Perform staking - // let alpha_staked = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, stake_amount); - - // // Verify storage updates - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao + stake_amount, - // "SubnetTAO should be increased by stake amount" - // ); - // assert!( - // SubnetAlphaIn::::get(netuid) <= initial_subnet_alpha_in, - // "SubnetAlphaIn should not increase" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha_out + alpha_staked, - // "SubnetAlphaOut should be increased by alpha staked" - // ); - // assert_eq!( - // TotalStake::::get(), - // initial_total_stake + stake_amount, - // "TotalStake should be increased by stake amount" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // initial_alpha + alpha_staked, - // "Alpha for hotkey-coldkey pair should be increased by alpha staked" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // initial_stake + stake_amount, - // "Stake for hotkey-coldkey pair should be increased by stake amount" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // initial_total_coldkey_alpha + alpha_staked, - // // "TotalColdkeyAlpha should be increased by alpha staked" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // initial_total_hotkey_alpha + alpha_staked, - // "TotalHotkeyAlpha should be increased by alpha staked" - // ); - - // // Verify StakingHotkeys - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // staking_hotkeys.contains(&hotkey), - // "StakingHotkeys should contain the hotkey" - // ); - - // // Check no unintended side effects - // assert_eq!( - // SubnetTAO::::get(netuid + 1), - // 0, - // "SubnetTAO for other subnets should not be affected" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid + 1), - // 0, - // "SubnetAlphaIn for other subnets should not be affected" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid + 1), - // 0, - // "SubnetAlphaOut for other subnets should not be affected" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid + 1)), - // 0, - // "Alpha for other subnets should not be affected" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid + 1), - // // 0, - // // "TotalColdkeyAlpha for other subnets should not be affected" - // // );(DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid + 1), - // 0, - // "TotalHotkeyAlpha for other subnets should not be affected" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_stake_into_subnet_return_value --exact --nocapture -#[test] -fn test_stake_into_subnet_return_value() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Scenario 1: Stable mechanism (mechanism_id = 0) - // SubnetMechanism::::insert(netuid, 0); - // let stake_amount_1 = 1_000_000; // 1 million - // let alpha_staked_1 = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, stake_amount_1); - // assert_eq!( - // alpha_staked_1, stake_amount_1, - // "For stable mechanism, alpha_staked should equal stake_amount" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // alpha_staked_1, - // "Alpha in storage should match returned value" - // ); - - // // Reset storage - // Alpha::::remove((hotkey, coldkey, netuid)); - // SubnetAlphaIn::::remove(netuid); - // SubnetAlphaOut::::remove(netuid); - // SubnetTAO::::remove(netuid); - - // // Scenario 2: Dynamic mechanism (mechanism_id = 1) - // SubnetMechanism::::insert(netuid, 1); - // let initial_subnet_tao = 10_000_000; // 10 million - // let initial_subnet_alpha = 5_000_000; // 5 million - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - - // let stake_amount_2 = 2_000_000; // 2 million - // let alpha_staked_2 = - // SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, stake_amount_2); - - // // Calculate expected alpha staked - // let k: I96F32 = - // I96F32::from_num(initial_subnet_alpha) * I96F32::from_num(initial_subnet_tao); - // let expected_alpha_staked: u64 = (I96F32::from_num(initial_subnet_alpha) - // - (k / (I96F32::from_num(initial_subnet_tao) + I96F32::from_num(stake_amount_2)))) - // .to_num::(); - - // assert_eq!( - // alpha_staked_2, expected_alpha_staked, - // "For dynamic mechanism, alpha_staked should match the calculated value" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // alpha_staked_2, - // "Alpha in storage should match returned value" - // ); - - // // Verify consistency with other storage updates - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // alpha_staked_2, - // "SubnetAlphaOut should match the returned alpha_staked" - // ); - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao + stake_amount_2, - // "SubnetTAO should be increased by stake amount" - // ); - }); -} - -// Test titles and descriptions for exhaustive testing of unstake_from_subnet function: - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_dynamic_mechanism --exact --nocapture -#[test] -fn test_unstake_from_subnet_dynamic_mechanism() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha first - // let alpha_to_stake = 1_000_000; // 1 Alpha - // Alpha::::insert((hotkey, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, alpha_to_stake); - - // // Perform unstaking - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_to_stake); - - // // Verify correct TAO calculation - // let expected_k = - // I96F32::from_num(initial_subnet_alpha) * I96F32::from_num(initial_subnet_tao); - // let expected_tao_unstaked = I96F32::from_num(initial_subnet_tao) - // - (expected_k / I96F32::from_num(initial_subnet_alpha + alpha_to_stake)); - // let expected_tao_unstaked_u64 = expected_tao_unstaked.to_num::(); - // assert_eq!( - // tao_unstaked, expected_tao_unstaked_u64, - // "TAO unstaked calculation is incorrect" - // ); - - // // Check subnet alpha and TAO updates - // let new_subnet_alpha = SubnetAlphaIn::::get(netuid); - // let new_subnet_tao = SubnetTAO::::get(netuid); - // assert_eq!( - // new_subnet_alpha, - // initial_subnet_alpha + alpha_to_stake, - // "Subnet alpha not updated correctly" - // ); - // assert_eq!( - // new_subnet_tao, - // initial_subnet_tao - tao_unstaked, - // "Subnet TAO not updated correctly" - // ); - - // // Ensure global and per-account storage updates - // assert_eq!( - // TotalStake::::get(), - // 0, - // "Total stake not updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // 0, - // "Stake for hotkey-coldkey pair not updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // 0, - // "Total hotkey alpha not updated correctly" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // 0, - // // "Total coldkey alpha not updated correctly" - // // ); (DEPRECATED) - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // 0, - // "Alpha for hotkey-coldkey pair not updated correctly" - // ); - - // // Verify StakingHotkeys update - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // !staking_hotkeys.contains(&hotkey), - // "Hotkey should be removed from StakingHotkeys" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_stable_mechanism --exact --nocapture -#[test] -fn test_unstake_from_subnet_stable_mechanism() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha first - // let alpha_to_stake = 1_000_000; // 1 Alpha - // Alpha::::insert((hotkey, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, alpha_to_stake); - // Stake::::insert(hotkey, coldkey, alpha_to_stake); - // TotalStake::::put(alpha_to_stake); - - // // Perform unstaking - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_to_stake); - - // // Verify TAO unstaked equals alpha unstaked - // assert_eq!( - // tao_unstaked, alpha_to_stake, - // "TAO unstaked should equal alpha unstaked in stable mechanism" - // ); - - // // Check subnet alpha and TAO updates - // let new_subnet_alpha = SubnetAlphaIn::::get(netuid); - // let new_subnet_tao = SubnetTAO::::get(netuid); - // assert_eq!( - // new_subnet_alpha, 0, - // "Subnet alpha should be zero in stable mechanism" - // ); - // assert_eq!( - // new_subnet_tao, - // initial_subnet_tao - tao_unstaked, - // "Subnet TAO not updated correctly" - // ); - - // // Ensure global and per-account storage updates - // assert_eq!( - // TotalStake::::get(), - // 0, - // "Total stake not updated correctly" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // 0, - // "Stake for hotkey-coldkey pair not updated correctly" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // 0, - // "Total hotkey alpha not updated correctly" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // 0, - // // "Total coldkey alpha not updated correctly" - // // ); (DEPRECATED) - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // 0, - // "Alpha for hotkey-coldkey pair not updated correctly" - // ); - - // // Verify StakingHotkeys update - // let staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // !staking_hotkeys.contains(&hotkey), - // "Hotkey should be removed from StakingHotkeys" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_zero_alpha --exact --nocapture -#[test] -fn test_unstake_from_subnet_zero_alpha() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha first - // let alpha_to_stake = 1_000_000; // 1 Alpha - // Alpha::::insert((hotkey, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, alpha_to_stake); - // Stake::::insert(hotkey, coldkey, alpha_to_stake); - // TotalStake::::put(alpha_to_stake); - - // // Perform unstaking of zero alpha - // let tao_unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 0); - - // // Verify no changes occurred - // assert_eq!(tao_unstaked, 0, "No TAO should be unstaked"); - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao, - // "Subnet TAO should not change" - // ); - // assert_eq!( - // SubnetAlphaIn::::get(netuid), - // initial_subnet_alpha, - // "Subnet alpha should not change" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha, - // "Subnet alpha out should not change" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // alpha_to_stake, - // "Alpha for hotkey-coldkey pair should not change" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // alpha_to_stake, - // // "Total coldkey alpha should not change" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // alpha_to_stake, - // "Total hotkey alpha should not change" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // alpha_to_stake, - // "Stake for hotkey-coldkey pair should not change" - // ); - // assert_eq!( - // TotalStake::::get(), - // alpha_to_stake, - // "Total stake should not change" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_all_alpha --exact --nocapture -#[test] -fn test_unstake_from_subnet_all_alpha() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha first - // let alpha_to_stake = 1_000_000; // 1 Alpha - // Alpha::::insert((hotkey, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, alpha_to_stake); - // Stake::::insert(hotkey, coldkey, alpha_to_stake); - // TotalStake::::put(alpha_to_stake); - - // // Add hotkey to StakingHotkeys - // let mut staking_hotkeys = StakingHotkeys::::get(coldkey); - // staking_hotkeys.push(hotkey); - // StakingHotkeys::::insert(coldkey, staking_hotkeys); - - // // Perform unstaking of all alpha - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_to_stake); - - // // Verify proper removal of storage entries - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao - tao_unstaked, - // "Subnet TAO should be updated" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha - alpha_to_stake, - // "Subnet alpha out should be updated" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // 0, - // "Alpha for hotkey-coldkey pair should be zero" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // 0, - // // "Total coldkey alpha should be zero" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // 0, - // "Total hotkey alpha should be zero" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // 0, - // "Stake for hotkey-coldkey pair should be zero" - // ); - // assert_eq!(TotalStake::::get(), 0, "Total stake should be zero"); - - // // Verify StakingHotkeys update - // let updated_staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // !updated_staking_hotkeys.contains(&hotkey), - // "Hotkey should be removed from StakingHotkeys" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_partial_alpha --exact --nocapture -#[test] -fn test_unstake_from_subnet_partial_alpha() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 50_000_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha first - // let alpha_to_stake = 2_000_000; // 2 Alpha - // Alpha::::insert((hotkey, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, alpha_to_stake); - // Stake::::insert(hotkey, coldkey, alpha_to_stake); - // TotalStake::::put(alpha_to_stake); - - // // Perform partial unstaking - // let alpha_to_unstake = 1_000_000; // 1 Alpha - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_to_unstake); - - // // Verify storage updates - // assert!(tao_unstaked > 0, "Partial TAO should be unstaked"); - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao - tao_unstaked, - // "Subnet TAO should be updated" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha - alpha_to_unstake, - // "Subnet alpha out should be updated" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // alpha_to_stake - alpha_to_unstake, - // "Alpha for hotkey-coldkey pair should be updated" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // alpha_to_stake - alpha_to_unstake, - // // "Total coldkey alpha should be updated" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // alpha_to_stake - alpha_to_unstake, - // "Total hotkey alpha should be updated" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // alpha_to_stake - tao_unstaked, - // "Stake for hotkey-coldkey pair should be updated" - // ); - // assert_eq!( - // TotalStake::::get(), - // alpha_to_stake - tao_unstaked, - // "Total stake should be updated" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_nonexistent_stake --exact --nocapture -#[test] -fn test_unstake_from_subnet_nonexistent_stake() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Attempt to unstake from a non-existent stake - // let alpha_to_unstake = 1_000_000; // 1 Alpha - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_to_unstake); - - // // Verify no changes - // assert_eq!(tao_unstaked, 0, "No TAO should be unstaked"); - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao, - // "Subnet TAO should remain unchanged" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha, - // "Subnet alpha out should remain unchanged" - // ); - // assert_eq!( - // Alpha::::get((hotkey, coldkey, netuid)), - // 0, - // "Alpha for hotkey-coldkey pair should remain zero" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // 0, - // // "Total coldkey alpha should remain zero" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey, netuid), - // 0, - // "Total hotkey alpha should remain zero" - // ); - // assert_eq!( - // Stake::::get(hotkey, coldkey), - // 0, - // "Stake for hotkey-coldkey pair should remain zero" - // ); - // assert_eq!( - // TotalStake::::get(), - // 0, - // "Total stake should remain zero" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_multiple_hotkeys --exact --nocapture -#[test] -fn test_unstake_from_subnet_multiple_hotkeys() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey1 = U256::from(1); - // let hotkey2 = U256::from(2); - // let coldkey = U256::from(3); - - // // Set up the subnet with dynamic mechanism - // SubnetMechanism::::insert(netuid, 1); - - // // Initialize subnet with some existing TAO and Alpha - // let initial_subnet_tao = 10_000_000_000; // 10 TAO - // let initial_subnet_alpha = 5_000_000; // 5 Alpha - // SubnetTAO::::insert(netuid, initial_subnet_tao); - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); - // SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); - - // // Stake some alpha for both hotkeys - // let alpha_to_stake = 1_000_000; // 1 Alpha - // Alpha::::insert((hotkey1, coldkey, netuid), alpha_to_stake); - // Alpha::::insert((hotkey2, coldkey, netuid), alpha_to_stake); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, alpha_to_stake * 2); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey1, netuid, alpha_to_stake); - // TotalHotkeyAlpha::::insert(hotkey2, netuid, alpha_to_stake); - // Stake::::insert(hotkey1, coldkey, initial_subnet_tao); - // Stake::::insert(hotkey2, coldkey, initial_subnet_tao); - // TotalStake::::put(initial_subnet_tao); - - // // Add both hotkeys to StakingHotkeys - // let staking_hotkeys = vec![hotkey1, hotkey2]; - // StakingHotkeys::::insert(coldkey, staking_hotkeys.clone()); - - // // Unstake all alpha from hotkey1 - // let tao_unstaked = - // SubtensorModule::unstake_from_subnet(&hotkey1, &coldkey, netuid, alpha_to_stake); - - // // Verify storage updates - // assert_eq!( - // SubnetTAO::::get(netuid), - // initial_subnet_tao - tao_unstaked, - // "Subnet TAO should be updated" - // ); - // assert_eq!( - // SubnetAlphaOut::::get(netuid), - // initial_subnet_alpha - alpha_to_stake, - // "Subnet alpha out should be updated" - // ); - // assert_eq!( - // Alpha::::get((hotkey1, coldkey, netuid)), - // 0, - // "Alpha for hotkey1-coldkey pair should be zero" - // ); - // assert_eq!( - // Alpha::::get((hotkey2, coldkey, netuid)), - // alpha_to_stake, - // "Alpha for hotkey2-coldkey pair should remain unchanged" - // ); - // // assert_eq!( - // // TotalColdkeyAlpha::::get(coldkey, netuid), - // // alpha_to_stake, - // // "Total coldkey alpha should be updated" - // // ); (DEPRECATED) - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey1, netuid), - // 0, - // "Total hotkey1 alpha should be zero" - // ); - // assert_eq!( - // TotalHotkeyAlpha::::get(hotkey2, netuid), - // alpha_to_stake, - // "Total hotkey2 alpha should remain unchanged" - // ); - // assert_eq!( - // Stake::::get(hotkey1, coldkey), - // initial_subnet_tao - tao_unstaked, - // "Stake for hotkey1-coldkey pair should be updated" - // ); - // assert_eq!( - // Stake::::get(hotkey2, coldkey), - // initial_subnet_tao, - // "Stake for hotkey2-coldkey pair should remain unchanged" - // ); - // assert_eq!( - // TotalStake::::get(), - // initial_subnet_tao - tao_unstaked, - // "Total stake should be updated" - // ); - - // // Verify StakingHotkeys update - // let updated_staking_hotkeys = StakingHotkeys::::get(coldkey); - // assert!( - // !updated_staking_hotkeys.contains(&hotkey1), - // "Hotkey1 should be removed from StakingHotkeys" - // ); - // assert!( - // updated_staking_hotkeys.contains(&hotkey2), - // "Hotkey2 should remain in StakingHotkeys" - // ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_edge_cases --exact --nocapture -#[test] -fn test_unstake_from_subnet_edge_cases() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Test case 1: Maximum u64 values - // let max_u64 = u64::MAX; - // SubnetTAO::::insert(netuid, max_u64); - // SubnetAlphaIn::::insert(netuid, max_u64); - // SubnetAlphaOut::::insert(netuid, max_u64); - // Alpha::::insert((hotkey, coldkey, netuid), max_u64); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, max_u64); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey, netuid, max_u64); - // Stake::::insert(hotkey, coldkey, max_u64); - // TotalStake::::put(max_u64); - - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, max_u64); - // assert_eq!( - // unstaked, max_u64, - // "Should unstake maximum u64 value without overflow" - // ); - - // // Test case 2: Unstaking more than staked - // SubnetTAO::::insert(netuid, 1000); - // SubnetAlphaIn::::insert(netuid, 1000); - // SubnetAlphaOut::::insert(netuid, 1000); - // Alpha::::insert((hotkey, coldkey, netuid), 500); - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 1000); - // assert_eq!(unstaked, 500, "Should only unstake available amount"); - - // // Test case 3: Unstaking from empty subnet - // SubnetTAO::::insert(netuid, 0); - // SubnetAlphaIn::::insert(netuid, 0); - // SubnetAlphaOut::::insert(netuid, 0); - // Alpha::::insert((hotkey, coldkey, netuid), 0); - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 100); - // assert_eq!(unstaked, 0, "Should not unstake from empty subnet"); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_concurrent_stakes --exact --nocapture -#[test] -fn test_unstake_from_subnet_concurrent_stakes() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey1 = U256::from(1); - // let hotkey2 = U256::from(2); - // let coldkey = U256::from(3); - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // SubnetTAO::::insert(netuid, 10_000); - // SubnetAlphaIn::::insert(netuid, 10_000); - // SubnetAlphaOut::::insert(netuid, 10_000); - - // // Stake for both hotkeys - // Alpha::::insert((hotkey1, coldkey, netuid), 5000); - // Alpha::::insert((hotkey2, coldkey, netuid), 5000); - // // TotalColdkeyAlpha::::insert(coldkey, netuid, 10_000); (DEPRECATED) - // TotalHotkeyAlpha::::insert(hotkey1, netuid, 5000); - // TotalHotkeyAlpha::::insert(hotkey2, netuid, 5000); - // Stake::::insert(hotkey1, coldkey, 5000); - // Stake::::insert(hotkey2, coldkey, 5000); - // TotalStake::::put(10_000); - - // // Unstake from hotkey1 - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey1, &coldkey, netuid, 3000); - // assert_eq!(unstaked, 3000, "Should unstake 3000 from hotkey1"); - - // // Verify storage updates - // assert_eq!(Alpha::::get((hotkey1, coldkey, netuid)), 2000); - // assert_eq!(Alpha::::get((hotkey2, coldkey, netuid)), 5000); - // // assert_eq!(TotalColdkeyAlpha::::get(coldkey, netuid), 7000); (DEPRECATED) - // assert_eq!(TotalHotkeyAlpha::::get(hotkey1, netuid), 2000); - // assert_eq!(TotalHotkeyAlpha::::get(hotkey2, netuid), 5000); - // assert_eq!(Stake::::get(hotkey1, coldkey), 2000); - // assert_eq!(Stake::::get(hotkey2, coldkey), 5000); - // assert_eq!(TotalStake::::get(), 7000); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test alpha -- test_unstake_from_subnet_return_value --exact --nocapture -#[test] -fn test_unstake_from_subnet_return_value() { - new_test_ext(1).execute_with(|| { - assert!(false); - - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - - // // Set up the subnet with stable mechanism - // SubnetMechanism::::insert(netuid, 0); - - // // Initialize subnet with some existing TAO and Alpha - // SubnetTAO::::insert(netuid, 10_000); - // SubnetAlphaIn::::insert(netuid, 10_000); - // SubnetAlphaOut::::insert(netuid, 10_000); - // Alpha::::insert((hotkey, coldkey, netuid), 5000); - - // // Test case 1: Unstake exact amount - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 5000); - // assert_eq!(unstaked, 5000, "Should return exact unstaked amount"); - - // // Test case 2: Unstake more than available - // Alpha::::insert((hotkey, coldkey, netuid), 3000); - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 5000); - // assert_eq!( - // unstaked, 3000, - // "Should return available amount when unstaking more than available" - // ); - - // // Test case 3: Unstake from empty stake - // Alpha::::insert((hotkey, coldkey, netuid), 0); - // let unstaked = SubtensorModule::unstake_from_subnet(&hotkey, &coldkey, netuid, 1000); - // assert_eq!( - // unstaked, 0, - // "Should return 0 when unstaking from empty stake" - // ); - }); -} diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 71e41d6bd..85dcb909a 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -1,121 +1,209 @@ #![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] use super::mock::*; -use frame_support::assert_ok; +use crate::*; use sp_core::U256; +use frame_support::assert_ok; use substrate_fixed::types::I64F64; +use substrate_fixed::types::I96F32; + +fn close(value: u64, target: u64, eps: u64) { + assert!( + (value as i64 - target as i64).abs() < eps as i64, + "Assertion failed: value = {}, target = {}, eps = {}", value, target, eps + ) +} -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --workspace --test coinbase -- test_dynamic_flow --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_zero_price_get_zero_tao_in --exact --show-output --nocapture #[test] -fn test_dynamic_flow() { +fn test_dynamic_function_zero_price_get_zero_tao_in() { new_test_ext(1).execute_with(|| { - assert!(false); + let netuid = 1; + let tao_block_emission: u64 = 1_000_000_000; + let alpha_block_emission: u64 = 1_000_000_000; + add_network(netuid, 110, 100); + let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( + netuid, tao_block_emission, tao_block_emission, alpha_block_emission + ); + assert_eq!( tao_in, 0 ); // tao emission drops to price which is zero given no reserves. + assert_eq!( alpha_in, alpha_block_emission ); + assert_eq!( alpha_out, alpha_block_emission ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_price_equal_emission --exact --show-output --nocapture +#[test] +fn test_dynamic_function_price_equal_emission() { + new_test_ext(1).execute_with(|| { + let netuid = 1; + let tao_subnet_emission: u64 = 100_000_000; + let tao_block_emission: u64 = 1_000_000_000; + let alpha_block_emission: u64 = 1_000_000_000; + SubnetTAO::::insert( netuid, 1_000_000_000); + SubnetAlphaIn::::insert( netuid, 1_000_000_000); + add_network(netuid, 110, 100); + let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( + netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + ); + assert_eq!( tao_in, tao_subnet_emission ); // at price == tao_in == tao_subnet_emission + let expected_alpha_in: u64 = (alpha_block_emission * tao_subnet_emission) / tao_block_emission; + close(alpha_in, expected_alpha_in, 10 ); + close(alpha_out, 2 * alpha_block_emission - expected_alpha_in, 10 ); + }); +} - // let netuid = 1; - // let hotkey = U256::from(1); - // let coldkey = U256::from(2); - // let block_emission: u64 = 1000000000; - // let initial_subnet_tao: u64 = 10_000_000_000; - // let initial_subnet_alpha: u64 = 100_000_000_000; - // add_network(netuid, 110, 100); - // // Tempo::::insert(netuid, 1); - // SubnetMechanism::::insert(netuid, 1); - // SubnetTAO::::insert(netuid, initial_subnet_tao); // 10 TAO - // SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); // 100 Alpha - // SubtensorModule::register_neuron( netuid, &hotkey ); - - // // Stake into the network adding 1 TAO through he pool. - // let stake: u64 = 1_000_000_000; - // SubtensorModule::stake_into_subnet( &hotkey, &coldkey, netuid, stake ); // Stake into subnet. - - // // Stake into root adding 1 TAO through the pool. - // SubtensorModule::stake_into_subnet( &hotkey, &coldkey, 0, stake ); // Stake into root. - - // // Check price function. - // let total_alpha_reserves: u64 = SubnetAlphaIn::::get(netuid); - // let total_tao_reserves: u64 = SubnetTAO::::get(netuid); - // let expected_alpha_price: I96F32 = I96F32::from_num(total_tao_reserves) / I96F32::from_num(total_alpha_reserves); - // assert_eq!( SubtensorModule::get_alpha_price( netuid ), expected_alpha_price ); - - // // Run a block forward. - // let total_issuance_before: u64 = TotalIssuance::::get(); - // let total_stake_before: u64 = TotalStake::::get(); - // let subnet_tao_before: u64 = SubnetTAO::::get(netuid); - // let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); - // let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); - // step_block(1); - // // Single subnet gets 100% of block emission. - // assert_eq!(EmissionValues::::get(netuid), block_emission); - // // Alpha_in emission = 1 because alpha_price < emission_value/block_emission - // assert_eq!(SubnetAlphaInEmission::::get(netuid), block_emission); - // assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before + block_emission); - // // Tao_in emission = block_emission * alpha_price - // let expected_tao_emission: u64 = (I96F32::from_num(block_emission) * expected_alpha_price).to_num::(); - // assert_eq!(SubnetTaoInEmission::::get(netuid), expected_tao_emission ); - // assert_eq!(TotalIssuance::::get(), total_issuance_before + expected_tao_emission ); - // assert_eq!(TotalStake::::get(), total_stake_before + expected_tao_emission ); - // assert_eq!(SubnetTAO::::get(netuid), subnet_tao_before + expected_tao_emission ); - // // Alpha_out = 2 - alpha_in thus == 2*block_emission - block_emission = block_emission - // assert_eq!(SubnetAlphaOutEmission::::get(netuid), block_emission); - // assert_eq!(SubnetAlphaOut::::get(netuid), alpha_out_before); // Unchanged. - // assert_eq!(PendingEmission::::get(netuid), block_emission); // All alpha.. - - // // Reset pending. - // PendingRootDivs::::insert(netuid, 0); - // PendingEmission::::insert(netuid, 0); - - // // Set tao weight. - // TaoWeight::::insert( netuid, u64::MAX ); - // let total_issuance_before: u64 = TotalIssuance::::get(); - // let total_stake_before: u64 = TotalStake::::get(); - // let root_tao_before: u64 = SubnetTAO::::get(0); - // let subnet_tao_before: u64 = SubnetTAO::::get(netuid); - // let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); - // let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); - // let previous_pending: u64 = PendingEmission::::get(netuid); - // step_block(1); - // // Single subnet gets 100% of block emission. - // assert_eq!(EmissionValues::::get(netuid), block_emission); - // // Alpha_in emission = 1 because alpha_price < emission_value/block_emission - // assert_eq!(SubnetAlphaInEmission::::get(netuid), block_emission); - // // Get the pending root dividends. - // let pending_root_divs: u64 = PendingRootDivs::::get(netuid); - // // Simualte the swap back to alpha. - // let pending_as_alpha: u64 = SubtensorModule::sim_swap_tao_for_alpha( netuid, pending_root_divs ); - // // Subnet ALpha out Emission . - // assert_eq!(SubnetAlphaOutEmission::::get(netuid), block_emission); - // // Assert difference is Pending emission. - // assert_eq!(PendingEmission::::get(netuid), previous_pending + (block_emission - pending_as_alpha) - 6 ); // All alpha with rounding. - // // Alpha in is increased by emission. - // assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before + block_emission + pending_as_alpha + 5 ); // Corret with rounding. - - // // Lets train the pending. - // let total_issuance_before: u64 = TotalIssuance::::get(); - // let total_stake_before: u64 = TotalStake::::get(); - // let root_tao_before: u64 = SubnetTAO::::get(0); - // let subnet_tao_before: u64 = SubnetTAO::::get(netuid); - // let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); - // let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); - // let previous_pending: u64 = PendingEmission::::get(netuid); - // let root_pending: u64 = PendingRootDivs::::get(netuid); - // SubtensorModule::drain_pending_emission( netuid ); - // // Drained - // assert_eq!(PendingEmission::::get(netuid), 0); - // // Unchanged. - // assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before); - // // Dividends are all pending to this hotkey. - // assert_eq!(HotkeyDividendsPerSubnet::::get(netuid, &hotkey), previous_pending); - // // Root Dividends are all pending to this hotkey. - // assert_eq!(RootDividendsPerSubnet::::get(netuid, &hotkey), root_pending); - - // // TODO( const ): test multiple subnets. - // // TODO( const ): test multi root proportions - // // TODO( const ): test parents etc - +// Test when alpha price is greater than tao_in_proportion +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_alpha_price_greater_than_tao_in --exact --show-output --nocapture +#[test] +fn test_dynamic_function_alpha_price_greater_than_tao_in() { + new_test_ext(1).execute_with(|| { + let netuid = 1; + let tao_subnet_emission: u64 = 500_000_000; + let tao_block_emission: u64 = 1_000_000_000; + let alpha_block_emission: u64 = 1_000_000_000; + SubnetTAO::::insert( netuid, 2_000_000_000); // Higher alpha reserves increases price. + SubnetAlphaIn::::insert( netuid, 1_000_000_000); + add_network(netuid, 110, 100); + let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( + netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + ); + assert_eq!( tao_in, tao_subnet_emission ); // tao_in should be equal to tao_subnet_emission + close(alpha_in, tao_subnet_emission/2, 10 ); + close(alpha_out, 2 * alpha_block_emission - tao_subnet_emission/2, 10 ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_zero_tao_block_emission --exact --show-output --nocapture +#[test] +fn test_dynamic_function_zero_tao_block_emission() { + new_test_ext(1).execute_with(|| { + let netuid = 1; + let tao_subnet_emission: u64 = 100_000_000; + let tao_block_emission: u64 = 0; // Zero tao block emission + let alpha_block_emission: u64 = 1_000_000_000; + add_network(netuid, 110, 100); + let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( + netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + ); + assert_eq!( tao_in, 0 ); // tao_in should be zero due to zero tao_block_emission + assert_eq!( alpha_in, alpha_block_emission ); + assert_eq!( alpha_out, alpha_block_emission ); }); } + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_flow --exact --show-output +// #[test] +// fn test_dynamic_flow() { +// new_test_ext(1).execute_with(|| { + +// let netuid = 1; +// let hotkey = U256::from(1); +// let coldkey = U256::from(2); +// let block_emission: u64 = 1000000000; +// let initial_subnet_tao: u64 = 10_000_000_000; +// let initial_subnet_alpha: u64 = 100_000_000_000; +// add_network(netuid, 110, 100); +// // Tempo::::insert(netuid, 1); +// SubnetMechanism::::insert(netuid, 1); +// SubnetTAO::::insert(netuid, initial_subnet_tao); // 10 TAO +// SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); // 100 Alpha +// SubtensorModule::register_neuron( netuid, &hotkey ); + +// // Stake into the network adding 1 TAO through he pool. +// let stake: u64 = 1_000_000_000; +// SubtensorModule::stake_into_subnet( &hotkey, &coldkey, netuid, stake ); // Stake into subnet. + +// // Stake into root adding 1 TAO through the pool. +// SubtensorModule::stake_into_subnet( &hotkey, &coldkey, 0, stake ); // Stake into root. + +// // Check price function. +// let total_alpha_reserves: u64 = SubnetAlphaIn::::get(netuid); +// let total_tao_reserves: u64 = SubnetTAO::::get(netuid); +// let expected_alpha_price: I96F32 = I96F32::from_num(total_tao_reserves) / I96F32::from_num(total_alpha_reserves); +// assert_eq!( SubtensorModule::get_alpha_price( netuid ), expected_alpha_price ); + +// // Run a block forward. +// let total_issuance_before: u64 = TotalIssuance::::get(); +// let total_stake_before: u64 = TotalStake::::get(); +// let subnet_tao_before: u64 = SubnetTAO::::get(netuid); +// let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); +// let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); +// step_block(1); +// // Single subnet gets 100% of block emission. +// assert_eq!(EmissionValues::::get(netuid), block_emission); +// // Alpha_in emission = 1 because alpha_price < emission_value/block_emission +// assert_eq!(SubnetAlphaInEmission::::get(netuid), block_emission); +// assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before + block_emission); +// // Tao_in emission = block_emission * alpha_price +// let expected_tao_emission: u64 = (I96F32::from_num(block_emission) * expected_alpha_price).to_num::(); +// assert_eq!(SubnetTaoInEmission::::get(netuid), expected_tao_emission ); +// assert_eq!(TotalIssuance::::get(), total_issuance_before + expected_tao_emission ); +// assert_eq!(TotalStake::::get(), total_stake_before + expected_tao_emission ); +// assert_eq!(SubnetTAO::::get(netuid), subnet_tao_before + expected_tao_emission ); +// // Alpha_out = 2 - alpha_in thus == 2*block_emission - block_emission = block_emission +// assert_eq!(SubnetAlphaOutEmission::::get(netuid), block_emission); +// assert_eq!(SubnetAlphaOut::::get(netuid), alpha_out_before); // Unchanged. +// assert_eq!(PendingEmission::::get(netuid), block_emission); // All alpha.. + +// // Reset pending. +// PendingRootDivs::::insert(netuid, 0); +// PendingEmission::::insert(netuid, 0); + +// // Set tao weight. +// TaoWeight::::insert( netuid, u64::MAX ); +// let total_issuance_before: u64 = TotalIssuance::::get(); +// let total_stake_before: u64 = TotalStake::::get(); +// let root_tao_before: u64 = SubnetTAO::::get(0); +// let subnet_tao_before: u64 = SubnetTAO::::get(netuid); +// let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); +// let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); +// let previous_pending: u64 = PendingEmission::::get(netuid); +// step_block(1); +// // Single subnet gets 100% of block emission. +// assert_eq!(EmissionValues::::get(netuid), block_emission); +// // Alpha_in emission = 1 because alpha_price < emission_value/block_emission +// assert_eq!(SubnetAlphaInEmission::::get(netuid), block_emission); +// // Get the pending root dividends. +// let pending_root_divs: u64 = PendingRootDivs::::get(netuid); +// // Simualte the swap back to alpha. +// let pending_as_alpha: u64 = SubtensorModule::sim_swap_tao_for_alpha( netuid, pending_root_divs ); +// // Subnet ALpha out Emission . +// assert_eq!(SubnetAlphaOutEmission::::get(netuid), block_emission); +// // Assert difference is Pending emission. +// assert_eq!(PendingEmission::::get(netuid), previous_pending + (block_emission - pending_as_alpha) - 6 ); // All alpha with rounding. +// // Alpha in is increased by emission. +// assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before + block_emission + pending_as_alpha + 5 ); // Corret with rounding. + +// // Lets train the pending. +// let total_issuance_before: u64 = TotalIssuance::::get(); +// let total_stake_before: u64 = TotalStake::::get(); +// let root_tao_before: u64 = SubnetTAO::::get(0); +// let subnet_tao_before: u64 = SubnetTAO::::get(netuid); +// let alpha_out_before: u64 = SubnetAlphaOut::::get(netuid); +// let alpha_in_before: u64 = SubnetAlphaIn::::get(netuid); +// let previous_pending: u64 = PendingEmission::::get(netuid); +// let root_pending: u64 = PendingRootDivs::::get(netuid); +// SubtensorModule::drain_pending_emission( netuid ); +// // Drained +// assert_eq!(PendingEmission::::get(netuid), 0); +// // Unchanged. +// assert_eq!(SubnetAlphaIn::::get(netuid), alpha_in_before); +// // Dividends are all pending to this hotkey. +// assert_eq!(HotkeyDividendsPerSubnet::::get(netuid, &hotkey), previous_pending); +// // Root Dividends are all pending to this hotkey. +// assert_eq!(RootDividendsPerSubnet::::get(netuid, &hotkey), root_pending); + +// // TODO( const ): test multiple subnets. +// // TODO( const ): test multi root proportions +// // TODO( const ): test parents etc + + +// }); +// } + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --test coinbase test_coinbase_nominator_drainage_no_deltas -- --nocapture #[test] fn test_coinbase_nominator_drainage_no_deltas() { diff --git a/pallets/subtensor/src/tests/mod.rs b/pallets/subtensor/src/tests/mod.rs index 85a70fe1a..9dd3c9d07 100644 --- a/pallets/subtensor/src/tests/mod.rs +++ b/pallets/subtensor/src/tests/mod.rs @@ -1,6 +1,4 @@ mod mock; - -mod alpha; mod batch_tx; mod children; mod coinbase; diff --git a/pallets/subtensor/src/tests/staking2.rs b/pallets/subtensor/src/tests/staking2.rs index 7b9c065ce..6627f47bc 100644 --- a/pallets/subtensor/src/tests/staking2.rs +++ b/pallets/subtensor/src/tests/staking2.rs @@ -1,6 +1,7 @@ use super::mock::*; // use substrate_fixed::types::I96F32; use sp_core::U256; +use crate::*; // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --workspace --test staking2 -- test_swap_tao_for_alpha_dynamic_mechanism --exact --nocapture #[test] @@ -69,7 +70,7 @@ fn test_stake_base_case() { // 1. Stakes are represented as shares in a pool // 2. Multiple coldkeys can stake to a single hotkey // 3. Direct hotkey stakes are distributed proportionally among existing coldkey stakes -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --workspace --test staking2 -- test_swap_tao_for_alpha_dynamic_mechanism --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::staking2::test_share_based_staking --exact --show-output #[test] fn test_share_based_staking() { new_test_ext(1).execute_with(|| { @@ -366,13 +367,14 @@ fn test_share_based_staking() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::staking2::test_share_based_staking_denominator_precision --exact --show-output #[test] fn test_share_based_staking_denominator_precision() { new_test_ext(1).execute_with(|| { let netuid = 1; let hotkey1 = U256::from(1); let coldkey1 = U256::from(2); - let stake_amount = 1_000; + let stake_amount = 1_000_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, @@ -380,6 +382,7 @@ fn test_share_based_staking_denominator_precision() { netuid, stake_amount ); + assert_eq!( Alpha::::get( (hotkey1, coldkey1, netuid) ), stake_amount ); SubtensorModule::decrease_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &coldkey1, @@ -396,6 +399,7 @@ fn test_share_based_staking_denominator_precision() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::staking2::test_share_based_staking_denominator_precision_2 --exact --show-output --nocapture #[test] fn test_share_based_staking_denominator_precision_2() { new_test_ext(1).execute_with(|| { From ce9a733e627f7b345968b3ad9e16abd7e6094722 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 13:06:43 -0500 Subject: [PATCH 2/7] unstake all alpha --- .../subtensor/src/coinbase/run_coinbase.rs | 61 ++++++++------- pallets/subtensor/src/macros/dispatches.rs | 37 ++++++++++ pallets/subtensor/src/staking/remove_stake.rs | 74 +++++++++++++++++++ pallets/subtensor/src/tests/coinbase.rs | 70 ++++++++++++++---- 4 files changed, 196 insertions(+), 46 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index b4afd305b..6d25c3754 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -20,51 +20,51 @@ pub struct WeightsTlockPayload { impl Pallet { - pub fn get_dynamic_tao_emission( netuid: u16, subnet_emission: u64, tao_block_emission: u64, alpha_block_emission: u64 ) -> (u64, u64, u64) { + pub fn get_dynamic_tao_emission( netuid: u16, tao_emission: u64, alpha_block_emission: u64 ) -> (u64, u64, u64) { - // Compute tao_in, as proportion of block emission from subnet emission - let tao_in_proportion: I96F32 = I96F32::from_num(subnet_emission).checked_div( I96F32::from_num( tao_block_emission ) ).unwrap_or( I96F32::from_num(0) ); - log::debug!("{:?} - tao_in_proportion: {:?}", netuid, tao_in_proportion); + // Init terms. + let mut tao_in_emission: I96F32 = I96F32::from_num( tao_emission ); + let float_alpha_block_emission: I96F32 = I96F32::from_num( alpha_block_emission ); // Get alpha price for subnet. let alpha_price: I96F32 = Self::get_alpha_price( netuid ); log::debug!("{:?} - alpha_price: {:?}", netuid, alpha_price); - // Switch on relationship between alpha price and tao_in - let tao_in_emission: I96F32; - let alpha_in_emission: I96F32; - let alpha_out_emission: I96F32; - if alpha_price <= tao_in_proportion { - log::debug!("{:?} - alpha_price: {:?} <= tao_in_proportion: {:?}", netuid, alpha_price, tao_in_proportion); - // If price if less than tao_in, multiply alpha_price by total block_emission to get tao_emission. - tao_in_emission = alpha_price.saturating_mul( I96F32::from_num( tao_block_emission ) ); - - // Alpha in alpha block emission. - alpha_in_emission = I96F32::from_num( alpha_block_emission ) ; - - // Set Alpha in emission. - alpha_out_emission = I96F32::from_num( 2 * alpha_block_emission).saturating_sub( alpha_in_emission ); - } else { - log::debug!("{:?} - alpha_price: {:?} > tao_in_proportion: {:?}", netuid, alpha_price, tao_in_proportion); - // If price is greater than tao_in, multiply back tao_in by tao_block_emission. - tao_in_emission = I96F32::from_num( subnet_emission ); - - // We attain alpha_in emission by dividing tao_in by alpha price and multiplying by alpha_block_emission - alpha_in_emission = I96F32::from_num( alpha_block_emission ).saturating_mul( tao_in_proportion.checked_div(alpha_price).unwrap_or(I96F32::from_num(0)) ); - - // Set Alpha in emission. - alpha_out_emission = I96F32::from_num(2).saturating_mul(I96F32::from_num(alpha_block_emission)).saturating_sub( alpha_in_emission ); + // Get initial alpha_in + let mut alpha_in_emission: I96F32 = I96F32::from_num( tao_emission ).checked_div( alpha_price ).unwrap_or( float_alpha_block_emission ); + + // Check if we are emitting too much alpha_in + if alpha_in_emission >= float_alpha_block_emission { + log::debug!("{:?} - alpha_in_emission: {:?} > alpha_block_emission: {:?}", netuid, alpha_in_emission, float_alpha_block_emission); + + // Scale down tao_in + tao_in_emission = alpha_price.saturating_mul( float_alpha_block_emission); + + // Set to max alpha_block_emission + alpha_in_emission = float_alpha_block_emission; + } - // Compute alpha out emission as 2 x alpha_block_emission - alpha_in_emission + // Avoid rounding errors. + if tao_in_emission < I96F32::from_num(1){ + alpha_in_emission = I96F32::from_num(0); + tao_in_emission = I96F32::from_num(0); + } + + // Set Alpha in emission. + let alpha_out_emission = I96F32::from_num(2).saturating_mul( float_alpha_block_emission ).saturating_sub( alpha_in_emission ); + + // Log results. log::debug!("{:?} - tao_in_emission: {:?}", netuid, tao_in_emission); log::debug!("{:?} - alpha_in_emission: {:?}", netuid, alpha_in_emission); - log::debug!("{:?} - alpha_in_emission: {:?}", netuid, alpha_out_emission); + log::debug!("{:?} - alpha_out_emission: {:?}", netuid, alpha_out_emission); + // Return result. (tao_in_emission.to_num::(), alpha_in_emission.to_num::(), alpha_out_emission.to_num::()) } + pub fn get_root_divs_in_alpha( netuid: u16, alpha_out_emission: I96F32 ) -> I96F32 { // Get total TAO on root. let total_root_tao: I96F32 = I96F32::from_num( SubnetTAO::::get( 0 ) ); @@ -170,7 +170,6 @@ impl Pallet { let (tao_in_emission, alpha_in_emission, alpha_out_emission):( u64, u64, u64 ) = Self::get_dynamic_tao_emission( *netuid, subnet_emission, - block_emission.to_num::(), alpha_block_emission ); diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 2cf1e49c9..58328e612 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1530,5 +1530,42 @@ mod dispatches { hotkey, ) } + + /// ---- The implementation for the extrinsic unstake_all: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. + /// + /// # Args: + /// * `origin` - (::Origin): + /// - The signature of the caller's coldkey. + /// + /// * `hotkey` (T::AccountId): + /// - The associated hotkey account. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * `NotRegistered`: + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * `NonAssociatedColdKey`: + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * `NotEnoughStakeToWithdraw`: + /// - Thrown if there is not enough stake on the hotkey to withdraw this amount. + /// + /// * `TxRateLimitExceeded`: + /// - Thrown if key has hit transaction rate limit + #[pallet::call_index(83)] + #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + pub fn unstake_all_alpha( + origin: OriginFor, + hotkey: T::AccountId, + ) -> DispatchResult { + Self::do_unstake_all_alpha( + origin, + hotkey, + ) + } } } diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 147b0dd61..b688e9852 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -153,4 +153,78 @@ impl Pallet { // 5. Done and ok. Ok(()) } + + + /// ---- The implementation for the extrinsic unstake_all: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. + /// + /// # Args: + /// * 'origin': (RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * 'NotRegistered': + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * 'NonAssociatedColdKey': + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * 'NotEnoughStakeToWithdraw': + /// - Thrown if there is not enough stake on the hotkey to withdraw this amount. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + pub fn do_unstake_all_alpha( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + ) -> dispatch::DispatchResult { + + // 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_unstake_all( origin:{:?} hotkey:{:?} )", + coldkey, + hotkey + ); + + // 2. Ensure that the hotkey account exists this is only possible through registration. + ensure!( Self::hotkey_account_exists(&hotkey), Error::::HotKeyAccountNotExists ); + + // 3. Get all netuids. + let netuids: Vec = Self::get_all_subnet_netuids(); + log::debug!("All subnet netuids: {:?}", netuids); + + // 4. Iterate through all subnets and remove stake. + let mut total_tao_unstaked: u64 = 0; + for netuid in netuids.iter() { + // If not Root network. + if netuid != Self::get_root_netuid() { + // Ensure that the hotkey has enough stake to withdraw. + let alpha_unstaked = Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid); + if alpha_unstaked > 0 { + // Swap the alpha to tao and update counters for this subnet. + let tao_unstaked: u64 = Self::unstake_from_subnet(&hotkey, &coldkey, *netuid, alpha_unstaked); + + // Increment total + total_tao_unstaked += tao_unstaked; + + // If the stake is below the minimum, we clear the nomination from storage. + Self::clear_small_nomination_if_required(&hotkey, &coldkey, *netuid); + } + } + } + + // Stake into root. + Self::stake_into_subnet( &hotkey, &coldkey, Self::get_root_netuid(), total_tao_unstaked ) + + // 5. Done and ok. + Ok(()) + } } diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 85dcb909a..759b43f00 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -14,20 +14,38 @@ fn close(value: u64, target: u64, eps: u64) { ) } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_zero_price_get_zero_tao_in --exact --show-output --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_various_values --exact --show-output --nocapture #[test] -fn test_dynamic_function_zero_price_get_zero_tao_in() { +fn test_dynamic_function_various_values() { new_test_ext(1).execute_with(|| { - let netuid = 1; - let tao_block_emission: u64 = 1_000_000_000; - let alpha_block_emission: u64 = 1_000_000_000; - add_network(netuid, 110, 100); - let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( - netuid, tao_block_emission, tao_block_emission, alpha_block_emission - ); - assert_eq!( tao_in, 0 ); // tao emission drops to price which is zero given no reserves. - assert_eq!( alpha_in, alpha_block_emission ); - assert_eq!( alpha_out, alpha_block_emission ); + let price_values: [f64; 9] = [0.001, 0.1, 0.5, 1.0, 2.0, 10.0, 100.0, 200.0, 1000.0]; + let tao_in_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ]; + let alpha_emission_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ]; + + for &price in price_values.iter() { + for &tao_in in tao_in_values.iter() { + for &alpha_emission in alpha_emission_values.iter() { + // Set the price. + SubnetTAO::::insert(1, (price * 1_000_000_000.0) as u64); + SubnetAlphaIn::::insert(1, 1_000_000_000); + + + println!("price: {}, tao_in: {}, alpha_emission: {}", price, tao_in, alpha_emission); + let (tao_in_emission, alpha_in_emission, alpha_out_emission) = SubtensorModule::get_dynamic_tao_emission( 1, tao_in, alpha_emission); + + println!("tao_in_emission: {}, alpha_in_emission: {}, alpha_out_emission: {}", tao_in_emission, alpha_in_emission, alpha_out_emission); + + assert!(tao_in_emission <= tao_in as u64, "tao_in_emission is greater than tao_in"); + assert!(alpha_in_emission <= alpha_emission as u64, "alpha_in_emission is greater than alpha_emission"); + assert!(alpha_out_emission <= 2 * alpha_emission as u64, "alpha_out_emission is greater than 2 * alpha_emission"); + assert!((alpha_in_emission + alpha_out_emission) < 2 * alpha_emission as u64, "Sum of alpha_in_emission and alpha_out_emission is not equal to 2 * alpha_emission"); + close( alpha_in_emission + alpha_out_emission, 2 * alpha_emission, 10 ); + if alpha_in_emission > 0 || tao_in_emission > 0 { + assert!((tao_in_emission as f64 / alpha_in_emission as f64 - price).abs() < 1e-6, "Ratio of tao_in_emission to alpha_in_emission is not equal to price"); + } + } + } + } }); } @@ -43,7 +61,7 @@ fn test_dynamic_function_price_equal_emission() { SubnetAlphaIn::::insert( netuid, 1_000_000_000); add_network(netuid, 110, 100); let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( - netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + netuid, tao_subnet_emission, alpha_block_emission ); assert_eq!( tao_in, tao_subnet_emission ); // at price == tao_in == tao_subnet_emission let expected_alpha_in: u64 = (alpha_block_emission * tao_subnet_emission) / tao_block_emission; @@ -66,7 +84,7 @@ fn test_dynamic_function_alpha_price_greater_than_tao_in() { SubnetAlphaIn::::insert( netuid, 1_000_000_000); add_network(netuid, 110, 100); let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( - netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + netuid, tao_subnet_emission, alpha_block_emission ); assert_eq!( tao_in, tao_subnet_emission ); // tao_in should be equal to tao_subnet_emission close(alpha_in, tao_subnet_emission/2, 10 ); @@ -84,7 +102,7 @@ fn test_dynamic_function_zero_tao_block_emission() { let alpha_block_emission: u64 = 1_000_000_000; add_network(netuid, 110, 100); let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( - netuid, tao_subnet_emission, tao_block_emission, alpha_block_emission + netuid, tao_subnet_emission, alpha_block_emission ); assert_eq!( tao_in, 0 ); // tao_in should be zero due to zero tao_block_emission assert_eq!( alpha_in, alpha_block_emission ); @@ -92,6 +110,28 @@ fn test_dynamic_function_zero_tao_block_emission() { }); } +// Test when alpha price is greater than tao_in_proportion +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_at_alpha_halving --exact --show-output --nocapture +#[test] +fn test_dynamic_function_at_alpha_halving() { + new_test_ext(1).execute_with(|| { + let netuid = 1; + let tao_subnet_emission: u64 = 500_000_000; + let tao_block_emission: u64 = 1_000_000_000; + let alpha_block_emission: u64 = 500_000_000; // Half normal. + SubnetTAO::::insert( netuid, 2_000_000_000); // Higher alpha reserves increases price. + SubnetAlphaIn::::insert( netuid, 1_000_000_000); + add_network(netuid, 110, 100); + let (tao_in, alpha_in, alpha_out): (u64, u64, u64) = SubtensorModule::get_dynamic_tao_emission( + netuid, tao_subnet_emission, alpha_block_emission + ); + assert_eq!( tao_in, tao_subnet_emission / 2 ); // tao_in should be equal to tao_subnet_emission + close(alpha_in, tao_in/2, 10 ); + // close(alpha_out, 2 * alpha_block_emission - alpha_block_emission/2, 10 ); + }); +} + + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_flow --exact --show-output From 68f47c721f2c90da9bce817aba595f00e00771e1 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 13:08:27 -0500 Subject: [PATCH 3/7] fix --- pallets/subtensor/src/macros/dispatches.rs | 2 +- pallets/subtensor/src/staking/remove_stake.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 58328e612..52a576bc3 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1556,7 +1556,7 @@ mod dispatches { /// /// * `TxRateLimitExceeded`: /// - Thrown if key has hit transaction rate limit - #[pallet::call_index(83)] + #[pallet::call_index(84)] #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] pub fn unstake_all_alpha( origin: OriginFor, diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index b688e9852..7783a4ebe 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -205,7 +205,7 @@ impl Pallet { let mut total_tao_unstaked: u64 = 0; for netuid in netuids.iter() { // If not Root network. - if netuid != Self::get_root_netuid() { + if *netuid != Self::get_root_netuid() { // Ensure that the hotkey has enough stake to withdraw. let alpha_unstaked = Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid); if alpha_unstaked > 0 { @@ -222,7 +222,7 @@ impl Pallet { } // Stake into root. - Self::stake_into_subnet( &hotkey, &coldkey, Self::get_root_netuid(), total_tao_unstaked ) + Self::stake_into_subnet( &hotkey, &coldkey, Self::get_root_netuid(), total_tao_unstaked ); // 5. Done and ok. Ok(()) From c61186a96fe02aed91100de85195d4180028f301 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 13:25:26 -0500 Subject: [PATCH 4/7] fix dynamic function --- pallets/subtensor/src/coinbase/run_coinbase.rs | 2 +- pallets/subtensor/src/tests/coinbase.rs | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 6d25c3754..43c1a901d 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -46,7 +46,7 @@ impl Pallet { } // Avoid rounding errors. - if tao_in_emission < I96F32::from_num(1){ + if tao_in_emission < I96F32::from_num(1) || alpha_in_emission < I96F32::from_num(1) { alpha_in_emission = I96F32::from_num(0); tao_in_emission = I96F32::from_num(0); } diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 759b43f00..9a0fe4ff6 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -29,19 +29,16 @@ fn test_dynamic_function_various_values() { SubnetTAO::::insert(1, (price * 1_000_000_000.0) as u64); SubnetAlphaIn::::insert(1, 1_000_000_000); - println!("price: {}, tao_in: {}, alpha_emission: {}", price, tao_in, alpha_emission); let (tao_in_emission, alpha_in_emission, alpha_out_emission) = SubtensorModule::get_dynamic_tao_emission( 1, tao_in, alpha_emission); - println!("tao_in_emission: {}, alpha_in_emission: {}, alpha_out_emission: {}", tao_in_emission, alpha_in_emission, alpha_out_emission); - assert!(tao_in_emission <= tao_in as u64, "tao_in_emission is greater than tao_in"); assert!(alpha_in_emission <= alpha_emission as u64, "alpha_in_emission is greater than alpha_emission"); assert!(alpha_out_emission <= 2 * alpha_emission as u64, "alpha_out_emission is greater than 2 * alpha_emission"); - assert!((alpha_in_emission + alpha_out_emission) < 2 * alpha_emission as u64, "Sum of alpha_in_emission and alpha_out_emission is not equal to 2 * alpha_emission"); + assert!((alpha_in_emission + alpha_out_emission) <= 2 * alpha_emission as u64, "Sum of alpha_in_emission and alpha_out_emission is less than or equal to. 2 * alpha_emission"); close( alpha_in_emission + alpha_out_emission, 2 * alpha_emission, 10 ); if alpha_in_emission > 0 || tao_in_emission > 0 { - assert!((tao_in_emission as f64 / alpha_in_emission as f64 - price).abs() < 1e-6, "Ratio of tao_in_emission to alpha_in_emission is not equal to price"); + assert!((tao_in_emission as f64 / alpha_in_emission as f64 - price).abs() < 1e-1, "Ratio of tao_in_emission to alpha_in_emission is not equal to price"); } } } From 8e2019bac614424cd51b6de6293a3e59a687c251 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 13:28:16 -0500 Subject: [PATCH 5/7] tao weight --- pallets/subtensor/src/migrations/migrate_rao.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 703d35d28..6b0afaa22 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -73,7 +73,7 @@ pub fn migrate_rao() -> Weight { SubnetAlphaOut::::insert(netuid, 0); // Set zero subnet alpha out. SubnetMechanism::::insert(netuid, 1); // Convert to dynamic immediately with initialization. Tempo::::insert(netuid, DefaultTempo::::get()); - // Set global weight to 1.8% from the start + // Set global weight to 18% from the start TaoWeight::::insert(netuid, 320_413_933_267_719_290); // Set the token symbol for this subnet using Self instead of Pallet:: TokenSymbol::::insert(netuid, Pallet::::get_symbol_for_subnet(*netuid)); From 32b64f306b0aca4443f03644616a2d7bbf72f1de Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 13:57:40 -0500 Subject: [PATCH 6/7] add term to see divs --- pallets/subtensor/src/coinbase/run_coinbase.rs | 1 + pallets/subtensor/src/lib.rs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 43c1a901d..c30d00373 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -206,6 +206,7 @@ impl Pallet { let pending_alpha_emission: I96F32 = I96F32::from_num( alpha_out_emission ).saturating_sub( root_emission_in_alpha ); // Sell root emission through the pool. let root_emission_in_tao: u64 = Self::swap_alpha_for_tao( *netuid, root_emission_in_alpha.to_num::() ); + SubnetAlphaEmissionSell::::insert( *netuid, root_emission_in_alpha.to_num::() ); // Accumulate root divs for subnet. PendingRootDivs::::mutate( *netuid, |total| { *total = total.saturating_add( root_emission_in_tao ); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 831e54192..661b132b6 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -888,6 +888,9 @@ pub mod pallet { #[pallet::storage] // --- DMAP ( netuid ) --> tao_in_emission | Returns the amount of tao emitted into this subent on the last block. pub type SubnetTaoInEmission = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultZeroU64>; + #[pallet::storage] // --- DMAP ( netuid ) --> alpha_sell_per_block | Alpha sold per block. + pub type SubnetAlphaEmissionSell = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultZeroU64>; #[pallet::storage] // --- DMAP ( netuid ) --> alpha_supply_in_pool | Returns the amount of alpha in the subnet. pub type SubnetAlphaIn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultZeroU64>; From 125d8a618a65609c55de2d8bee080eca34216c92 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 7 Jan 2025 14:19:47 -0500 Subject: [PATCH 7/7] make tao weight global --- .../subtensor/src/coinbase/run_coinbase.rs | 6 ++--- pallets/subtensor/src/lib.rs | 4 ++-- .../subtensor/src/migrations/migrate_rao.rs | 4 ++-- pallets/subtensor/src/staking/stake_utils.rs | 10 ++++----- pallets/subtensor/src/subnets/subnet.rs | 3 --- pallets/subtensor/src/tests/weights.rs | 22 ------------------- 6 files changed, 12 insertions(+), 37 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index c30d00373..ce1b6b8e7 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -71,7 +71,7 @@ impl Pallet { // Get total ALPHA on subnet. let total_alpha_issuance: I96F32 = I96F32::from_num(Self::get_alpha_issuance( netuid )); // Get tao_weight - let tao_weight: I96F32 = total_root_tao.saturating_mul( Self::get_tao_weight( netuid ) ); + let tao_weight: I96F32 = total_root_tao.saturating_mul( Self::get_tao_weight() ); // Get root proportional dividends. let root_proportion: I96F32 = tao_weight.checked_div( tao_weight.saturating_add( total_alpha_issuance ) ).unwrap_or( I96F32::from_num( 0.0 ) ); // Get root proportion of alpha_out dividends. @@ -293,7 +293,7 @@ impl Pallet { // 7.6.3.3: Get the local alpha and root alpha. let hotkey_tao: I96F32 = I96F32::from_num( Self::get_stake_for_hotkey_on_subnet( &hotkey, Self::get_root_netuid() ) ); - let hotkey_tao_as_alpha: I96F32 = hotkey_tao.saturating_mul( Self::get_tao_weight(netuid) ); + let hotkey_tao_as_alpha: I96F32 = hotkey_tao.saturating_mul( Self::get_tao_weight() ); let hotkey_alpha = I96F32::from_num(Self::get_stake_for_hotkey_on_subnet( &hotkey, netuid )); log::debug!("Hotkey tao for hotkey {:?} on root netuid: {:?}, hotkey tao as alpha: {:?}, hotkey alpha: {:?}", hotkey, hotkey_tao, hotkey_tao_as_alpha, hotkey_alpha); @@ -381,7 +381,7 @@ impl Pallet { let mut contributions: Vec<(T::AccountId, I96F32)> = Vec::new(); // Get the weights for root and alpha stakes in emission distribution - let tao_weight: I96F32 = Self::get_tao_weight(netuid); + let tao_weight: I96F32 = Self::get_tao_weight(); // Calculate total root and alpha (subnet-specific) stakes from all parents for (proportion, parent) in Self::get_parents(hotkey, netuid) { diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 661b132b6..1cf9f9390 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -737,8 +737,8 @@ pub mod pallet { /// Eventually, Bittensor should migrate to using Holds afterwhich time we will not require this /// separate accounting. #[pallet::storage] - /// --- MAP ( netuid ) --> Global weight - pub type TaoWeight = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultTaoWeight>; + /// --- ITEM --> Global weight + pub type TaoWeight = StorageValue<_, u64, ValueQuery, DefaultTaoWeight>; #[pallet::storage] /// --- ITEM ( default_delegate_take ) pub type MaxDelegateTake = StorageValue<_, u16, ValueQuery, DefaultDelegateTake>; diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 6b0afaa22..e8f53c324 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -55,6 +55,8 @@ pub fn migrate_rao() -> Weight { }); // Convert subnets and give them lock. + // Set global weight to 18% from the start + TaoWeight::::set(320_413_933_267_719_290); for netuid in netuids.iter().clone() { if *netuid == 0 { // Give root a single RAO in pool to avoid any catestrophic division by zero. @@ -73,8 +75,6 @@ pub fn migrate_rao() -> Weight { SubnetAlphaOut::::insert(netuid, 0); // Set zero subnet alpha out. SubnetMechanism::::insert(netuid, 1); // Convert to dynamic immediately with initialization. Tempo::::insert(netuid, DefaultTempo::::get()); - // Set global weight to 18% from the start - TaoWeight::::insert(netuid, 320_413_933_267_719_290); // Set the token symbol for this subnet using Self instead of Pallet:: TokenSymbol::::insert(netuid, Pallet::::get_symbol_for_subnet(*netuid)); diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index d1eb43213..88496fefe 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -54,9 +54,9 @@ impl Pallet { /// /// # Note /// This function uses saturating division to prevent potential overflow errors. - pub fn get_tao_weight(netuid: u16) -> I96F32 { + pub fn get_tao_weight() -> I96F32 { // Step 1: Fetch the global weight from storage - let stored_weight = TaoWeight::::get(netuid); + let stored_weight = TaoWeight::::get(); // Step 2: Convert the u64 weight to I96F32 let weight_fixed = I96F32::from_num(stored_weight); @@ -82,9 +82,9 @@ impl Pallet { /// # Note /// The weight is stored as a raw u64 value. To get the normalized weight between 0 and 1, /// use the `get_tao_weight()` function. - pub fn set_tao_weight(weight: u64, netuid: u16) { + pub fn set_tao_weight(weight: u64) { // Update the TaoWeight storage with the new weight value - TaoWeight::::insert(netuid, weight); + TaoWeight::::set(weight); } /// Calculates the weighted combination of alpha and global tao for hotkeys on a subnet. @@ -113,7 +113,7 @@ impl Pallet { // Step 5: Combine alpha and root tao stakes. // Retrieve the global global weight. - let tao_weight: I64F64 = I64F64::from_num(Self::get_tao_weight(netuid)); + let tao_weight: I64F64 = I64F64::from_num(Self::get_tao_weight()); // Calculate the weighted average of alpha and global tao stakes for each neuron. let total_stake: Vec = alpha_stake .iter() diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index c6095a80c..e08aa825c 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -337,9 +337,6 @@ impl Pallet { BurnRegistrationsThisInterval::::get(netuid), ); } - if !TaoWeight::::contains_key(netuid) { - TaoWeight::::insert(netuid, DefaultTaoWeight::::get()); - } } } diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index baa71ddd5..9b4adde6b 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -59,28 +59,6 @@ fn test_set_weights_dispatch_info_ok() { assert_eq!(dispatch_info.pays_fee, Pays::No); }); } -#[test] -fn test_set_rootweights_dispatch_info_ok() { - new_test_ext(0).execute_with(|| { - let dests = vec![1, 1]; - let weights = vec![1, 1]; - let netuid: u16 = 1; - let version_key: u64 = 0; - let hotkey: U256 = U256::from(1); // Add the hotkey field - let call = RuntimeCall::SubtensorModule(SubtensorCall::set_tao_weights { - netuid, - dests, - weights, - version_key, - hotkey, // Include the hotkey field - }); - let dispatch_info = call.get_dispatch_info(); - - assert_eq!(dispatch_info.class, DispatchClass::Normal); - assert_eq!(dispatch_info.pays_fee, Pays::No); - }); -} - #[test] fn test_set_rootweights_validate() { // Testing the signed extension validate function