From 60ae851e33782e5f892edd9bd974a14f9c2426fb Mon Sep 17 00:00:00 2001 From: unconst Date: Mon, 25 May 2026 16:38:04 +0200 Subject: [PATCH 1/2] Restrict sudo_set_subnet_emission_enabled to root origin Switch the dispatch from ensure_sn_owner_or_root_with_limits to ensure_root so only the Triumvirate (root) can toggle pool-side emission for a subnet. Drop the owner rate-limit recording since no subnet owner can take this path anymore. Co-authored-by: Cursor --- 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 ccf047b2b3..c71d92b9ab 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -2232,11 +2232,7 @@ pub mod pallet { netuid: NetUid, enabled: bool, ) -> DispatchResult { - let maybe_owner = pallet_subtensor::Pallet::::ensure_sn_owner_or_root_with_limits( - origin, - netuid, - &[Hyperparameter::SubnetEmissionEnabled.into()], - )?; + ensure_root(origin)?; pallet_subtensor::Pallet::::ensure_admin_window_open(netuid)?; ensure!( @@ -2249,12 +2245,6 @@ pub mod pallet { Self::deposit_event(Event::SubnetEmissionEnabledSet { netuid, enabled }); log::debug!("SubnetEmissionEnabledSet( netuid: {netuid:?}, enabled: {enabled:?} )"); - pallet_subtensor::Pallet::::record_owner_rl( - maybe_owner, - netuid, - &[Hyperparameter::SubnetEmissionEnabled.into()], - ); - Ok(()) } } From 51b6645de02afcab53936ef9e31e70171d0ac2b1 Mon Sep 17 00:00:00 2001 From: unconst Date: Mon, 25 May 2026 17:37:05 +0200 Subject: [PATCH 2/2] Add regression test for root-only sudo_set_subnet_emission_enabled Cover the changed authorization boundary directly: a signed subnet owner must receive DispatchError::BadOrigin and leave SubnetEmissionEnabled unchanged, and RuntimeOrigin::root() must still be able to toggle the flag. The admin freeze window is disabled in the test so neither path is blocked by it. Co-authored-by: Cursor --- pallets/admin-utils/src/tests/mod.rs | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 61b9662492..89601bf80c 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -3104,3 +3104,45 @@ fn test_sudo_set_start_call_delay_permissions_and_zero_delay() { ); }); } + +#[test] +fn test_sudo_set_subnet_emission_enabled_root_only() { + new_test_ext().execute_with(|| { + let netuid = NetUid::from(1); + let sn_owner = U256::from(42); + + add_network(netuid, 10); + SubnetOwner::::insert(netuid, sn_owner); + + // Disable the admin freeze window so neither path is blocked by it. + SubtensorModule::set_admin_freeze_window(0); + + let initial = pallet_subtensor::SubnetEmissionEnabled::::get(netuid); + + // Signed subnet owner must be rejected with BadOrigin and storage unchanged. + assert_eq!( + AdminUtils::sudo_set_subnet_emission_enabled( + <::RuntimeOrigin>::signed(sn_owner), + netuid, + !initial, + ), + Err(DispatchError::BadOrigin) + ); + assert_eq!( + pallet_subtensor::SubnetEmissionEnabled::::get(netuid), + initial, + "signed owner origin must not mutate SubnetEmissionEnabled" + ); + + // Root can still toggle the flag. + assert_ok!(AdminUtils::sudo_set_subnet_emission_enabled( + <::RuntimeOrigin>::root(), + netuid, + !initial, + )); + assert_eq!( + pallet_subtensor::SubnetEmissionEnabled::::get(netuid), + !initial + ); + }); +}