diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 475a2cb8f5..59fb73a3c6 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -885,9 +885,9 @@ pub mod pallet { /// The extrinsic will call the Subtensor pallet to set the weights min stake. #[pallet::call_index(42)] #[pallet::weight((0, DispatchClass::Operational, Pays::No))] - pub fn sudo_set_weights_min_stake(origin: OriginFor, min_stake: u64) -> DispatchResult { + pub fn sudo_set_stake_threshold(origin: OriginFor, min_stake: u64) -> DispatchResult { ensure_root(origin)?; - pallet_subtensor::Pallet::::set_weights_min_stake(min_stake); + pallet_subtensor::Pallet::::set_stake_threshold(min_stake); Ok(()) } diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 1d2e6bc450..f6bdd0bc19 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -682,23 +682,23 @@ fn test_sudo_set_max_allowed_validators() { } #[test] -fn test_sudo_set_weights_min_stake() { +fn test_sudo_set_stake_threshold() { new_test_ext().execute_with(|| { let to_be_set: u64 = 10; - let init_value: u64 = SubtensorModule::get_weights_min_stake(); + let init_value: u64 = SubtensorModule::get_stake_threshold(); assert_eq!( - AdminUtils::sudo_set_weights_min_stake( + AdminUtils::sudo_set_stake_threshold( <::RuntimeOrigin>::signed(U256::from(1)), to_be_set ), Err(DispatchError::BadOrigin) ); - assert_eq!(SubtensorModule::get_weights_min_stake(), init_value); - assert_ok!(AdminUtils::sudo_set_weights_min_stake( + assert_eq!(SubtensorModule::get_stake_threshold(), init_value); + assert_ok!(AdminUtils::sudo_set_stake_threshold( <::RuntimeOrigin>::root(), to_be_set )); - assert_eq!(SubtensorModule::get_weights_min_stake(), to_be_set); + assert_eq!(SubtensorModule::get_stake_threshold(), to_be_set); }); } diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 42f5615f54..3db36441b3 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -784,7 +784,7 @@ impl Pallet { // Check to see if the hotkey has enough stake to set weights. ensure!( - Self::get_total_stake_for_hotkey(&hotkey) >= Self::get_weights_min_stake(), + Self::get_total_stake_for_hotkey(&hotkey) >= Self::get_stake_threshold(), Error::::NotEnoughStakeToSetWeights ); diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 1b35279328..04574733a5 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -166,6 +166,9 @@ impl Pallet { ); log::debug!("Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", hotkey, *netuid, mining_emission, validator_emission); } + + // 4.5 Apply pending childkeys of this subnet for the next epoch + Self::do_set_pending_children(*netuid); } else { // No epoch, increase blocks since last step and continue Self::set_blocks_since_last_step( diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 9b0bf67c0d..2f92fd60e7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -311,6 +311,11 @@ pub mod pallet { vec![] } #[pallet::type_value] + /// Default pending childkeys + pub fn DefaultPendingChildkeys() -> (Vec<(u64, T::AccountId)>, u64) { + (vec![], 0) + } + #[pallet::type_value] /// Default account linkage pub fn DefaultProportion() -> u64 { 0 @@ -576,7 +581,7 @@ pub mod pallet { } #[pallet::type_value] /// Default minimum stake for weights. - pub fn DefaultWeightsMinStake() -> u64 { + pub fn DefaultStakeThreshold() -> u64 { 0 } #[pallet::type_value] @@ -677,6 +682,18 @@ pub mod pallet { T::InitialColdkeySwapScheduleDuration::get() } + #[pallet::type_value] + /// Default value for applying pending items (e.g. childkeys). + pub fn DefaultPendingCooldown() -> u64 { + 7200 + } + + #[pallet::type_value] + /// Default minimum stake for setting childkeys. + pub fn DefaultChildkeysMinStake() -> u64 { + 1_000_000_000_000 + } + #[pallet::storage] pub type ColdkeySwapScheduleDuration = StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; @@ -824,6 +841,18 @@ pub mod pallet { DefaultStakeDelta, >; #[pallet::storage] + /// DMAP ( netuid, parent ) --> (Vec<(proportion,child)>, cool_down_block) + pub type PendingChildKeys = StorageDoubleMap< + _, + Identity, + u16, + Blake2_128Concat, + T::AccountId, + (Vec<(u64, T::AccountId)>, u64), + ValueQuery, + DefaultPendingChildkeys, + >; + #[pallet::storage] /// DMAP ( parent, netuid ) --> Vec<(proportion,child)> pub type ChildKeys = StorageDoubleMap< _, @@ -1270,7 +1299,7 @@ pub mod pallet { StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] /// ITEM( weights_min_stake ) - pub type WeightsMinStake = StorageValue<_, u64, ValueQuery, DefaultWeightsMinStake>; + pub type StakeThreshold = StorageValue<_, u64, ValueQuery, DefaultStakeThreshold>; #[pallet::storage] /// --- MAP (netuid, who) --> VecDeque<(hash, commit_block, first_reveal_block, last_reveal_block)> | Stores a queue of commits for an account on a given netuid. pub type WeightCommits = StorageDoubleMap< @@ -1342,7 +1371,7 @@ pub mod pallet { /// Is the caller allowed to set weights pub fn check_weights_min_stake(hotkey: &T::AccountId, netuid: u16) -> bool { // Blacklist weights transactions for low stake peers. - Self::get_stake_for_hotkey_on_subnet(hotkey, netuid) >= Self::get_weights_min_stake() + Self::get_stake_for_hotkey_on_subnet(hotkey, netuid) >= Self::get_stake_threshold() } /// Helper function to check if register is allowed diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 04a998e169..82e6d4e2ee 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1197,7 +1197,7 @@ mod dispatches { netuid: u16, children: Vec<(u64, T::AccountId)>, ) -> DispatchResultWithPostInfo { - Self::do_set_children(origin, hotkey, netuid, children)?; + Self::do_schedule_children(origin, hotkey, netuid, children)?; Ok(().into()) } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 11f8d81bab..755f86406d 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -35,6 +35,8 @@ mod errors { /// The caller is requesting to set weights but the caller has less than minimum stake /// required to set weights (less than WeightsMinStake). NotEnoughStakeToSetWeights, + /// The parent hotkey doesn't have enough own stake to set childkeys. + NotEnoughStakeToSetChildkeys, /// The caller is requesting adding more stake than there exists in the coldkey account. /// See: "[add_stake()]" NotEnoughBalanceToStake, diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index b403f39f56..23d4b11b73 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -102,7 +102,7 @@ mod events { /// setting the RAO recycled for registration. RAORecycledForRegistrationSet(u16, u64), /// min stake is set for validators to set weights. - WeightsMinStake(u64), + StakeThresholdSet(u64), /// setting the minimum required stake amount for senate registration. SenateRequiredStakePercentSet(u64), /// setting the adjustment alpha on a subnet. @@ -179,6 +179,8 @@ mod events { /// The account ID of the coldkey coldkey: T::AccountId, }, + /// Setting of children of a hotkey have been scheduled + SetChildrenScheduled(T::AccountId, u16, u64, Vec<(u64, T::AccountId)>), /// The children of a hotkey have been set SetChildren(T::AccountId, u16, Vec<(u64, T::AccountId)>), /// The hotkey emission tempo has been set diff --git a/pallets/subtensor/src/migrations/migrate_stake_threshold.rs b/pallets/subtensor/src/migrations/migrate_stake_threshold.rs new file mode 100644 index 0000000000..b70b1ac948 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_stake_threshold.rs @@ -0,0 +1,48 @@ +use super::*; +use crate::HasMigrationRun; +use frame_support::pallet_prelude::ValueQuery; +use frame_support::storage_alias; +use frame_support::{traits::Get, weights::Weight}; +use scale_info::prelude::string::String; + +/// Module containing deprecated storage format for WeightsMinStake +pub mod deprecated_weights_min_stake { + use super::*; + + #[storage_alias] + pub(super) type WeightsMinStake = StorageValue, u64, ValueQuery>; +} + +pub fn migrate_stake_threshold() -> Weight { + let migration_name = b"migrate_stake_threshold".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + let min_stake = deprecated_weights_min_stake::WeightsMinStake::::get(); + StakeThreshold::::set(min_stake); + deprecated_weights_min_stake::WeightsMinStake::::kill(); + + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully.", + String::from_utf8_lossy(&migration_name) + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 6341ca0c85..0925aa6a0d 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -9,6 +9,7 @@ pub mod migrate_fix_total_coldkey_stake; pub mod migrate_init_total_issuance; pub mod migrate_populate_owned_hotkeys; pub mod migrate_populate_staking_hotkeys; +pub mod migrate_stake_threshold; pub mod migrate_to_v1_separate_emission; pub mod migrate_to_v2_fixed_total_stake; pub mod migrate_total_issuance; diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 587583f5ed..71d3c31087 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -90,6 +90,13 @@ impl Pallet { let new_stake = Self::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey); Self::clear_small_nomination_if_required(&hotkey, &coldkey, new_stake); + // Check if stake lowered below MinStake and remove Pending children if it did + if Self::get_total_stake_for_hotkey(&hotkey) < StakeThreshold::::get() { + Self::get_all_subnet_netuids().iter().for_each(|netuid| { + PendingChildKeys::::remove(netuid, &hotkey); + }) + } + // Set last block for rate limiting let block: u64 = Self::get_current_block_as_u64(); Self::set_last_tx_block(&coldkey, block); diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 9029d58ca2..ce9362b227 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -1,26 +1,25 @@ use super::*; +use sp_core::Get; impl Pallet { /// ---- The implementation for the extrinsic do_set_child_singular: Sets a single child. - /// /// This function allows a coldkey to set children keys. /// - /// # Arguments: - /// * `origin` (::RuntimeOrigin): - /// - The signature of the calling coldkey. Setting a hotkey child can only be done by the coldkey. - /// - /// * `hotkey` (T::AccountId): - /// - The hotkey which will be assigned the child. - /// - /// * `netuid` (u16): - /// - The u16 network identifier where the child keys will exist. - /// - /// * `children` Vec[(u64, T::AccountId)]: - /// - A list of children with their proportions. + /// Adds a childkey vector to the PendingChildKeys map and performs a few checks: + /// **Signature Verification**: Ensures that the caller has signed the transaction, verifying the coldkey. + /// **Root Network Check**: Ensures that the delegation is not on the root network, as child hotkeys are not valid on the root. + /// **Network Existence Check**: Ensures that the specified network exists. + /// **Ownership Verification**: Ensures that the coldkey owns the hotkey. + /// **Hotkey Account Existence Check**: Ensures that the hotkey account already exists. + /// **Child count**: Only allow to add up to 5 children per parent + /// **Child-Hotkey Distinction**: Ensures that the child is not the same as the hotkey. + /// **Minimum stake**: Ensures that the parent key has at least the minimum stake. + /// **Proportion check**: Ensure that the sum of the proportions does not exceed u64::MAX. + /// **Duplicate check**: Ensure there are no duplicates in the list of children. /// /// # Events: - /// * `ChildrenAdded`: - /// - On successfully registering children to a hotkey. + /// * `SetChildrenScheduled`: + /// - If all checks pass and setting the childkeys is scheduled. /// /// # Errors: /// * `SubNetworkDoesNotExist`: @@ -31,24 +30,16 @@ impl Pallet { /// - The coldkey does not own the hotkey or the child is the same as the hotkey. /// * `HotKeyAccountNotExists`: /// - The hotkey account does not exist. + /// * `TooManyChildren`: + /// - Too many children in request /// - /// # Detailed Explanation of Checks: - /// 1. **Signature Verification**: Ensures that the caller has signed the transaction, verifying the coldkey. - /// 2. **Root Network Check**: Ensures that the delegation is not on the root network, as child hotkeys are not valid on the root. - /// 3. **Network Existence Check**: Ensures that the specified network exists. - /// 4. **Ownership Verification**: Ensures that the coldkey owns the hotkey. - /// 5. **Hotkey Account Existence Check**: Ensures that the hotkey account already exists. - /// 6. **Child-Hotkey Distinction**: Ensures that the child is not the same as the hotkey. - /// 7. **Old Children Cleanup**: Removes the hotkey from the parent list of its old children. - /// 8. **New Children Assignment**: Assigns the new child to the hotkey and updates the parent list for the new child. - /// - pub fn do_set_children( + pub fn do_schedule_children( origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: u16, children: Vec<(u64, T::AccountId)>, ) -> DispatchResult { - // --- 1. Check that the caller has signed the transaction. (the coldkey of the pairing) + // Check that the caller has signed the transaction. (the coldkey of the pairing) let coldkey = ensure_signed(origin)?; log::trace!( "do_set_children( coldkey:{:?} hotkey:{:?} netuid:{:?} children:{:?} )", @@ -77,38 +68,38 @@ impl Pallet { current_block, ); - // --- 2. Check that this delegation is not on the root network. Child hotkeys are not valid on root. + // Check that this delegation is not on the root network. Child hotkeys are not valid on root. ensure!( netuid != Self::get_root_netuid(), Error::::RegistrationNotPermittedOnRootSubnet ); - // --- 3. Check that the network we are trying to create the child on exists. + // Check that the network we are trying to create the child on exists. ensure!( Self::if_subnet_exist(netuid), Error::::SubNetworkDoesNotExist ); - // --- 4. Check that the coldkey owns the hotkey. + // Check that the coldkey owns the hotkey. ensure!( Self::coldkey_owns_hotkey(&coldkey, &hotkey), Error::::NonAssociatedColdKey ); - // --- 4.1. Ensure that the number of children does not exceed 5. + // Ensure that the number of children does not exceed 5. ensure!(children.len() <= 5, Error::::TooManyChildren); - // --- 5. Ensure that each child is not the hotkey. + // Ensure that each child is not the hotkey. for (_, child_i) in &children { ensure!(child_i != &hotkey, Error::::InvalidChild); } - // --- 5.1. Ensure that the sum of the proportions does not exceed u64::MAX. + // Ensure that the sum of the proportions does not exceed u64::MAX. let _total_proportion: u64 = children .iter() .try_fold(0u64, |acc, &(proportion, _)| acc.checked_add(proportion)) .ok_or(Error::::ProportionOverflow)?; - // --- 5.2. Ensure there are no duplicates in the list of children. + // Ensure there are no duplicates in the list of children. let mut unique_children = Vec::new(); for (_, child_i) in &children { ensure!( @@ -118,55 +109,131 @@ impl Pallet { unique_children.push(child_i.clone()); } - // --- 6. Erase myself from old children's parents. - let old_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(hotkey.clone(), netuid); - - // --- 6.0. Iterate over all my old children and remove myself from their parent's map. - for (_, old_child_i) in old_children.clone().iter() { - // --- 6.1. Get the old child's parents on this network. - let my_old_child_parents: Vec<(u64, T::AccountId)> = - ParentKeys::::get(old_child_i.clone(), netuid); - - // --- 6.2. Filter my hotkey from my old children's parents list. - let filtered_parents: Vec<(u64, T::AccountId)> = my_old_child_parents - .into_iter() - .filter(|(_, parent)| *parent != hotkey) - .collect(); - - // --- 6.3. Update the parent list in storage - ParentKeys::::insert(old_child_i, netuid, filtered_parents); - } - - // --- 7.1. Insert my new children + proportion list into the map. - ChildKeys::::insert(hotkey.clone(), netuid, children.clone()); - - // --- 7.2. Update the parents list for my new children. - for (proportion, new_child_i) in children.clone().iter() { - // --- 8.2.1. Get the child's parents on this network. - let mut new_child_previous_parents: Vec<(u64, T::AccountId)> = - ParentKeys::::get(new_child_i.clone(), netuid); + // Check that the parent key has at least the minimum own stake + // (checking with check_weights_min_stake wouldn't work because it considers + // grandparent stake in this case) + ensure!( + Self::get_total_stake_for_hotkey(&hotkey) >= StakeThreshold::::get(), + Error::::NotEnoughStakeToSetChildkeys + ); - // --- 7.2.2. Append my hotkey and proportion to my new child's parents list. - // NOTE: There are no duplicates possible because I previously removed my self from my old children. - new_child_previous_parents.push((*proportion, hotkey.clone())); + // Calculate cool-down block + let cooldown_block = + Self::get_current_block_as_u64().saturating_add(DefaultPendingCooldown::::get()); - // --- 7.2.3. Update the parents list in storage. - ParentKeys::::insert(new_child_i.clone(), netuid, new_child_previous_parents); - } + // Insert or update PendingChildKeys + PendingChildKeys::::insert(netuid, hotkey.clone(), (children.clone(), cooldown_block)); // --- 8. Log and return. log::trace!( - "SetChildren( netuid:{:?}, hotkey:{:?}, children:{:?} )", + "SetChildrenScheduled( netuid:{:?}, cooldown_block:{:?}, hotkey:{:?}, children:{:?} )", + cooldown_block, hotkey, netuid, children.clone() ); - Self::deposit_event(Event::SetChildren(hotkey.clone(), netuid, children.clone())); + Self::deposit_event(Event::SetChildrenScheduled( + hotkey.clone(), + netuid, + cooldown_block, + children.clone(), + )); // Ok and return. Ok(()) } + /// This function executes setting children keys when called during hotkey draining. + /// + /// * `netuid` (u16): + /// - The u16 network identifier where the child keys will exist. + /// + /// # Events: + /// * `SetChildren`: + /// - On successfully registering children to a hotkey. + /// + /// # Errors: + /// * `SubNetworkDoesNotExist`: + /// - Attempting to register to a non-existent network. + /// * `RegistrationNotPermittedOnRootSubnet`: + /// - Attempting to register a child on the root network. + /// * `NonAssociatedColdKey`: + /// - The coldkey does not own the hotkey or the child is the same as the hotkey. + /// * `HotKeyAccountNotExists`: + /// - The hotkey account does not exist. + /// + /// # Detailed Explanation of actions: + /// 1. **Old Children Cleanup**: Removes the hotkey from the parent list of its old children. + /// 2. **New Children Assignment**: Assigns the new child to the hotkey and updates the parent list for the new child. + /// + pub fn do_set_pending_children(netuid: u16) { + let current_block = Self::get_current_block_as_u64(); + + // Iterate over all pending children of this subnet and set as needed + PendingChildKeys::::iter_prefix(netuid).for_each( + |(hotkey, (children, cool_down_block))| { + if cool_down_block < current_block { + // Erase myself from old children's parents. + let old_children: Vec<(u64, T::AccountId)> = + ChildKeys::::get(hotkey.clone(), netuid); + + // Iterate over all my old children and remove myself from their parent's map. + for (_, old_child_i) in old_children.clone().iter() { + // Get the old child's parents on this network. + let my_old_child_parents: Vec<(u64, T::AccountId)> = + ParentKeys::::get(old_child_i.clone(), netuid); + + // Filter my hotkey from my old children's parents list. + let filtered_parents: Vec<(u64, T::AccountId)> = my_old_child_parents + .into_iter() + .filter(|(_, parent)| *parent != hotkey) + .collect(); + + // Update the parent list in storage + ParentKeys::::insert(old_child_i, netuid, filtered_parents); + } + + // Insert my new children + proportion list into the map. + ChildKeys::::insert(hotkey.clone(), netuid, children.clone()); + + // Update the parents list for my new children. + for (proportion, new_child_i) in children.clone().iter() { + // Get the child's parents on this network. + let mut new_child_previous_parents: Vec<(u64, T::AccountId)> = + ParentKeys::::get(new_child_i.clone(), netuid); + + // Append my hotkey and proportion to my new child's parents list. + // NOTE: There are no duplicates possible because I previously removed my self from my old children. + new_child_previous_parents.push((*proportion, hotkey.clone())); + + // Update the parents list in storage. + ParentKeys::::insert( + new_child_i.clone(), + netuid, + new_child_previous_parents, + ); + } + + // Log and emit event. + log::trace!( + "SetChildren( netuid:{:?}, hotkey:{:?}, children:{:?} )", + hotkey, + netuid, + children.clone() + ); + Self::deposit_event(Event::SetChildren( + hotkey.clone(), + netuid, + children.clone(), + )); + + // Remove pending children + PendingChildKeys::::remove(netuid, hotkey); + } + }, + ); + } + /* Retrieves the list of children for a given hotkey and network. /// /// # Arguments diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index 3d74ef378f..dd2c12a805 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -21,12 +21,7 @@ fn test_do_set_child_singular_success() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, child)]); // Verify child assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -47,7 +42,7 @@ fn test_do_set_child_singular_network_does_not_exist() { // Attempt to set child assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -74,7 +69,7 @@ fn test_do_set_child_singular_invalid_child() { // Attempt to set child as the same hotkey assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -104,7 +99,7 @@ fn test_do_set_child_singular_non_associated_coldkey() { // Attempt to set child assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -131,7 +126,7 @@ fn test_do_set_child_singular_root_network() { // Attempt to set child assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -165,22 +160,12 @@ fn test_do_set_child_singular_old_children_cleanup() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set old child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, old_child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, old_child)]); step_rate_limit(&TransactionType::SetChildren, netuid); // Set new child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, new_child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, new_child)]); // Verify old child is removed let old_child_parents = SubtensorModule::get_parents(&old_child, netuid); @@ -213,12 +198,7 @@ fn test_do_set_child_singular_new_children_assignment() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, child)]); // Verify child assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -251,12 +231,7 @@ fn test_do_set_child_singular_proportion_edge_cases() { // Set child with minimum proportion let min_proportion: u64 = 0; - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(min_proportion, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(min_proportion, child)]); // Verify child assignment with minimum proportion let children = SubtensorModule::get_children(&hotkey, netuid); @@ -266,12 +241,7 @@ fn test_do_set_child_singular_proportion_edge_cases() { // Set child with maximum proportion let max_proportion: u64 = u64::MAX; - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(max_proportion, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(max_proportion, child)]); // Verify child assignment with maximum proportion let children = SubtensorModule::get_children(&hotkey, netuid); @@ -303,22 +273,12 @@ fn test_do_set_child_singular_multiple_children() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set first child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion1, child1)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion1, child1)]); step_rate_limit(&TransactionType::SetChildren, netuid); // Set second child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion2, child2)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion1, child2)]); // Verify children assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -348,7 +308,7 @@ fn test_add_singular_child() { let hotkey = U256::from(1); let coldkey = U256::from(2); assert_eq!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -359,7 +319,7 @@ fn test_add_singular_child() { add_network(netuid, 0, 0); step_rate_limit(&TransactionType::SetChildren, netuid); assert_eq!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -370,7 +330,7 @@ fn test_add_singular_child() { SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); step_rate_limit(&TransactionType::SetChildren, netuid); assert_eq!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -380,12 +340,8 @@ fn test_add_singular_child() { ); let child = U256::from(3); step_rate_limit(&TransactionType::SetChildren, netuid); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(u64::MAX, child)] - )); + + mock_set_children(&coldkey, &hotkey, netuid, &[(u64::MAX, child)]); }) } @@ -410,6 +366,9 @@ fn test_get_stake_for_hotkey_on_subnet() { register_ok_neuron(netuid, parent, coldkey1, 0); register_ok_neuron(netuid, child, coldkey2, 0); + // Set parent-child relationship with 100% stake allocation + mock_set_children(&coldkey1, &parent, netuid, &[(u64::MAX, child)]); + // Stake 1000 to parent from coldkey1 SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &parent, 1000); // Stake 1000 to parent from coldkey2 @@ -419,14 +378,6 @@ fn test_get_stake_for_hotkey_on_subnet() { // Stake 1000 to child from coldkey2 SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey2, &child, 1000); - // Set parent-child relationship with 100% stake allocation - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey1), - parent, - netuid, - vec![(u64::MAX, child)] - )); - let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); @@ -465,12 +416,7 @@ fn test_do_revoke_child_singular_success() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, child)]); // Verify child assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -479,12 +425,7 @@ fn test_do_revoke_child_singular_success() { step_rate_limit(&TransactionType::SetChildren, netuid); // Revoke child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify child removal let children = SubtensorModule::get_children(&hotkey, netuid); @@ -496,13 +437,10 @@ fn test_do_revoke_child_singular_success() { }); } -// 13: Test revoking a child in a non-existent network -// This test verifies that attempting to revoke a child in a non-existent network results in an error: -// - Attempts to revoke a child in a network that doesn't exist -// - Checks that the appropriate error is returned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_child_singular_network_does_not_exist --exact --nocapture +// 13: Test setting empty child vector on a non-existing subnet +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_empty_children_network_does_not_exist --exact --nocapture #[test] -fn test_do_revoke_child_singular_network_does_not_exist() { +fn test_do_set_empty_children_network_does_not_exist() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -510,7 +448,7 @@ fn test_do_revoke_child_singular_network_does_not_exist() { // Attempt to revoke child assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -540,7 +478,7 @@ fn test_do_revoke_child_singular_non_associated_coldkey() { // Attempt to revoke child assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -569,7 +507,7 @@ fn test_do_revoke_child_singular_child_not_associated() { add_network(netuid, 13, 0); // Attempt to revoke child that is not associated assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -586,9 +524,9 @@ fn test_do_revoke_child_singular_child_not_associated() { // - Sets multiple children with different proportions // - Verifies that the children are correctly assigned to the parent // - Checks that the parent is correctly assigned to each child -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_success --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_success --exact --nocapture #[test] -fn test_do_set_children_multiple_success() { +fn test_do_schedule_children_multiple_success() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -603,12 +541,12 @@ fn test_do_set_children_multiple_success() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set multiple children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion1, child1), (proportion2, child2)] - )); + &[(proportion1, child1), (proportion2, child2)], + ); // Verify children assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -627,9 +565,9 @@ fn test_do_set_children_multiple_success() { // This test ensures that attempting to set multiple children in a non-existent network results in an error: // - Attempts to set children in a network that doesn't exist // - Verifies that the appropriate error is returned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_network_does_not_exist --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_network_does_not_exist --exact --nocapture #[test] -fn test_do_set_children_multiple_network_does_not_exist() { +fn test_do_schedule_children_multiple_network_does_not_exist() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -639,7 +577,7 @@ fn test_do_set_children_multiple_network_does_not_exist() { // Attempt to set children assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -655,9 +593,9 @@ fn test_do_set_children_multiple_network_does_not_exist() { // - Sets up a network and registers a hotkey // - Attempts to set a child that is the same as the parent hotkey // - Checks that the appropriate error is returned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_invalid_child --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_invalid_child --exact --nocapture #[test] -fn test_do_set_children_multiple_invalid_child() { +fn test_do_schedule_children_multiple_invalid_child() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -670,7 +608,7 @@ fn test_do_set_children_multiple_invalid_child() { // Attempt to set child as the same hotkey assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -686,9 +624,9 @@ fn test_do_set_children_multiple_invalid_child() { // - Sets up a network with a hotkey registered to a different coldkey // - Attempts to set children using an unassociated coldkey // - Verifies that the appropriate error is returned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_non_associated_coldkey --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_non_associated_coldkey --exact --nocapture #[test] -fn test_do_set_children_multiple_non_associated_coldkey() { +fn test_do_schedule_children_multiple_non_associated_coldkey() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -702,7 +640,7 @@ fn test_do_set_children_multiple_non_associated_coldkey() { // Attempt to set children assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -718,9 +656,9 @@ fn test_do_set_children_multiple_non_associated_coldkey() { // - Sets up the root network // - Attempts to set children in the root network // - Checks that the appropriate error is returned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_root_network --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_root_network --exact --nocapture #[test] -fn test_do_set_children_multiple_root_network() { +fn test_do_schedule_children_multiple_root_network() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -733,7 +671,7 @@ fn test_do_set_children_multiple_root_network() { // Attempt to set children assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -751,9 +689,9 @@ fn test_do_set_children_multiple_root_network() { // - Replaces it with multiple new children // - Verifies that the old child is no longer associated // - Confirms the new children are correctly assigned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_old_children_cleanup --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_old_children_cleanup --exact --nocapture #[test] -fn test_do_set_children_multiple_old_children_cleanup() { +fn test_do_schedule_children_multiple_old_children_cleanup() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -768,22 +706,17 @@ fn test_do_set_children_multiple_old_children_cleanup() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set old child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, old_child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, old_child)]); step_rate_limit(&TransactionType::SetChildren, netuid); // Set new children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion, new_child1), (proportion, new_child2)] - )); + &[(proportion, new_child1), (proportion, new_child2)], + ); // Verify old child is removed let old_child_parents = SubtensorModule::get_parents(&old_child, netuid); @@ -803,9 +736,9 @@ fn test_do_set_children_multiple_old_children_cleanup() { // - Sets up a network and registers a hotkey // - Sets two children with minimum and maximum proportions respectively // - Verifies that the children are correctly assigned with their respective proportions -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_proportion_edge_cases --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_proportion_edge_cases --exact --nocapture #[test] -fn test_do_set_children_multiple_proportion_edge_cases() { +fn test_do_schedule_children_multiple_proportion_edge_cases() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -820,12 +753,12 @@ fn test_do_set_children_multiple_proportion_edge_cases() { // Set children with minimum and maximum proportions let min_proportion: u64 = 0; let max_proportion: u64 = u64::MAX; - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(min_proportion, child1), (max_proportion, child2)] - )); + &[(min_proportion, child1), (max_proportion, child2)], + ); // Verify children assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -843,9 +776,9 @@ fn test_do_set_children_multiple_proportion_edge_cases() { // - Overwrites with new children // - Verifies that the final children assignment is correct // - Checks that old children are properly removed and new ones are correctly assigned -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_overwrite_existing --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_overwrite_existing --exact --nocapture #[test] -fn test_do_set_children_multiple_overwrite_existing() { +fn test_do_schedule_children_multiple_overwrite_existing() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -860,22 +793,22 @@ fn test_do_set_children_multiple_overwrite_existing() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set initial children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion, child1), (proportion, child2)] - )); + &[(proportion, child1), (proportion, child2)], + ); step_rate_limit(&TransactionType::SetChildren, netuid); // Overwrite with new children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion * 2, child2), (proportion * 3, child3)] - )); + &[(proportion * 2, child2), (proportion * 3, child3)], + ); // Verify final children assignment let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1157,9 +1090,9 @@ fn test_multiple_networks_childkey_take() { // - Adds a network and registers a hotkey // - Sets an empty children list for the hotkey // - Verifies that the children assignment is empty -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_empty_list --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_schedule_children_multiple_empty_list --exact --nocapture #[test] -fn test_do_set_children_multiple_empty_list() { +fn test_do_schedule_children_multiple_empty_list() { new_test_ext(1).execute_with(|| { let coldkey = U256::from(1); let hotkey = U256::from(2); @@ -1170,12 +1103,7 @@ fn test_do_set_children_multiple_empty_list() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set empty children list - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify children assignment is empty let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1207,22 +1135,17 @@ fn test_do_revoke_children_multiple_success() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set multiple children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion1, child1), (proportion2, child2)] - )); + &[(proportion1, child1), (proportion2, child2)], + ); step_rate_limit(&TransactionType::SetChildren, netuid); // Revoke multiple children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify children removal let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1252,7 +1175,7 @@ fn test_do_revoke_children_multiple_network_does_not_exist() { let netuid: u16 = 999; // Non-existent network // Attempt to revoke children assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -1284,7 +1207,7 @@ fn test_do_revoke_children_multiple_non_associated_coldkey() { // Attempt to revoke children assert_err!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -1319,26 +1242,26 @@ fn test_do_revoke_children_multiple_partial_revocation() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set multiple children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![ + &[ (proportion, child1), (proportion, child2), - (proportion, child3) - ] - )); + (proportion, child3), + ], + ); step_rate_limit(&TransactionType::SetChildren, netuid); // Revoke only child3 - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion, child1), (proportion, child2)] - )); + &[(proportion, child1), (proportion, child2)], + ); // Verify children removal let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1376,22 +1299,12 @@ fn test_do_revoke_children_multiple_non_existent_children() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set one child - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, child1)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(proportion, child1)]); step_rate_limit(&TransactionType::SetChildren, netuid); // Attempt to revoke existing and non-existent children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify all children are removed let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1421,12 +1334,7 @@ fn test_do_revoke_children_multiple_empty_list() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Attempt to revoke with an empty list - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify no changes in children let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1460,26 +1368,26 @@ fn test_do_revoke_children_multiple_complex_scenario() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set multiple children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![ + &[ (proportion1, child1), (proportion2, child2), - (proportion3, child3) - ] - )); + (proportion3, child3), + ], + ); step_rate_limit(&TransactionType::SetChildren, netuid); // Revoke child2 - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![(proportion1, child1), (proportion3, child3)] - )); + &[(proportion1, child1), (proportion3, child3)], + ); // Verify remaining children let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1492,12 +1400,7 @@ fn test_do_revoke_children_multiple_complex_scenario() { step_rate_limit(&TransactionType::SetChildren, netuid); // Revoke remaining children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[]); // Verify all children are removed let children = SubtensorModule::get_children(&hotkey, netuid); @@ -1669,16 +1572,17 @@ fn test_children_stake_values() { ); // Set multiple children with proportions. - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, + mock_set_children( + &coldkey, + &hotkey, netuid, - vec![ + &[ (proportion1, child1), (proportion2, child2), - (proportion3, child3) - ] - )); + (proportion3, child3), + ], + ); + assert_eq!( SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid), 25_000_000_069_852 @@ -1752,12 +1656,12 @@ fn test_get_parents_chain() { // Set up parent-child relationships for i in 0..num_keys - 1 { - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkeys[i], + mock_set_children( + &coldkey, + &hotkeys[i], netuid, - vec![(proportion, hotkeys[i + 1])] - )); + &[(proportion, hotkeys[i + 1])], + ); log::info!( "Set parent-child relationship: parent={}, child={}, proportion={}", hotkeys[i], @@ -1811,12 +1715,13 @@ fn test_get_parents_chain() { netuid ); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - new_parent, + mock_set_children( + &coldkey, + &new_parent, netuid, - vec![(proportion / 2, last_hotkey)] - )); + &[(proportion / 2, last_hotkey)], + ); + log::info!( "Set additional parent-child relationship: parent={}, child={}, proportion={}", new_parent, @@ -1895,12 +1800,7 @@ fn test_childkey_single_parent_emission() { SubtensorModule::set_weights_set_rate_limit(netuid, 0); // Set parent-child relationship - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent), - parent, - netuid, - vec![(u64::MAX, child)] - )); + mock_set_children(&coldkey_parent, &parent, netuid, &[(u64::MAX, child)]); step_block(7200 + 1); // Set weights on the child using the weight_setter account let origin = RuntimeOrigin::signed(weight_setter); @@ -2036,18 +1936,8 @@ fn test_childkey_multiple_parents_emission() { step_block(2); // Set parent-child relationships - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent1), - parent1, - netuid, - vec![(100_000, child)] - )); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent2), - parent2, - netuid, - vec![(75_000, child)] - )); + mock_set_children(&coldkey_parent1, &parent1, netuid, &[(100_000, child)]); + mock_set_children(&coldkey_parent2, &parent2, netuid, &[(75_000, child)]); // Set weights let uids: Vec = vec![0, 1, 2]; @@ -2205,19 +2095,10 @@ fn test_parent_child_chain_emission() { // Set parent-child relationships // A -> B (50% of A's stake) - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_a), - hotkey_a, - netuid, - vec![(u64::MAX / 2, hotkey_b)] - )); + mock_set_children(&coldkey_a, &hotkey_a, netuid, &[(u64::MAX / 2, hotkey_b)]); + // B -> C (50% of B's stake) - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_b), - hotkey_b, - netuid, - vec![(u64::MAX / 2, hotkey_c)] - )); + mock_set_children(&coldkey_b, &hotkey_b, netuid, &[(u64::MAX / 2, hotkey_c)]); step_block(2); @@ -2356,13 +2237,7 @@ fn test_dynamic_parent_child_relationships() { SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_child1, &child1, 50_000); SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_child2, &child2, 30_000); - // Set initial parent-child relationship - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent), - parent, - netuid, - vec![(u64::MAX / 2, child1)] - )); + mock_set_children(&coldkey_parent, &parent, netuid, &[(u64::MAX / 2, child1)]); step_block(2); @@ -2397,15 +2272,10 @@ fn test_dynamic_parent_child_relationships() { // Step blocks to allow for emission distribution step_block(11); + step_rate_limit(&TransactionType::SetChildren, netuid); // Change parent-child relationships - step_rate_limit(&TransactionType::SetChildren, netuid); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent), - parent, - netuid, - vec![(u64::MAX / 4, child1), (u64::MAX / 3, child2)] - )); + mock_set_children(&coldkey_parent, &parent, netuid, &[(u64::MAX / 4, child1), (u64::MAX / 3, child2)]); // Run second epoch let hotkey_emission: Vec<(U256, u64, u64)> = SubtensorModule::epoch(netuid, hardcoded_emission); @@ -2597,12 +2467,7 @@ fn test_get_stake_for_hotkey_on_subnet_single_parent_child() { SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent, 1000); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - vec![(u64::MAX, child)] - )); + mock_set_children(&coldkey, &parent, netuid, &[(u64::MAX, child)]); assert_eq!( SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid), @@ -2639,18 +2504,8 @@ fn test_get_stake_for_hotkey_on_subnet_multiple_parents_single_child() { SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent1, 1000); SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent2, 2000); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent1, - netuid, - vec![(u64::MAX / 2, child)] - )); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent2, - netuid, - vec![(u64::MAX / 2, child)] - )); + mock_set_children(&coldkey, &parent1, netuid, &[(u64::MAX / 2, child)]); + mock_set_children(&coldkey, &parent2, netuid, &[(u64::MAX / 2, child)]); assert_eq!( SubtensorModule::get_stake_for_hotkey_on_subnet(&parent1, netuid), @@ -2691,12 +2546,12 @@ fn test_get_stake_for_hotkey_on_subnet_single_parent_multiple_children() { let total_stake = 3000; SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent, total_stake); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, + mock_set_children( + &coldkey, + &parent, netuid, - vec![(u64::MAX / 3, child1), (u64::MAX / 3, child2)] - )); + &[(u64::MAX / 3, child1), (u64::MAX / 3, child2)], + ); let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child1_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); @@ -2752,12 +2607,12 @@ fn test_get_stake_for_hotkey_on_subnet_edge_cases() { ); // Test with 0% and 100% stake allocation - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, + mock_set_children( + &coldkey, + &parent, netuid, - vec![(0, child1), (u64::MAX, child2)] - )); + &[(0, child1), (u64::MAX, child2)], + ); let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child1_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); @@ -2840,12 +2695,12 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { ); // Step 1: Set children for parent - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent), - parent, + mock_set_children( + &coldkey_parent, + &parent, netuid, - vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)] - )); + &[(u64::MAX / 2, child1), (u64::MAX / 2, child2)], + ); log::info!("After setting parent's children:"); log::info!( @@ -2877,12 +2732,7 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { assert_eq!(child2_stake_1, 499, "Child2 should have 499 stake"); // Step 2: Set children for child1 - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_child1), - child1, - netuid, - vec![(u64::MAX, grandchild)] - )); + mock_set_children(&coldkey_child1, &child1, netuid, &[(u64::MAX, grandchild)]); log::info!("After setting child1's children:"); log::info!( @@ -3149,12 +2999,7 @@ fn test_rank_trust_incentive_calculation_with_parent_child() { log::debug!("Initial child dividends: {:?}", initial_child_dividends); // Parent sets the child with 100% of its weight - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(parent_coldkey), - parent_hotkey, - netuid, - vec![(u64::MAX, child_hotkey)] - )); + mock_set_children(&parent_coldkey, &parent_hotkey, netuid, &[(u64::MAX, child_hotkey)]); // Child now sets weights as a validator assert_ok!(SubtensorModule::set_weights( @@ -3307,12 +3152,8 @@ fn test_childkey_set_weights_single_parent() { SubtensorModule::set_weights_set_rate_limit(netuid, 0); // Set parent-child relationship - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey_parent), - parent, - netuid, - vec![(u64::MAX, child)] - )); + mock_set_children(&coldkey_parent, &parent, netuid, &[(u64::MAX, child)]); + step_block(7200 + 1); // Set weights on the child using the weight_setter account let origin = RuntimeOrigin::signed(weight_setter); @@ -3328,12 +3169,12 @@ fn test_childkey_set_weights_single_parent() { )); // Set the min stake very high - SubtensorModule::set_weights_min_stake(stake_to_give_child * 5); + SubtensorModule::set_stake_threshold(stake_to_give_child * 5); // Check the child has less stake than required assert!( SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid) - < SubtensorModule::get_weights_min_stake() + < SubtensorModule::get_stake_threshold() ); // Check the child cannot set weights @@ -3351,12 +3192,12 @@ fn test_childkey_set_weights_single_parent() { assert!(!SubtensorModule::check_weights_min_stake(&child, netuid)); // Set a minimum stake to set weights - SubtensorModule::set_weights_min_stake(stake_to_give_child - 5); + SubtensorModule::set_stake_threshold(stake_to_give_child - 5); // Check if the stake for the child is above assert!( SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid) - >= SubtensorModule::get_weights_min_stake() + >= SubtensorModule::get_stake_threshold() ); // Check the child can set weights @@ -3411,12 +3252,12 @@ fn test_set_weights_no_parent() { let version_key = SubtensorModule::get_weights_version_key(netuid); // Set the min stake very high - SubtensorModule::set_weights_min_stake(stake_to_give_child * 5); + SubtensorModule::set_stake_threshold(stake_to_give_child * 5); // Check the key has less stake than required assert!( SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid) - < SubtensorModule::get_weights_min_stake() + < SubtensorModule::get_stake_threshold() ); // Check the hotkey cannot set weights @@ -3434,12 +3275,12 @@ fn test_set_weights_no_parent() { assert!(!SubtensorModule::check_weights_min_stake(&hotkey, netuid)); // Set a minimum stake to set weights - SubtensorModule::set_weights_min_stake(stake_to_give_child - 5); + SubtensorModule::set_stake_threshold(stake_to_give_child - 5); // Check if the stake for the hotkey is above assert!( SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid) - >= SubtensorModule::get_weights_min_stake() + >= SubtensorModule::get_stake_threshold() ); // Check the hotkey can set weights @@ -3475,6 +3316,10 @@ fn test_childkey_take_drain() { add_network(netuid, subnet_tempo, 0); register_ok_neuron(netuid, child, coldkey, 0); register_ok_neuron(netuid, parent, coldkey, 1); + + // Set children + mock_set_children(&coldkey, &parent, netuid, &[(proportion, child)]); + SubtensorModule::add_balance_to_coldkey_account( &coldkey, stake + ExistentialDeposit::get(), @@ -3528,12 +3373,6 @@ fn test_childkey_take_drain() { child, stake )); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - vec![(proportion, child)] - )); // Make all stakes viable crate::StakeDeltaSinceLastEmissionDrain::::set(parent, coldkey, -1); crate::StakeDeltaSinceLastEmissionDrain::::set(child, nominator, -1); @@ -3628,6 +3467,9 @@ fn test_childkey_take_drain_validator_take() { step_block(subnet_tempo); crate::SubnetOwnerCut::::set(0); + // Set children + mock_set_children(&coldkey, &parent, netuid, &[(proportion, child)]); + // Set 20% childkey take let max_take: u16 = 0xFFFF / 5; SubtensorModule::set_max_childkey_take(max_take); @@ -3667,12 +3509,6 @@ fn test_childkey_take_drain_validator_take() { child, stake )); - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - vec![(proportion, child)] - )); // Make all stakes viable crate::StakeDeltaSinceLastEmissionDrain::::set(parent, coldkey, -1); crate::StakeDeltaSinceLastEmissionDrain::::set(child, nominator, -1); @@ -3754,16 +3590,11 @@ fn test_set_children_rate_limit_fail_then_succeed() { register_ok_neuron(netuid, hotkey, coldkey, 0); // First set_children transaction - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(100, child)] - )); + mock_set_children(&coldkey, &hotkey, netuid, &[(100, child)]); // Immediate second transaction should fail due to rate limit assert_noop!( - SubtensorModule::do_set_children( + SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, @@ -3791,15 +3622,127 @@ fn test_set_children_rate_limit_fail_then_succeed() { )); // Try again - assert_ok!(SubtensorModule::do_set_children( + mock_set_children(&coldkey, &hotkey, netuid, &[(100, child2)]); + + // Verify children assignment has changed + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(100, child2)]); + }); +} + +// Test that min stake is enforced for setting children +#[test] +fn test_do_set_child_below_min_stake() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + StakeThreshold::::set(1_000_000_000_000); + + // Attempt to set child + assert_err!( + SubtensorModule::do_schedule_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::NotEnoughStakeToSetChildkeys + ); + }); +} + +// Test that removing stake clears pending childkeys +#[test] +fn test_do_remove_stake_clears_pending_childkeys() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set non-default value for childkey stake threshold + StakeThreshold::::set(1_000_000_000_000); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey, + &hotkey, + StakeThreshold::::get(), + ); + + // Attempt to set child + assert_ok!(SubtensorModule::do_schedule_children( RuntimeOrigin::signed(coldkey), hotkey, netuid, - vec![(100, child2)] + vec![(proportion, child)] )); - // Verify children assignment has changed - let children = SubtensorModule::get_children(&hotkey, netuid); - assert_eq!(children, vec![(100, child2)]); + // Check that pending child exists + let pending_before = PendingChildKeys::::get(netuid, hotkey); + assert!(!pending_before.0.is_empty()); + assert!(pending_before.1 > 0); + + // Remove stake + let _ = SubtensorModule::do_remove_stake( + RuntimeOrigin::signed(coldkey), + hotkey, + 100_000_000_000, + ); + + // Assert that pending child is removed + let pending_after = PendingChildKeys::::get(netuid, hotkey); + assert!(pending_after.0.is_empty()); // zero child vec + assert_eq!(pending_after.1, 0); // zero cooldown block + }); +} + +// Test that pending childkeys do not apply immediately and apply after cooldown period +#[test] +fn test_do_set_child_cooldown_period() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let parent = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, parent, coldkey, 0); + + // Set minimum stake for setting children + let parent_total_stake_original = TotalHotkeyStake::::get(parent); + TotalHotkeyStake::::insert(parent, StakeThreshold::::get()); + + // Schedule parent-child relationship + assert_ok!(SubtensorModule::do_schedule_children( + RuntimeOrigin::signed(coldkey), + parent, + netuid, + vec![(proportion, child)], + )); + + // Ensure the childkeys are not yet applied + let children_before = SubtensorModule::get_children(&parent, netuid); + assert_eq!(children_before, vec![]); + + wait_and_set_pending_children(netuid); + TotalHotkeyStake::::insert(parent, parent_total_stake_original); + + // Verify child assignment + let children_after = SubtensorModule::get_children(&parent, netuid); + assert_eq!(children_after, vec![(proportion, child)]); }); } diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index b9ac2dcfcc..59011bf59a 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -213,7 +213,7 @@ impl CanVote for CanVoteToTriumvirate { } } -use crate::{CollectiveInterface, MemberManagement}; +use crate::{CollectiveInterface, MemberManagement, StakeThreshold, TotalHotkeyStake}; pub struct ManageSenateMembers; impl MemberManagement for ManageSenateMembers { fn add_member(account: &AccountId) -> DispatchResultWithPostInfo { @@ -680,6 +680,31 @@ pub fn is_within_tolerance(actual: u64, expected: u64, tolerance: u64) -> bool { difference <= tolerance } +#[allow(dead_code)] +pub fn wait_and_set_pending_children(netuid: u16) { + let original_block = System::block_number(); + System::set_block_number(System::block_number() + 7300); + SubtensorModule::do_set_pending_children(netuid); + System::set_block_number(original_block); +} + +#[allow(dead_code)] +pub fn mock_set_children(coldkey: &U256, parent: &U256, netuid: u16, child_vec: &[(u64, U256)]) { + // Set minimum stake for setting children + let parent_total_stake_original = TotalHotkeyStake::::get(parent); + TotalHotkeyStake::::insert(parent, StakeThreshold::::get()); + + // Set initial parent-child relationship + assert_ok!(SubtensorModule::do_schedule_children( + RuntimeOrigin::signed(*coldkey), + *parent, + netuid, + child_vec.to_vec() + )); + wait_and_set_pending_children(netuid); + TotalHotkeyStake::::insert(parent, parent_total_stake_original); +} + // Helper function to wait for the rate limit #[allow(dead_code)] pub fn step_rate_limit(transaction_type: &TransactionType, netuid: u16) { diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index f4453a129f..f30d97b92c 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -7,8 +7,7 @@ use frame_system::{Config, RawOrigin}; use super::mock::*; use crate::*; -use sp_core::H256; -use sp_core::U256; +use sp_core::{Get, H256, U256}; use sp_runtime::SaturatedConversion; // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner --exact --nocapture @@ -1250,12 +1249,7 @@ fn test_swap_parent_hotkey_childkey_maps() { SubtensorModule::create_account_if_non_existent(&coldkey, &parent_old); // Set child and verify state maps - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent_old, - netuid, - vec![(u64::MAX, child)] - )); + mock_set_children(&coldkey, &parent_old, netuid, &[(u64::MAX, child)]); assert_eq!( ParentKeys::::get(child, netuid), vec![(u64::MAX, parent_old)] @@ -1299,12 +1293,8 @@ fn test_swap_child_hotkey_childkey_maps() { SubtensorModule::create_account_if_non_existent(&coldkey, &parent); // Set child and verify state maps - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - parent, - netuid, - vec![(u64::MAX, child_old)] - )); + mock_set_children(&coldkey, &parent, netuid, &[(u64::MAX, child_old)]); + assert_eq!( ParentKeys::::get(child_old, netuid), vec![(u64::MAX, parent)] diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index fd959870eb..df12f1e79f 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -110,7 +110,7 @@ fn test_set_rootweights_validate() { let min_stake = 500_000_000_000; // Set the minimum stake - SubtensorModule::set_weights_min_stake(min_stake); + SubtensorModule::set_stake_threshold(min_stake); // Verify stake is less than minimum assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); @@ -210,7 +210,7 @@ fn test_commit_weights_validate() { let min_stake = 500_000_000_000; // Set the minimum stake - SubtensorModule::set_weights_min_stake(min_stake); + SubtensorModule::set_stake_threshold(min_stake); // Verify stake is less than minimum assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); @@ -304,7 +304,7 @@ fn test_set_weights_validate() { let min_stake = 500_000_000_000; // Set the minimum stake - SubtensorModule::set_weights_min_stake(min_stake); + SubtensorModule::set_stake_threshold(min_stake); // Verify stake is less than minimum assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); @@ -369,7 +369,7 @@ fn test_reveal_weights_validate() { let min_stake = 500_000_000_000; // Set the minimum stake - SubtensorModule::set_weights_min_stake(min_stake); + SubtensorModule::set_stake_threshold(min_stake); // Verify stake is less than minimum assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); @@ -479,9 +479,9 @@ fn test_weights_err_no_validator_permit() { }); } -// To execute this test: cargo test --package pallet-subtensor --test weights test_set_weights_min_stake_failed -- --nocapture` +// To execute this test: cargo test --package pallet-subtensor --test weights test_set_stake_threshold_failed -- --nocapture` #[test] -fn test_set_weights_min_stake_failed() { +fn test_set_stake_threshold_failed() { new_test_ext(0).execute_with(|| { let dests = vec![0]; let weights = vec![1]; @@ -492,10 +492,10 @@ fn test_set_weights_min_stake_failed() { add_network(netuid, 0, 0); register_ok_neuron(netuid, hotkey, coldkey, 2143124); - SubtensorModule::set_weights_min_stake(20_000_000_000_000); + SubtensorModule::set_stake_threshold(20_000_000_000_000); // Check the signed extension function. - assert_eq!(SubtensorModule::get_weights_min_stake(), 20_000_000_000_000); + assert_eq!(SubtensorModule::get_stake_threshold(), 20_000_000_000_000); assert!(!SubtensorModule::check_weights_min_stake(&hotkey, netuid)); SubtensorModule::increase_stake_on_hotkey_account(&hotkey, 19_000_000_000_000); assert!(!SubtensorModule::check_weights_min_stake(&hotkey, netuid)); @@ -503,7 +503,7 @@ fn test_set_weights_min_stake_failed() { assert!(SubtensorModule::check_weights_min_stake(&hotkey, netuid)); // Check that it fails at the pallet level. - SubtensorModule::set_weights_min_stake(100_000_000_000_000); + SubtensorModule::set_stake_threshold(100_000_000_000_000); assert_eq!( SubtensorModule::set_weights( RuntimeOrigin::signed(hotkey), diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index e69506507e..472fccd58b 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -144,9 +144,9 @@ impl Pallet { *updated_validator_permit = validator_permit; ValidatorPermit::::insert(netuid, updated_validator_permits); } - pub fn set_weights_min_stake(min_stake: u64) { - WeightsMinStake::::put(min_stake); - Self::deposit_event(Event::WeightsMinStake(min_stake)); + pub fn set_stake_threshold(min_stake: u64) { + StakeThreshold::::put(min_stake); + Self::deposit_event(Event::StakeThresholdSet(min_stake)); } pub fn set_target_stakes_per_interval(target_stakes_per_interval: u64) { TargetStakesPerInterval::::set(target_stakes_per_interval); @@ -213,8 +213,8 @@ impl Pallet { let vec = ValidatorPermit::::get(netuid); vec.get(uid as usize).copied().unwrap_or(false) } - pub fn get_weights_min_stake() -> u64 { - WeightsMinStake::::get() + pub fn get_stake_threshold() -> u64 { + StakeThreshold::::get() } // ============================