diff --git a/pallets/admin-utils/tests/tests.rs b/pallets/admin-utils/tests/tests.rs index c86230cbd..f1842f40c 100644 --- a/pallets/admin-utils/tests/tests.rs +++ b/pallets/admin-utils/tests/tests.rs @@ -2,10 +2,9 @@ use frame_support::assert_ok; use frame_support::sp_runtime::DispatchError; use frame_system::Config; use pallet_admin_utils::Error; +use pallet_subtensor::Error as SubtensorError; use pallet_subtensor::Event; use sp_core::U256; -use pallet_subtensor::Error as SubtensorError; - mod mock; use mock::*; @@ -1181,156 +1180,153 @@ fn test_sudo_set_target_stakes_per_interval() { }); } +#[test] +fn alpha_low_can_only_be_called_by_admin() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX + assert_eq!( + AdminUtils::sudo_set_alpha_low( + <::RuntimeOrigin>::signed(U256::from(1)), + netuid, + to_be_set + ), + Err(DispatchError::BadOrigin) + ); + }); +} - #[test] - fn alpha_low_can_only_be_called_by_admin() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX - assert_eq!( - AdminUtils::sudo_set_alpha_low( - <::RuntimeOrigin>::signed(U256::from(1)), - netuid, - to_be_set - ), - Err(DispatchError::BadOrigin) - ); - }); - } +#[test] +fn sets_alpha_low_valid_value() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX + let init_value = SubtensorModule::get_alpha_low(netuid); + assert_eq!(SubtensorModule::get_alpha_low(netuid), init_value); + assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( + <::RuntimeOrigin>::root(), + netuid, + true, + )); + assert_ok!(AdminUtils::sudo_set_alpha_low( + <::RuntimeOrigin>::root(), + netuid, + to_be_set + )); + assert_eq!(SubtensorModule::get_alpha_low(netuid), to_be_set); + }); +} - #[test] - fn sets_alpha_low_valid_value() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX - let init_value = SubtensorModule::get_alpha_low(netuid); - assert_eq!(SubtensorModule::get_alpha_low(netuid), init_value); - assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( +#[test] +fn alpha_low_fails_if_liquid_alpha_disabled() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX + assert_eq!( + AdminUtils::sudo_set_alpha_low( <::RuntimeOrigin>::root(), netuid, - true, - )); - assert_ok!(AdminUtils::sudo_set_alpha_low( + to_be_set + ), + Err(SubtensorError::::LiquidAlphaDisabled.into()) + ); + }); +} + +#[test] +fn alpha_low_fails_if_alpha_low_too_low() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 0; // Invalid value + assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( + <::RuntimeOrigin>::root(), + netuid, + true, + )); + assert_eq!( + AdminUtils::sudo_set_alpha_low( <::RuntimeOrigin>::root(), netuid, to_be_set - )); - assert_eq!(SubtensorModule::get_alpha_low(netuid), to_be_set); - }); - } + ), + Err(SubtensorError::::AlphaLowTooLow.into()) + ); + }); +} - #[test] - fn alpha_low_fails_if_liquid_alpha_disabled() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 52428; // 0.8 i.e. 0.8 x u16::MAX - assert_eq!( - AdminUtils::sudo_set_alpha_low( - <::RuntimeOrigin>::root(), - netuid, - to_be_set - ), - Err(SubtensorError::::LiquidAlphaDisabled.into()) - ); - }); - } +#[test] +fn alpha_high_can_only_be_called_by_admin() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 60000; // Valid value + assert_eq!( + AdminUtils::sudo_set_alpha_high( + <::RuntimeOrigin>::signed(U256::from(1)), + netuid, + to_be_set + ), + Err(DispatchError::BadOrigin) + ); + }); +} - #[test] - fn alpha_low_fails_if_alpha_low_too_low() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 0; // Invalid value - assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( +#[test] +fn sets_a_valid_value() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 60000; // Valid value + let init_value = SubtensorModule::get_alpha_high(netuid); + assert_eq!(SubtensorModule::get_alpha_high(netuid), init_value); + assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( + <::RuntimeOrigin>::root(), + netuid, + true, + )); + assert_ok!(AdminUtils::sudo_set_alpha_high( + <::RuntimeOrigin>::root(), + netuid, + to_be_set + )); + assert_eq!(SubtensorModule::get_alpha_high(netuid), to_be_set); + }); +} + +#[test] +fn alpha_high_fails_if_liquid_alpha_disabled() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 60000; // Valid value + assert_eq!( + AdminUtils::sudo_set_alpha_high( <::RuntimeOrigin>::root(), netuid, - true, - )); - assert_eq!( - AdminUtils::sudo_set_alpha_low( - <::RuntimeOrigin>::root(), - netuid, - to_be_set - ), - Err(SubtensorError::::AlphaLowTooLow.into()) - ); - }); - } + to_be_set + ), + Err(SubtensorError::::LiquidAlphaDisabled.into()) + ); + }); +} - - #[test] - fn alpha_high_can_only_be_called_by_admin() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 60000; // Valid value - assert_eq!( - AdminUtils::sudo_set_alpha_high( - <::RuntimeOrigin>::signed(U256::from(1)), - netuid, - to_be_set - ), - Err(DispatchError::BadOrigin) - ); - }); - } - - #[test] - fn sets_a_valid_value() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 60000; // Valid value - let init_value = SubtensorModule::get_alpha_high(netuid); - assert_eq!(SubtensorModule::get_alpha_high(netuid), init_value); - assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( - <::RuntimeOrigin>::root(), - netuid, - true, - )); - assert_ok!(AdminUtils::sudo_set_alpha_high( - <::RuntimeOrigin>::root(), - netuid, - to_be_set - )); - assert_eq!(SubtensorModule::get_alpha_high(netuid), to_be_set); - }); - } - - #[test] - fn alpha_high_fails_if_liquid_alpha_disabled() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 60000; // Valid value - assert_eq!( - AdminUtils::sudo_set_alpha_high( - <::RuntimeOrigin>::root(), - netuid, - to_be_set - ), - Err(SubtensorError::::LiquidAlphaDisabled.into()) - ); - }); - } - - #[test] - fn fails_if_alpha_high_too_low() { - new_test_ext().execute_with(|| { - let netuid: u16 = 1; - let to_be_set: u16 = 50000; // Invalid value, less than 52428 - assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( - <::RuntimeOrigin>::root(), - netuid, - true, - )); - assert_eq!( - AdminUtils::sudo_set_alpha_high( - <::RuntimeOrigin>::root(), - netuid, - to_be_set - ), - Err(SubtensorError::::AlphaHighTooLow.into()) - ); - }); - } - +#[test] +fn fails_if_alpha_high_too_low() { + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let to_be_set: u16 = 50000; // Invalid value, less than 52428 + assert_ok!(AdminUtils::sudo_set_liquid_alpha_enabled( + <::RuntimeOrigin>::root(), + netuid, + true, + )); + assert_eq!( + AdminUtils::sudo_set_alpha_high( + <::RuntimeOrigin>::root(), + netuid, + to_be_set + ), + Err(SubtensorError::::AlphaHighTooLow.into()) + ); + }); +} #[test] fn test_sudo_set_liquid_alpha_enabled() { diff --git a/pallets/subtensor/src/epoch.rs b/pallets/subtensor/src/epoch.rs index f7a7792bf..b88799552 100644 --- a/pallets/subtensor/src/epoch.rs +++ b/pallets/subtensor/src/epoch.rs @@ -845,27 +845,18 @@ impl Pallet { // Calculate the slope 'a' of the logistic function. // a = (ln((1 / alpha_high - 1)) - ln((1 / alpha_low - 1))) / (consensus_low - consensus_high) - let a = (safe_ln( - I32F32::from_num(1.0) - .saturating_div(alpha_high) - .saturating_sub(I32F32::from_num(1.0)), - ) - .saturating_sub(safe_ln( - I32F32::from_num(1.0) - .saturating_div(alpha_low) - .saturating_sub(I32F32::from_num(1.0)), - ))) - .saturating_div(consensus_low.saturating_sub(consensus_high)); + let a = + (safe_ln((I32F32::from_num(1.0) / alpha_high).saturating_sub(I32F32::from_num(1.0))) + .saturating_sub(safe_ln( + (I32F32::from_num(1.0) / alpha_low).saturating_sub(I32F32::from_num(1.0)), + ))) + .saturating_div(consensus_low.saturating_sub(consensus_high)); log::trace!("a: {:?}", a); // Calculate the intercept 'b' of the logistic function. // b = ln((1 / alpha_low - 1)) + a * consensus_low - let b = safe_ln( - I32F32::from_num(1.0) - .saturating_div(alpha_low) - .saturating_sub(I32F32::from_num(1.0)), - ) - .saturating_add(a.saturating_mul(consensus_low)); + let b = safe_ln((I32F32::from_num(1.0) / alpha_low).saturating_sub(I32F32::from_num(1.0))) + .saturating_add(a.saturating_mul(consensus_low)); log::trace!("b: {:?}", b); // Return the calculated slope 'a' and intercept 'b'. @@ -1082,9 +1073,12 @@ impl Pallet { // Calculate the 75th percentile (high) and 25th percentile (low) of the consensus values. let consensus_high = quantile(&consensus, 0.75); let consensus_low = quantile(&consensus, 0.25); - + // consensus_low < 0 || + // consensus_high <= consensus_low || + // alpha_low < 0 || + // alpha_high <= alpha_low // Further check if the high and low consensus values meet the required conditions. - if (consensus_high > consensus_low) && consensus_high != 0 && consensus_low != 0 { + if (consensus_high > consensus_low) || consensus_high != 0 || consensus_low < 0 { // if (consensus_high > consensus_low) || consensus_high != 0) || consensus_low != 0 { // if (consensus_high > consensus_low) || consensus_low != 0 { log::trace!("Using Liquid Alpha"); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 70a6f0fdb..711d7c8dd 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -376,7 +376,7 @@ pub mod pallet { /// -- ITEM (switches liquid alpha on) #[pallet::type_value] pub fn DefaultLiquidAlpha() -> bool { - return false; + false } #[pallet::storage] // --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled pub type LiquidAlphaOn = diff --git a/pallets/subtensor/src/math.rs b/pallets/subtensor/src/math.rs index 350724c1d..f6a26f728 100644 --- a/pallets/subtensor/src/math.rs +++ b/pallets/subtensor/src/math.rs @@ -8,7 +8,6 @@ use sp_std::cmp::Ordering; use sp_std::vec; use substrate_fixed::transcendental::{exp, ln}; use substrate_fixed::types::{I32F32, I64F64}; -use crate::alloc::borrow::ToOwned; // TODO: figure out what cfg gate this needs to not be a warning in rustc #[allow(unused)] diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index 87e4dc024..9b96b0955 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -668,7 +668,7 @@ impl Pallet { } pub fn get_alpha_high_32(netuid: u16) -> I32F32 { - I32F32::from_num(AlphaHigh::::get(netuid) as f64 / 1000.0) + I32F32::from_num(AlphaHigh::::get(netuid)) / I32F32::from_num(u16::MAX) } pub fn set_alpha_high(netuid: u16, alpha_high: u16) -> Result<(), DispatchError> { @@ -689,7 +689,7 @@ impl Pallet { } pub fn get_alpha_low_32(netuid: u16) -> I32F32 { - I32F32::from_num(AlphaLow::::get(netuid)) + I32F32::from_num(AlphaLow::::get(netuid)) / I32F32::from_num(u16::MAX) } pub fn set_alpha_low(netuid: u16, alpha_low: u16) -> Result<(), DispatchError> { @@ -697,7 +697,10 @@ impl Pallet { Self::get_liquid_alpha_enabled(netuid), Error::::LiquidAlphaDisabled ); - ensure!(alpha_low > 0 || alpha_low == 52428, Error::::AlphaLowTooLow); + ensure!( + alpha_low > 0 || alpha_low == 52428, + Error::::AlphaLowTooLow + ); AlphaLow::::insert(netuid, alpha_low); Ok(()) diff --git a/pallets/subtensor/tests/epoch.rs b/pallets/subtensor/tests/epoch.rs index 0ca309ce4..1852553d8 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -1407,7 +1407,7 @@ fn test_bonds_with_liquid_alpha() { } let bonds = SubtensorModule::get_bonds(netuid); - assert_eq!(bonds[0][4], 14582); + assert_eq!(bonds[0][4], 2862); assert_eq!(bonds[1][4], 32767); assert_eq!(bonds[2][4], 49151); assert_eq!(bonds[3][4], 65535); @@ -1470,8 +1470,8 @@ fn test_bonds_with_liquid_alpha() { Pruning Scores: [0.0016997808, 0.0151777493, 0.2070524206, 0.2760700488, 0.049998779, 0.1000006103, 0.1499963377, 0.2000042726] */ - assert_eq!(bonds[0][4], 12603); - assert_eq!(bonds[1][4], 28321); + assert_eq!(bonds[0][4], 435); + assert_eq!(bonds[1][4], 4985); assert_eq!(bonds[2][4], 49151); assert_eq!(bonds[3][4], 65535); }); @@ -2507,88 +2507,21 @@ fn test_compute_ema_bonds_with_liquid_alpha_sparse_empty() { ); } -// #[test] -// fn test_compute_ema_bonds_sparse_with_liquid_alpha() { -// new_test_ext(1).execute_with(|| { -// let sparse: bool = true; -// let n: u16 = 8; -// let netuid: u16 = 1; -// let tempo: u16 = u16::MAX - 1; // high tempo to skip automatic epochs in on_initialize, use manual epochs instead -// let max_stake: u64 = 4; -// let stakes: Vec = vec![1, 2, 3, 4, 0, 0, 0, 0]; -// let block_number = System::block_number(); -// add_network(netuid, tempo, 0); -// SubtensorModule::set_max_allowed_uids(netuid, n); -// SubtensorModule::set_max_registrations_per_block(netuid, n); -// SubtensorModule::set_target_registrations_per_interval(netuid, n); -// SubtensorModule::set_weights_set_rate_limit(netuid, 0); -// SubtensorModule::set_min_allowed_weights(netuid, 1); -// SubtensorModule::set_max_weight_limit(netuid, u16::MAX); - -// // Register validators and servers -// for key in 0..n as u64 { -// SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), max_stake); -// let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( -// netuid, -// block_number, -// key * 1_000_000, -// &U256::from(key), -// ); -// assert_ok!(SubtensorModule::register( -// <::RuntimeOrigin>::signed(U256::from(key)), -// netuid, -// block_number, -// nonce, -// work, -// U256::from(key), -// U256::from(key) -// )); -// SubtensorModule::increase_stake_on_coldkey_hotkey_account( -// &U256::from(key), -// &U256::from(key), -// stakes[key as usize], -// ); -// } - -// // Initialize with first epoch -// SubtensorModule::epoch(netuid, 1_000_000_000); -// step_block(1); - -// // Set weights -// for uid in 0..(n / 2) as u16 { -// SubtensorModule::set_validator_permit_for_uid(netuid, uid, true); -// assert_ok!(SubtensorModule::set_weights( -// RuntimeOrigin::signed(U256::from(uid)), -// netuid, -// ((n / 2)..n).collect(), -// vec![u16::MAX / 4, u16::MAX / 2, (u16::MAX / 4) * 3, u16::MAX], -// 0 -// )); -// } - -// // Enable LiquidAlpha -// SubtensorModule::set_liquid_alpha_enabled(netuid, true); -// assert_eq!(SubtensorModule::get_liquid_alpha_enabled(netuid), true); - -// // Continue with additional epochs to mimic the end-to-end test -// // for _ in 0..5 { -// // next_block(); -// // if sparse { -// // SubtensorModule::epoch(netuid, 1_000_000_000); -// // } else { -// // SubtensorModule::epoch_dense(netuid, 1_000_000_000); -// // } -// // } - -// // Fetch the final bonds and validate -// let final_bonds = SubtensorModule::get_bonds(netuid); -// // Example assertions, adjust as needed based on expected LiquidAlpha values -// assert_eq!(final_bonds[0][0], 14582); -// assert_eq!(final_bonds[1][1], 32767); -// assert_eq!(final_bonds[2][2], 49151); -// assert_eq!(final_bonds[3][3], 65535); -// }); -// } +#[test] +fn test_get_alpha_low() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let alpha_low: u16 = 1000; + SubtensorModule::set_liquid_alpha_enabled(netuid, true); + SubtensorModule::set_alpha_low(netuid, alpha_low).unwrap(); + log::info!("alpha_low: {:?}", SubtensorModule::get_alpha_low(netuid)); + assert_eq!(SubtensorModule::get_alpha_low(netuid), alpha_low); + assert_eq!( + SubtensorModule::get_alpha_low_32(netuid), + I32F32::from_num(0.015259022) + ); + }); +} // // Map the retention graph for consensus guarantees with an single epoch on a graph with 512 nodes, of which the first 64 are validators, the graph is split into a major and minor set, each setting specific weight on itself and the complement on the other. // // diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 0356da3af..ee18619e9 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -158,8 +158,8 @@ parameter_types! { pub const InitialSubnetLimit: u16 = 10; // Max 10 subnets. pub const InitialNetworkRateLimit: u64 = 0; pub const InitialTargetStakesPerInterval: u16 = 2; - pub const InitialAlphaHigh: u16 = 900; // Represents 0.9 as per the production default - pub const InitialAlphaLow: u16 = 700; // Represents 0.7 as per the production default + pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default + pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn } diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh index ab06060aa..4e413c6d1 100755 --- a/scripts/test_specific.sh +++ b/scripts/test_specific.sh @@ -1,4 +1,4 @@ pallet="${3:-pallet-subtensor}" features="${4:-pow-faucet}" -RUST_LOG=info cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file +RUST_LOG="pallet_subtensor=trace,info" cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file