From b28ea8b94aeaf16fb820c2574be8f2b383aeeefb Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 6 Nov 2024 22:39:01 -0500 Subject: [PATCH] respect chk for set weights min stake filter (#935) * respect chk for set weights min stake filter * use for test func * respect chk in set weights call also * add tests back * fix weights min stake tests also --- pallets/subtensor/src/lib.rs | 20 +-- pallets/subtensor/src/subnets/uids.rs | 2 +- pallets/subtensor/src/subnets/weights.rs | 4 +- pallets/subtensor/tests/children.rs | 191 +++++++++++++++++++++++ pallets/subtensor/tests/weights.rs | 6 +- 5 files changed, 207 insertions(+), 16 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d93253cfa..958ef3480 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1299,7 +1299,7 @@ pub mod pallet { /// Returns the transaction priority for setting weights. pub fn get_priority_set_weights(hotkey: &T::AccountId, netuid: u16) -> u64 { if let Ok(uid) = Self::get_uid_for_net_and_hotkey(netuid, hotkey) { - let _stake = Self::get_total_stake_for_hotkey(hotkey); + let _stake = Self::get_stake_for_hotkey_on_subnet(hotkey, netuid); let current_block_number: u64 = Self::get_current_block_as_u64(); let default_priority: u64 = current_block_number.saturating_sub(Self::get_last_update_for_uid(netuid, uid)); @@ -1309,9 +1309,9 @@ pub mod pallet { } /// Is the caller allowed to set weights - pub fn check_weights_min_stake(hotkey: &T::AccountId) -> bool { + pub fn check_weights_min_stake(hotkey: &T::AccountId, netuid: u16) -> bool { // Blacklist weights transactions for low stake peers. - Self::get_total_stake_for_hotkey(hotkey) >= Self::get_weights_min_stake() + Self::get_stake_for_hotkey_on_subnet(hotkey, netuid) >= Self::get_weights_min_stake() } /// Helper function to check if register is allowed @@ -1404,8 +1404,8 @@ where Pallet::::get_priority_set_weights(who, netuid) } - pub fn check_weights_min_stake(who: &T::AccountId) -> bool { - Pallet::::check_weights_min_stake(who) + pub fn check_weights_min_stake(who: &T::AccountId, netuid: u16) -> bool { + Pallet::::check_weights_min_stake(who, netuid) } } @@ -1443,7 +1443,7 @@ where ) -> TransactionValidity { match call.is_sub_type() { Some(Call::commit_weights { netuid, .. }) => { - if Self::check_weights_min_stake(who) { + if Self::check_weights_min_stake(who, *netuid) { let priority: u64 = Self::get_priority_set_weights(who, *netuid); Ok(ValidTransaction { priority, @@ -1455,7 +1455,7 @@ where } } Some(Call::reveal_weights { netuid, .. }) => { - if Self::check_weights_min_stake(who) { + if Self::check_weights_min_stake(who, *netuid) { let priority: u64 = Self::get_priority_set_weights(who, *netuid); Ok(ValidTransaction { priority, @@ -1467,7 +1467,7 @@ where } } Some(Call::batch_reveal_weights { netuid, .. }) => { - if Self::check_weights_min_stake(who) { + if Self::check_weights_min_stake(who, *netuid) { let priority: u64 = Self::get_priority_set_weights(who, *netuid); Ok(ValidTransaction { priority, @@ -1479,7 +1479,7 @@ where } } Some(Call::set_weights { netuid, .. }) => { - if Self::check_weights_min_stake(who) { + if Self::check_weights_min_stake(who, *netuid) { let priority: u64 = Self::get_priority_set_weights(who, *netuid); Ok(ValidTransaction { priority, @@ -1491,7 +1491,7 @@ where } } Some(Call::set_root_weights { netuid, hotkey, .. }) => { - if Self::check_weights_min_stake(hotkey) { + if Self::check_weights_min_stake(hotkey, *netuid) { let priority: u64 = Self::get_priority_set_weights(hotkey, *netuid); Ok(ValidTransaction { priority, diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index 2a5ceedb4..11f59602d 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -120,7 +120,7 @@ impl Pallet { /// pub fn get_stake_for_uid_and_subnetwork(netuid: u16, neuron_uid: u16) -> u64 { if let Ok(hotkey) = Self::get_hotkey_for_net_and_uid(netuid, neuron_uid) { - Self::get_total_stake_for_hotkey(&hotkey) + Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid) } else { 0 } diff --git a/pallets/subtensor/src/subnets/weights.rs b/pallets/subtensor/src/subnets/weights.rs index 87042f456..c511bceae 100644 --- a/pallets/subtensor/src/subnets/weights.rs +++ b/pallets/subtensor/src/subnets/weights.rs @@ -525,9 +525,9 @@ impl Pallet { Error::::HotKeyNotRegisteredInSubNet ); - // --- 6. Check to see if the hotkey has enought stake to set weights. + // --- 6. 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::check_weights_min_stake(&hotkey, netuid), Error::::NotEnoughStakeToSetWeights ); diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 2b99030ab..0182888c0 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -3237,3 +3237,194 @@ fn test_rank_trust_incentive_calculation_with_parent_child() { }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --test children -- test_childkey_set_weights_single_parent --exact --nocapture +#[test] +fn test_childkey_set_weights_single_parent() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // Define hotkeys + let parent: U256 = U256::from(1); + let child: U256 = U256::from(2); + let weight_setter: U256 = U256::from(3); + + // Define coldkeys with more readable names + let coldkey_parent: U256 = U256::from(100); + let coldkey_child: U256 = U256::from(101); + let coldkey_weight_setter: U256 = U256::from(102); + + let stake_to_give_child = 109_999; + + // Register parent with minimal stake and child with high stake + SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 1); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child, stake_to_give_child + 10); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_weight_setter, 1_000_000); + + // Add neurons for parent, child and weight_setter + register_ok_neuron(netuid, parent, coldkey_parent, 1); + register_ok_neuron(netuid, child, coldkey_child, 1); + register_ok_neuron(netuid, weight_setter, coldkey_weight_setter, 1); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey_parent, + &parent, + stake_to_give_child, + ); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey_weight_setter, + &weight_setter, + 1_000_000, + ); + + 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)] + )); + step_block(7200 + 1); + // Set weights on the child using the weight_setter account + let origin = RuntimeOrigin::signed(weight_setter); + let uids: Vec = vec![1]; // Only set weight for the child (UID 1) + let values: Vec = vec![u16::MAX]; // Use maximum value for u16 + let version_key = SubtensorModule::get_weights_version_key(netuid); + assert_ok!(SubtensorModule::set_weights( + origin, + netuid, + uids.clone(), + values.clone(), + version_key + )); + + // Set the min stake very high + SubtensorModule::set_weights_min_stake(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() + ); + + // Check the child cannot set weights + assert_noop!( + SubtensorModule::set_weights( + RuntimeOrigin::signed(child), + netuid, + uids.clone(), + values.clone(), + version_key + ), + Error::::NotEnoughStakeToSetWeights + ); + + 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); + + // Check if the stake for the child is above + assert!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid) + >= SubtensorModule::get_weights_min_stake() + ); + + // Check the child can set weights + assert_ok!(SubtensorModule::set_weights( + RuntimeOrigin::signed(child), + netuid, + uids, + values, + version_key + )); + + assert!(SubtensorModule::check_weights_min_stake(&child, netuid)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --test children -- test_set_weights_no_parent --exact --nocapture +#[test] +fn test_set_weights_no_parent() { + // Verify that a regular key without a parent delegation is effected by the minimum stake requirements + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + let hotkey: U256 = U256::from(2); + let spare_hk: U256 = U256::from(3); + + let coldkey: U256 = U256::from(101); + let spare_ck = U256::from(102); + + let stake_to_give_child = 109_999; + + SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake_to_give_child + 10); + + // Is registered + register_ok_neuron(netuid, hotkey, coldkey, 1); + // Register a spare key + register_ok_neuron(netuid, spare_hk, spare_ck, 1); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey, + &hotkey, + stake_to_give_child, + ); + + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + + // Has stake and no parent + step_block(7200 + 1); + + let uids: Vec = vec![1]; // Set weights on the other hotkey + let values: Vec = vec![u16::MAX]; // Use maximum value for u16 + 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); + + // Check the key has less stake than required + assert!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid) + < SubtensorModule::get_weights_min_stake() + ); + + // Check the hotkey cannot set weights + assert_noop!( + SubtensorModule::set_weights( + RuntimeOrigin::signed(hotkey), + netuid, + uids.clone(), + values.clone(), + version_key + ), + Error::::NotEnoughStakeToSetWeights + ); + + 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); + + // Check if the stake for the hotkey is above + assert!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid) + >= SubtensorModule::get_weights_min_stake() + ); + + // Check the hotkey can set weights + assert_ok!(SubtensorModule::set_weights( + RuntimeOrigin::signed(hotkey), + netuid, + uids, + values, + version_key + )); + + assert!(SubtensorModule::check_weights_min_stake(&hotkey, netuid)); + }); +} diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 7dbeba288..573e5d351 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -481,11 +481,11 @@ fn test_set_weights_min_stake_failed() { // Check the signed extension function. assert_eq!(SubtensorModule::get_weights_min_stake(), 20_000_000_000_000); - assert!(!SubtensorModule::check_weights_min_stake(&hotkey)); + 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)); + assert!(!SubtensorModule::check_weights_min_stake(&hotkey, netuid)); SubtensorModule::increase_stake_on_hotkey_account(&hotkey, 20_000_000_000_000); - assert!(SubtensorModule::check_weights_min_stake(&hotkey)); + 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);