diff --git a/pallets/subtensor/src/epoch/math.rs b/pallets/subtensor/src/epoch/math.rs index 6a53cb135b..11930bf26e 100644 --- a/pallets/subtensor/src/epoch/math.rs +++ b/pallets/subtensor/src/epoch/math.rs @@ -246,6 +246,22 @@ pub fn is_topk(vector: &[I32F32], k: usize) -> Vec { result } +// Returns a bool vector where an item is true if the vector item is in topk values and is non-zero. +#[allow(dead_code, clippy::indexing_slicing)] +pub fn is_topk_nonzero(vector: &[I32F32], k: usize) -> Vec { + let n: usize = vector.len(); + let mut result: Vec = vector.iter().map(|&elem| elem != I32F32::from(0)).collect(); + if n < k { + return result; + } + let mut idxs: Vec = (0..n).collect(); + idxs.sort_by_key(|&idx| &vector[idx]); // ascending stable sort + for &idx in idxs.iter().take(n.saturating_sub(k)) { + result[idx] = false; + } + result +} + // Returns a normalized (sum to 1 except 0) copy of the input vector. #[allow(dead_code)] pub fn normalize(x: &[I32F32]) -> Vec { diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index 1b87388b85..c550135123 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -80,10 +80,26 @@ impl Pallet { log::trace!("hotkeys: {:?}", &hotkeys); // Access network stake as normalized vector. - let (mut total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = + let (total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = Self::get_stake_weights_for_network(netuid); - inplace_normalize_64(&mut total_stake); - let stake: Vec = vec_fixed64_to_fixed32(total_stake); + + // Get the minimum stake required. + let min_stake = Self::get_stake_threshold(); + + // Set stake of validators that doesn't meet the staking threshold to 0 as filter. + let mut filtered_stake: Vec = total_stake + .iter() + .map(|&s| { + if fixed64_to_u64(s) < min_stake { + return I64F64::from(0); + } + s + }) + .collect(); + log::debug!("Filtered stake: {:?}", &filtered_stake); + + inplace_normalize_64(&mut filtered_stake); + let stake: Vec = vec_fixed64_to_fixed32(filtered_stake); log::trace!("S: {:?}", &stake); // ======================= @@ -102,7 +118,8 @@ impl Pallet { log::trace!("max_allowed_validators: {:?}", max_allowed_validators); // Get new validator permits. - let new_validator_permits: Vec = is_topk(&stake, max_allowed_validators as usize); + let new_validator_permits: Vec = + is_topk_nonzero(&stake, max_allowed_validators as usize); log::trace!("new_validator_permits: {:?}", new_validator_permits); // ================== @@ -470,10 +487,26 @@ impl Pallet { log::debug!("hotkeys: {:?}", &hotkeys); // Access network stake as normalized vector. - let (mut total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = + let (total_stake, _alpha_stake, _tao_stake): (Vec, Vec, Vec) = Self::get_stake_weights_for_network(netuid); - inplace_normalize_64(&mut total_stake); - let stake: Vec = vec_fixed64_to_fixed32(total_stake); + + // Get the minimum stake required. + let min_stake = Self::get_stake_threshold(); + + // Set stake of validators that doesn't meet the staking threshold to 0 as filter. + let mut filtered_stake: Vec = total_stake + .iter() + .map(|&s| { + if fixed64_to_u64(s) < min_stake { + return I64F64::from(0); + } + s + }) + .collect(); + log::debug!("Filtered stake: {:?}", &filtered_stake); + + inplace_normalize_64(&mut filtered_stake); + let stake: Vec = vec_fixed64_to_fixed32(filtered_stake); log::debug!("Normalised Stake: {:?}", &stake); // ======================= @@ -492,7 +525,8 @@ impl Pallet { log::trace!("max_allowed_validators: {:?}", max_allowed_validators); // Get new validator permits. - let new_validator_permits: Vec = is_topk(&stake, max_allowed_validators as usize); + let new_validator_permits: Vec = + is_topk_nonzero(&stake, max_allowed_validators as usize); log::trace!("new_validator_permits: {:?}", new_validator_permits); // ================== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 261c55345e..650fb50451 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -925,7 +925,7 @@ mod dispatches { /// User register a new subnetwork via burning token #[pallet::call_index(7)] #[pallet::weight((Weight::from_parts(219_400_000, 0) - .saturating_add(T::DbWeight::get().reads(34)) + .saturating_add(T::DbWeight::get().reads(33)) .saturating_add(T::DbWeight::get().writes(29)), DispatchClass::Normal, Pays::No))] pub fn burned_register( origin: OriginFor, @@ -1012,7 +1012,7 @@ mod dispatches { #[pallet::call_index(75)] #[pallet::weight(( Weight::from_parts(49_470_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::Yes diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 372b4f6e61..378ea8001b 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -617,7 +617,7 @@ impl Pallet { pub fn get_max_amount_remove(netuid: u16, limit_price: u64) -> Result> { // Corner case: root and stao // There's no slippage for root or stable subnets, so if limit price is 1e9 rao or - // higher, then max_amount equals u64::MAX, otherwise it is 0. + // lower, then max_amount equals u64::MAX, otherwise it is 0. if (netuid == Self::get_root_netuid()) || (SubnetMechanism::::get(netuid)) == 0 { if limit_price <= 1_000_000_000 { return Ok(u64::MAX); diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 2ae6169a3d..2d2ebaec47 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -317,15 +317,19 @@ impl Pallet { Error::::InvalidChildkeyTake ); - // Ensure the hotkey passes the rate limit. - ensure!( - Self::passes_rate_limit_on_subnet( - &TransactionType::SetChildkeyTake, // Set childkey take. - &hotkey, // Specific to a hotkey. - netuid, // Specific to a subnet. - ), - Error::::TxChildkeyTakeRateLimitExceeded - ); + let current_take = Self::get_childkey_take(&hotkey, netuid); + // Check the rate limit for increasing childkey take case + if take > current_take { + // Ensure the hotkey passes the rate limit. + ensure!( + Self::passes_rate_limit_on_subnet( + &TransactionType::SetChildkeyTake, // Set childkey take. + &hotkey, // Specific to a hotkey. + netuid, // Specific to a subnet. + ), + Error::::TxChildkeyTakeRateLimitExceeded + ); + } // Set last transaction block let current_block = Self::get_current_block_as_u64(); diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index 39a9d237e4..5c698c1b33 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -86,8 +86,6 @@ impl Pallet { Error::::SubNetworkDoesNotExist ); - Self::ensure_subtoken_enabled(netuid)?; - // --- 3. Ensure the passed network allows registrations. ensure!( Self::get_network_registration_allowed(netuid), diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index 34c7b5459b..1a9016f13f 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -3988,3 +3988,109 @@ fn test_pending_cooldown_one_day() { assert_eq!(pending_children.1, curr_block + expected_cooldown); }); } + +#[test] +fn test_do_set_childkey_take_success() { + new_test_ext(1).execute_with(|| { + // Setup + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + let take = 5000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set childkey take + assert_ok!(SubtensorModule::do_set_childkey_take( + coldkey, hotkey, netuid, take + )); + + // Verify the take was set correctly + assert_eq!(SubtensorModule::get_childkey_take(&hotkey, netuid), take); + let tx_type: u16 = TransactionType::SetChildkeyTake.into(); + assert_eq!( + TransactionKeyLastBlock::::get((hotkey, netuid, tx_type,)), + System::block_number() + ); + }); +} + +#[test] +fn test_do_set_childkey_take_non_associated_coldkey() { + new_test_ext(1).execute_with(|| { + // Setup + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let hotkey2 = U256::from(3); + let netuid: u16 = 1; + let take = 5000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set childkey take + assert_noop!( + SubtensorModule::do_set_childkey_take(coldkey, hotkey2, netuid, take), + Error::::NonAssociatedColdKey + ); + }); +} + +#[test] +fn test_do_set_childkey_take_invalid_take_value() { + new_test_ext(1).execute_with(|| { + // Setup + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + let take = SubtensorModule::get_max_childkey_take() + 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set childkey take + assert_noop!( + SubtensorModule::do_set_childkey_take(coldkey, hotkey, netuid, take), + Error::::InvalidChildkeyTake + ); + }); +} + +#[test] +fn test_do_set_childkey_take_rate_limit_exceeded() { + new_test_ext(1).execute_with(|| { + // Setup + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + let initial_take = 3000; + let higher_take = 5000; + let lower_take = 1000; + + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set initial childkey take + assert_ok!(SubtensorModule::do_set_childkey_take( + coldkey, + hotkey, + netuid, + initial_take + )); + + // Try to increase the take value, should hit rate limit + assert_noop!( + SubtensorModule::do_set_childkey_take(coldkey, hotkey, netuid, higher_take), + Error::::TxChildkeyTakeRateLimitExceeded + ); + + // lower take value should be ok + assert_ok!(SubtensorModule::do_set_childkey_take( + coldkey, hotkey, netuid, lower_take + )); + }); +} diff --git a/pallets/subtensor/src/tests/epoch.rs b/pallets/subtensor/src/tests/epoch.rs index a6e688625d..2557709912 100644 --- a/pallets/subtensor/src/tests/epoch.rs +++ b/pallets/subtensor/src/tests/epoch.rs @@ -2095,13 +2095,14 @@ fn test_deregistered_miner_bonds() { }); } -// Test that epoch assigns validator permits to highest stake uids, varies uid interleaving and stake values. +// Test that epoch assigns validator permits to highest stake uids that are over the stake threshold, varies uid interleaving and stake values. #[test] fn test_validator_permits() { let netuid: u16 = 1; let tempo: u16 = u16::MAX - 1; // high tempo to skip automatic epochs in on_initialize, use manual epochs instead for interleave in 0..3 { for (network_n, validators_n) in [(2, 1), (4, 2), (8, 4)] { + let min_stake = validators_n as u64; for assignment in 0..=1 { let (validators, servers) = distribute_nodes(validators_n as usize, network_n, interleave as usize); @@ -2132,6 +2133,7 @@ fn test_validator_permits() { netuid, network_n as u16, ); + SubtensorModule::set_stake_threshold(min_stake); // === Register [validator1, validator2, server1, server2] for key in 0..network_n as u64 { @@ -2173,7 +2175,7 @@ fn test_validator_permits() { SubtensorModule::epoch(netuid, 1_000_000_000); // run first epoch to set allowed validators for validator in &validators { assert_eq!( - correct, + stake[*validator as usize] >= min_stake, SubtensorModule::get_validator_permit_for_uid(netuid, *validator) ); } @@ -2211,7 +2213,7 @@ fn test_validator_permits() { } for server in &servers { assert_eq!( - correct, + (stake[*server as usize] + (2 * network_n as u64)) >= min_stake, SubtensorModule::get_validator_permit_for_uid(netuid, *server) ); } diff --git a/pallets/subtensor/src/tests/subnet.rs b/pallets/subtensor/src/tests/subnet.rs index a8c6cb2c52..ec737f8601 100644 --- a/pallets/subtensor/src/tests/subnet.rs +++ b/pallets/subtensor/src/tests/subnet.rs @@ -240,7 +240,6 @@ fn test_subtoken_enable() { } // cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable_reject_trading_before_enable --exact --show-output - #[test] fn test_subtoken_enable_reject_trading_before_enable() { // ensure_subtoken_enabled @@ -252,23 +251,18 @@ fn test_subtoken_enable_reject_trading_before_enable() { let hotkey_account_2_id: U256 = U256::from(3); let amount = DefaultMinStake::::get() * 10; - let burn_cost = 1000; - // Set the burn cost - SubtensorModule::set_burn(netuid, burn_cost); add_network_disable_subtoken(netuid, 10, 0); add_network_disable_subtoken(netuid2, 10, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, burn_cost + 10_000); - // all trading extrinsic should be rejected. - assert_noop!( - SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(coldkey_account_id), - netuid, - hotkey_account_id - ), - Error::::SubtokenDisabled - ); + // Register so staking *could* work + register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 0); + register_ok_neuron(netuid2, hotkey_account_id, coldkey_account_id, 100); + register_ok_neuron(netuid, hotkey_account_2_id, coldkey_account_id, 0); + register_ok_neuron(netuid2, hotkey_account_2_id, coldkey_account_id, 100); + + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10_000); + // all trading extrinsic should be rejected. assert_noop!( SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey_account_id), @@ -347,7 +341,6 @@ fn test_subtoken_enable_reject_trading_before_enable() { } // cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable_trading_ok_with_enable --exact --show-output - #[test] fn test_subtoken_enable_trading_ok_with_enable() { new_test_ext(1).execute_with(|| { @@ -361,29 +354,17 @@ fn test_subtoken_enable_trading_ok_with_enable() { // unstake, transfer, swap just very little let unstake_amount = DefaultMinStake::::get() * 10; - let burn_cost = 1000; - // Set the burn cost - SubtensorModule::set_burn(netuid, burn_cost); add_network(netuid, 10, 0); add_network(netuid2, 10, 0); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey_account_id, - burn_cost * 2 + stake_amount * 10, - ); + // Register so staking works + register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 0); + register_ok_neuron(netuid2, hotkey_account_id, coldkey_account_id, 100); + register_ok_neuron(netuid, hotkey_account_2_id, coldkey_account_id, 0); + register_ok_neuron(netuid2, hotkey_account_2_id, coldkey_account_id, 100); - // all trading extrinsic should be rejected. - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(coldkey_account_id), - netuid, - hotkey_account_id - )); - - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(coldkey_account_id), - netuid2, - hotkey_account_2_id - )); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, stake_amount * 10); + // all trading extrinsic should be possible now that subtoken is enabled. assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, @@ -470,3 +451,38 @@ fn test_subtoken_enable_trading_ok_with_enable() { )); }); } + +// cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable_ok_for_burn_register_before_enable --exact --show-output +#[test] +fn test_subtoken_enable_ok_for_burn_register_before_enable() { + // ensure_subtoken_enabled + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let netuid2: u16 = 2; + let hotkey_account_id: U256 = U256::from(1); + let coldkey_account_id = U256::from(2); + let hotkey_account_2_id: U256 = U256::from(3); + + let burn_cost = 1000; + // Set the burn cost + SubtensorModule::set_burn(netuid, burn_cost); + // Add the networks with subtoken disabled + add_network_disable_subtoken(netuid, 10, 0); + add_network_disable_subtoken(netuid2, 10, 0); + // Give enough to burned register + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, burn_cost * 2 + 5_000); + + // Should be possible to burned register before enable is activated + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid2, + hotkey_account_2_id + )); + }); +} diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index 14b80a0310..3d240750cf 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -677,6 +677,13 @@ fn test_weights_err_setting_weights_too_fast() { SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id) .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &(U256::from(66)), + netuid, + 1, + ); SubtensorModule::set_weights_set_rate_limit(netuid, 10); assert_eq!(SubtensorModule::get_weights_set_rate_limit(netuid), 10); @@ -753,6 +760,7 @@ fn test_weights_err_has_duplicate_ids() { let salt: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8]; add_network(netuid, tempo, 0); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_max_allowed_uids(netuid, 100); // Allow many registrations per block. SubtensorModule::set_max_registrations_per_block(netuid, 100); // Allow many registrations per block. SubtensorModule::set_target_registrations_per_interval(netuid, 100); // Allow many registrations per block. @@ -762,6 +770,13 @@ fn test_weights_err_has_duplicate_ids() { SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id) .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(77), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &(U256::from(77)), + netuid, + 1, + ); // uid 1 register_ok_neuron(netuid, U256::from(1), U256::from(1), 100_000); @@ -933,7 +948,15 @@ fn test_set_weights_err_invalid_uid() { let neuron_uid: u16 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id) .expect("Not registered."); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &(U256::from(66)), + netuid, + 1, + ); let weight_keys: Vec = vec![9999]; // Does not exist let weight_values: Vec = vec![88]; // random value let result = @@ -958,6 +981,13 @@ fn test_set_weight_not_enough_values() { .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); SubtensorModule::set_max_weight_limit(netuid, u16::MAX); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &account_id, + &(U256::from(2)), + netuid, + 1, + ); register_ok_neuron(1, U256::from(3), U256::from(4), 300000); SubtensorModule::set_min_allowed_weights(netuid, 2); @@ -1059,8 +1089,16 @@ fn test_set_weights_sum_larger_than_u16_max() { register_ok_neuron(1, U256::from(1), U256::from(2), 100_000); let neuron_uid: u16 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(1)) .expect("Not registered."); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); SubtensorModule::set_max_weight_limit(netuid, u16::MAX); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(2)), + netuid, + 1, + ); register_ok_neuron(1, U256::from(3), U256::from(4), 300_000); SubtensorModule::set_min_allowed_weights(1, 2); @@ -1548,10 +1586,25 @@ fn test_commit_reveal_weights_ok() { // Register neurons and set up configurations register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Commit at block 0 assert_ok!(SubtensorModule::commit_weights( @@ -1601,10 +1654,25 @@ fn test_commit_reveal_tempo_interval() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Commit at block 0 assert_ok!(SubtensorModule::commit_weights( @@ -1722,9 +1790,24 @@ fn test_commit_reveal_hash() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -1807,9 +1890,24 @@ fn test_commit_reveal_disabled_or_enabled() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Disable commit/reveal SubtensorModule::set_commit_reveal_weights_enabled(netuid, false); @@ -1869,9 +1967,24 @@ fn test_toggle_commit_reveal_weights_and_set_weights() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_weights_set_rate_limit(netuid, 5); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Enable commit/reveal SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); @@ -1939,10 +2052,25 @@ fn test_tempo_change_during_commit_reveal_process() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); assert_ok!(SubtensorModule::commit_weights( RuntimeOrigin::signed(hotkey), @@ -2073,10 +2201,25 @@ fn test_commit_reveal_multiple_commits() { // Setup the network and neurons register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // 1. Commit 10 times successfully let mut commit_info = Vec::new(); @@ -2463,8 +2606,23 @@ fn test_expired_commits_handling_in_commit_and_reveal() { // Register neurons register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // 1. Commit 5 times in epoch 0 let mut commit_info = Vec::new(); @@ -2646,8 +2804,23 @@ fn test_reveal_at_exact_epoch() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); let reveal_periods: Vec = vec![0, 1, 2, 7, 40, 86, 100]; @@ -2795,8 +2968,23 @@ fn test_tempo_and_reveal_period_change_during_commit_reveal_process() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Step 1: Commit weights assert_ok!(SubtensorModule::commit_weights( @@ -2970,8 +3158,23 @@ fn test_commit_reveal_order_enforcement() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // Commit three times: A, B, C let mut commit_info = Vec::new(); @@ -3227,8 +3430,23 @@ fn test_successful_batch_reveal() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // 1. Commit multiple times let mut commit_info = Vec::new(); @@ -3290,8 +3508,23 @@ fn test_batch_reveal_with_expired_commits() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); let mut commit_info = Vec::new(); @@ -3692,8 +3925,23 @@ fn test_batch_reveal_with_out_of_order_commits() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, hotkey, U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // 1. Commit multiple times (A, B, C) let mut commit_info = Vec::new(); @@ -4080,10 +4328,25 @@ fn test_get_reveal_blocks() { // **5. Register Neurons and Configure the Network** register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); // **6. Commit Weights at Block 0** assert_ok!(SubtensorModule::commit_weights( @@ -4199,10 +4462,25 @@ fn test_commit_weights_rate_limit() { register_ok_neuron(netuid, U256::from(3), U256::from(4), 300_000); register_ok_neuron(netuid, U256::from(1), U256::from(2), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 10); // Rate limit is 10 blocks SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(0)), + &(U256::from(0)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &(U256::from(1)), + &(U256::from(1)), + netuid, + 1, + ); let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey).expect("expected uid"); @@ -4367,6 +4645,7 @@ fn test_reveal_crv3_commits_success() { add_network(netuid, 5, 0); register_ok_neuron(netuid, hotkey1, U256::from(3), 100_000); register_ok_neuron(netuid, hotkey2, U256::from(4), 100_000); + SubtensorModule::set_stake_threshold(0); SubtensorModule::set_weights_set_rate_limit(netuid, 0); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); SubtensorModule::set_reveal_period(netuid, 3); @@ -4378,6 +4657,20 @@ fn test_reveal_crv3_commits_success() { SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid2, true); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey1, + &(U256::from(3)), + netuid, + 1, + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey2, + &(U256::from(4)), + netuid, + 1, + ); let version_key = SubtensorModule::get_weights_version_key(netuid); diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index ca52831323..4c6824e07b 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -86,7 +86,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 14] { + pub fn used_addresses() -> [H160; 15] { [ hash(1), hash(2), @@ -102,6 +102,7 @@ where hash(MetagraphPrecompile::::INDEX), hash(NeuronPrecompile::::INDEX), hash(StakingPrecompileV2::::INDEX), + hash(UidLookupPrecompile::::INDEX), ] } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 948b90fcbe..64937fd3bb 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -209,7 +209,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 269, + spec_version: 271, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,