From dd3688eebee8aced907958c6d138b5e7f88d7385 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Thu, 16 Oct 2025 09:57:13 -0700 Subject: [PATCH 1/6] make kappa root only --- pallets/admin-utils/src/lib.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 66e7eab318..7e6d243e55 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -581,23 +581,13 @@ pub mod pallet { .saturating_add(::DbWeight::get().reads(3_u64)) .saturating_add(::DbWeight::get().writes(1_u64)))] pub fn sudo_set_kappa(origin: OriginFor, netuid: NetUid, kappa: u16) -> DispatchResult { - let maybe_owner = pallet_subtensor::Pallet::::ensure_sn_owner_or_root_with_limits( - origin, - netuid, - &[Hyperparameter::Kappa.into()], - )?; - + ensure_root(origin)?; ensure!( pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); pallet_subtensor::Pallet::::set_kappa(netuid, kappa); log::debug!("KappaSet( netuid: {netuid:?} kappa: {kappa:?} ) "); - pallet_subtensor::Pallet::::record_owner_rl( - maybe_owner, - netuid, - &[Hyperparameter::Kappa.into()], - ); Ok(()) } From 81667e1e189c1f15e06460c16a6e9e4c4ad7e6cb Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Thu, 16 Oct 2025 10:30:43 -0700 Subject: [PATCH 2/6] fix tests --- pallets/admin-utils/src/tests/mod.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 4e534c3210..f113163c21 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -2058,7 +2058,7 @@ fn test_freeze_window_blocks_root_and_owner() { let owner: U256 = U256::from(9); SubnetOwner::::insert(netuid, owner); assert_noop!( - AdminUtils::sudo_set_kappa( + AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 77 @@ -2145,14 +2145,14 @@ fn test_owner_hyperparam_update_rate_limit_enforced() { )); // First update succeeds - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 11 )); // Immediate second update fails due to TxRateLimitExceeded assert_noop!( - AdminUtils::sudo_set_kappa( + AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 12 @@ -2163,7 +2163,7 @@ fn test_owner_hyperparam_update_rate_limit_enforced() { // Advance less than limit still fails run_to_block(SubtensorModule::get_current_block_as_u64() + 1); assert_noop!( - AdminUtils::sudo_set_kappa( + AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 13 @@ -2173,7 +2173,7 @@ fn test_owner_hyperparam_update_rate_limit_enforced() { // Advance one more block to pass the limit; should succeed run_to_block(SubtensorModule::get_current_block_as_u64() + 1); - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 14 @@ -2200,7 +2200,7 @@ fn test_hyperparam_rate_limit_enforced_by_tempo() { )); // First owner update should succeed - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 1 @@ -2208,13 +2208,17 @@ fn test_hyperparam_rate_limit_enforced_by_tempo() { // Immediate second update should fail due to tempo-based RL assert_noop!( - AdminUtils::sudo_set_kappa(<::RuntimeOrigin>::signed(owner), netuid, 2), + AdminUtils::sudo_set_commit_reveal_weights_interval( + <::RuntimeOrigin>::signed(owner), + netuid, + 2 + ), SubtensorError::::TxRateLimitExceeded ); // Advance 2 blocks (2 tempos with tempo=1) then succeed run_to_block(SubtensorModule::get_current_block_as_u64() + 2); - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 3 @@ -2244,7 +2248,7 @@ fn test_owner_hyperparam_rate_limit_independent_per_param() { )); // First update to kappa should succeed - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 10 @@ -2252,7 +2256,7 @@ fn test_owner_hyperparam_rate_limit_independent_per_param() { // Immediate second update to the SAME param (kappa) should be blocked by RL assert_noop!( - AdminUtils::sudo_set_kappa( + AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 11 @@ -2269,7 +2273,7 @@ fn test_owner_hyperparam_rate_limit_independent_per_param() { // kappa should still be blocked until its own RL window passes assert_noop!( - AdminUtils::sudo_set_kappa( + AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 12 @@ -2287,7 +2291,7 @@ fn test_owner_hyperparam_rate_limit_independent_per_param() { run_to_block(SubtensorModule::get_current_block_as_u64() + 2); // Now both hyperparameters can be updated again - assert_ok!(AdminUtils::sudo_set_kappa( + assert_ok!(AdminUtils::sudo_set_commit_reveal_weights_interval( <::RuntimeOrigin>::signed(owner), netuid, 13 From fcdc3ab7b6ea3c32512463a59d510d89717c5738 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 16 Oct 2025 18:36:19 +0000 Subject: [PATCH 3/6] auto-update benchmark weights --- pallets/admin-utils/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 7e6d243e55..25f162d43f 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -577,8 +577,8 @@ pub mod pallet { /// It is only callable by the root account or subnet owner. /// The extrinsic will call the Subtensor pallet to set the kappa. #[pallet::call_index(16)] - #[pallet::weight(Weight::from_parts(26_210_000, 0) - .saturating_add(::DbWeight::get().reads(3_u64)) + #[pallet::weight(Weight::from_parts(15_390_000, 0) + .saturating_add(::DbWeight::get().reads(1_u64)) .saturating_add(::DbWeight::get().writes(1_u64)))] pub fn sudo_set_kappa(origin: OriginFor, netuid: NetUid, kappa: u16) -> DispatchResult { ensure_root(origin)?; @@ -1242,7 +1242,7 @@ pub mod pallet { /// The extrinsic will call the Subtensor pallet to set the minimum delegate take. #[pallet::call_index(46)] #[pallet::weight(( - Weight::from_parts(5_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64)), + Weight::from_parts(7_214_000, 0).saturating_add(T::DbWeight::get().writes(1_u64)), DispatchClass::Operational, Pays::Yes ))] From 17d0d482ac601da24069a40ee7de755b30d93d9f Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 20 Oct 2025 10:13:23 -0700 Subject: [PATCH 4/6] migrate kappa to default --- pallets/subtensor/src/macros/hooks.rs | 4 +- .../migrate_kappa_map_to_default.rs | 60 +++++++++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + pallets/subtensor/src/tests/migration.rs | 77 +++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 20651f68fc..3e75035160 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -153,7 +153,9 @@ mod hooks { // Cleanup child/parent keys .saturating_add(migrations::migrate_fix_childkeys::migrate_fix_childkeys::()) // Migrate AutoStakeDestinationColdkeys - .saturating_add(migrations::migrate_auto_stake_destination::migrate_auto_stake_destination::()); + .saturating_add(migrations::migrate_auto_stake_destination::migrate_auto_stake_destination::()) + // Migrate Kappa to default (0.5) + .saturating_add(migrations::migrate_kappa_map_to_default::migrate_kappa_map_to_default::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs new file mode 100644 index 0000000000..1e379da7df --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs @@ -0,0 +1,60 @@ +use super::*; +use frame_support::{storage::IterableStorageMap, traits::Get, weights::Weight}; +use log; +use scale_info::prelude::string::String; + +pub fn migrate_kappa_map_to_default() -> Weight { + let mig_name: Vec = b"kappa_map_to_default".to_vec(); + + // 1 read for the HasMigrationRun flag + let mut total_weight = T::DbWeight::get().reads(1); + + // Run once guard + if HasMigrationRun::::get(&mig_name) { + log::info!( + "Migration '{}' already executed - skipping", + String::from_utf8_lossy(&mig_name) + ); + return total_weight; + } + + log::info!("Running migration '{}'", String::from_utf8_lossy(&mig_name)); + + let target: u16 = DefaultKappa::::get(); + + let mut reads: u64 = 0; + let mut writes: u64 = 0; + let mut visited: u64 = 0; + let mut updated: u64 = 0; + let mut unchanged: u64 = 0; + + for (netuid, current) in Kappa::::iter() { + visited += 1; + reads += 1; + + if current != target { + Kappa::::insert(netuid, target); + writes += 1; + updated += 1; + } else { + unchanged += 1; + } + } + + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(reads, writes)); + + log::info!( + "Kappa migration summary: visited={visited}, updated={updated}, unchanged={unchanged}, target_default={}", + target + ); + + HasMigrationRun::::insert(&mig_name, true); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{}' completed", + String::from_utf8_lossy(&mig_name) + ); + + total_weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index db0b290661..ca21f9bef2 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -21,6 +21,7 @@ pub mod migrate_fix_root_subnet_tao; pub mod migrate_fix_root_tao_and_alpha_in; pub mod migrate_identities_v2; pub mod migrate_init_total_issuance; +pub mod migrate_kappa_map_to_default; pub mod migrate_network_immunity_period; pub mod migrate_network_lock_cost_2500; pub mod migrate_network_lock_reduction_interval; diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index ede32aa06c..6e9544de6a 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -2171,3 +2171,80 @@ fn test_migrate_network_lock_cost_2500_sets_price_and_decay() { ); }); } + +#[test] +fn test_migrate_kappa_map_to_default() { + new_test_ext(1).execute_with(|| { + // ------------------------------ + // 0. Constants / helpers + // ------------------------------ + const MIG_NAME: &[u8] = b"kappa_map_to_default"; + + let default: u16 = DefaultKappa::::get(); + let not_default: u16 = default.wrapping_add(1); + + // Choose a few netuids to exercise both "changed" and "unchanged" paths + let n0: u16 = 0; + let n1: u16 = 1; + let n2: u16 = 42; + + // ------------------------------ + // 1. Pre-state: seed non-default & default entries + // ------------------------------ + Kappa::::insert(n0, not_default); // will need update + Kappa::::insert(n1, default); // already default + Kappa::::insert(n2, not_default); // will need update + + assert_eq!( + Kappa::::get(n0), + not_default, + "precondition failed: Kappa[n0] should be non-default before migration" + ); + assert_eq!( + Kappa::::get(n1), + default, + "precondition failed: Kappa[n1] should be default before migration" + ); + assert_eq!( + Kappa::::get(n2), + not_default, + "precondition failed: Kappa[n2] should be non-default before migration" + ); + + assert!( + !HasMigrationRun::::get(MIG_NAME.to_vec()), + "migration flag should be false before run" + ); + + // ------------------------------ + // 2. Run migration + // ------------------------------ + let w = + crate::migrations::migrate_kappa_map_to_default::migrate_kappa_map_to_default::(); + assert!(!w.is_zero(), "weight must be non-zero"); + + // ------------------------------ + // 3. Verify results + // ------------------------------ + assert!( + HasMigrationRun::::get(MIG_NAME.to_vec()), + "migration flag not set" + ); + + assert_eq!( + Kappa::::get(n0), + default, + "Kappa[n0] should be reset to the configured default" + ); + assert_eq!( + Kappa::::get(n1), + default, + "Kappa[n1] should remain at the configured default" + ); + assert_eq!( + Kappa::::get(n2), + default, + "Kappa[n2] should be reset to the configured default" + ); + }); +} From feb736e55e3841d63a428bbff99a057587c41899 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 20 Oct 2025 10:52:13 -0700 Subject: [PATCH 5/6] fix test --- .../migrate_kappa_map_to_default.rs | 2 +- pallets/subtensor/src/tests/migration.rs | 27 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs index 1e379da7df..2de12acd0f 100644 --- a/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs +++ b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs @@ -1,5 +1,5 @@ use super::*; -use frame_support::{storage::IterableStorageMap, traits::Get, weights::Weight}; +use frame_support::{traits::Get, weights::Weight}; use log; use scale_info::prelude::string::String; diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 6e9544de6a..f5c619bf65 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -2183,30 +2183,29 @@ fn test_migrate_kappa_map_to_default() { let default: u16 = DefaultKappa::::get(); let not_default: u16 = default.wrapping_add(1); - // Choose a few netuids to exercise both "changed" and "unchanged" paths - let n0: u16 = 0; - let n1: u16 = 1; - let n2: u16 = 42; - // ------------------------------ // 1. Pre-state: seed non-default & default entries // ------------------------------ - Kappa::::insert(n0, not_default); // will need update - Kappa::::insert(n1, default); // already default - Kappa::::insert(n2, not_default); // will need update + let n0: NetUid = 0u16.into(); + let n1: NetUid = 1u16.into(); + let n2: NetUid = 42u16.into(); + + Kappa::::insert(&n0, not_default); + Kappa::::insert(&n1, default); + Kappa::::insert(&n2, not_default); assert_eq!( - Kappa::::get(n0), + Kappa::::get(&n0), not_default, "precondition failed: Kappa[n0] should be non-default before migration" ); assert_eq!( - Kappa::::get(n1), + Kappa::::get(&n1), default, "precondition failed: Kappa[n1] should be default before migration" ); assert_eq!( - Kappa::::get(n2), + Kappa::::get(&n2), not_default, "precondition failed: Kappa[n2] should be non-default before migration" ); @@ -2232,17 +2231,17 @@ fn test_migrate_kappa_map_to_default() { ); assert_eq!( - Kappa::::get(n0), + Kappa::::get(&n0), default, "Kappa[n0] should be reset to the configured default" ); assert_eq!( - Kappa::::get(n1), + Kappa::::get(&n1), default, "Kappa[n1] should remain at the configured default" ); assert_eq!( - Kappa::::get(n2), + Kappa::::get(&n2), default, "Kappa[n2] should be reset to the configured default" ); From 6ca4b2401a1986ac47192ff4adb4e34fd7b20b1d Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 20 Oct 2025 11:18:21 -0700 Subject: [PATCH 6/6] clippy --- .../migrate_kappa_map_to_default.rs | 26 +++++++---------- pallets/subtensor/src/tests/migration.rs | 28 +++++++++++-------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs index 2de12acd0f..69b82cae0b 100644 --- a/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs +++ b/pallets/subtensor/src/migrations/migrate_kappa_map_to_default.rs @@ -5,20 +5,18 @@ use scale_info::prelude::string::String; pub fn migrate_kappa_map_to_default() -> Weight { let mig_name: Vec = b"kappa_map_to_default".to_vec(); + let mig_name_str = String::from_utf8_lossy(&mig_name); // 1 read for the HasMigrationRun flag let mut total_weight = T::DbWeight::get().reads(1); // Run once guard if HasMigrationRun::::get(&mig_name) { - log::info!( - "Migration '{}' already executed - skipping", - String::from_utf8_lossy(&mig_name) - ); + log::info!("Migration '{mig_name_str}' already executed - skipping"); return total_weight; } - log::info!("Running migration '{}'", String::from_utf8_lossy(&mig_name)); + log::info!("Running migration '{mig_name_str}'"); let target: u16 = DefaultKappa::::get(); @@ -29,32 +27,28 @@ pub fn migrate_kappa_map_to_default() -> Weight { let mut unchanged: u64 = 0; for (netuid, current) in Kappa::::iter() { - visited += 1; - reads += 1; + visited = visited.saturating_add(1); + reads = reads.saturating_add(1); if current != target { Kappa::::insert(netuid, target); - writes += 1; - updated += 1; + writes = writes.saturating_add(1); + updated = updated.saturating_add(1); } else { - unchanged += 1; + unchanged = unchanged.saturating_add(1); } } total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(reads, writes)); log::info!( - "Kappa migration summary: visited={visited}, updated={updated}, unchanged={unchanged}, target_default={}", - target + "Kappa migration summary: visited={visited}, updated={updated}, unchanged={unchanged}, target_default={target}" ); HasMigrationRun::::insert(&mig_name, true); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::info!( - "Migration '{}' completed", - String::from_utf8_lossy(&mig_name) - ); + log::info!("Migration '{mig_name_str}' completed"); total_weight } diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index f5c619bf65..fbf49f3ae5 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -2179,33 +2179,37 @@ fn test_migrate_kappa_map_to_default() { // 0. Constants / helpers // ------------------------------ const MIG_NAME: &[u8] = b"kappa_map_to_default"; - let default: u16 = DefaultKappa::::get(); - let not_default: u16 = default.wrapping_add(1); + + let not_default: u16 = if default == u16::MAX { + default.saturating_sub(1) + } else { + default.saturating_add(1) + }; // ------------------------------ - // 1. Pre-state: seed non-default & default entries + // 1. Pre-state: seed using the correct key type (NetUid) // ------------------------------ let n0: NetUid = 0u16.into(); let n1: NetUid = 1u16.into(); let n2: NetUid = 42u16.into(); - Kappa::::insert(&n0, not_default); - Kappa::::insert(&n1, default); - Kappa::::insert(&n2, not_default); + Kappa::::insert(n0, not_default); + Kappa::::insert(n1, default); + Kappa::::insert(n2, not_default); assert_eq!( - Kappa::::get(&n0), + Kappa::::get(n0), not_default, "precondition failed: Kappa[n0] should be non-default before migration" ); assert_eq!( - Kappa::::get(&n1), + Kappa::::get(n1), default, "precondition failed: Kappa[n1] should be default before migration" ); assert_eq!( - Kappa::::get(&n2), + Kappa::::get(n2), not_default, "precondition failed: Kappa[n2] should be non-default before migration" ); @@ -2231,17 +2235,17 @@ fn test_migrate_kappa_map_to_default() { ); assert_eq!( - Kappa::::get(&n0), + Kappa::::get(n0), default, "Kappa[n0] should be reset to the configured default" ); assert_eq!( - Kappa::::get(&n1), + Kappa::::get(n1), default, "Kappa[n1] should remain at the configured default" ); assert_eq!( - Kappa::::get(&n2), + Kappa::::get(n2), default, "Kappa[n2] should be reset to the configured default" );