diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 245fc8a5a..7b99c306a 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -509,10 +509,14 @@ pub mod pallet { /// The extrinsic will call the Subtensor pallet to set the kappa. #[pallet::call_index(16)] #[pallet::weight(Weight::from_parts(16_740_000, 0) - .saturating_add(::DbWeight::get().reads(1_u64)) + .saturating_add(::DbWeight::get().reads(2_u64)) .saturating_add(::DbWeight::get().writes(1_u64)))] pub fn sudo_set_kappa(origin: OriginFor, netuid: NetUid, kappa: u16) -> DispatchResult { - pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; + if pallet_subtensor::Pallet::::get_kappa_can_set_by_owner(netuid) { + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; + } else { + ensure_root(origin)?; + } ensure!( pallet_subtensor::Pallet::::if_subnet_exist(netuid), @@ -1221,7 +1225,7 @@ pub mod pallet { /// # Weight /// Weight is handled by the `#[pallet::weight]` attribute. #[pallet::call_index(57)] - #[pallet::weight(Weight::from_parts(19_320_000, 0) + #[pallet::weight(Weight::from_parts(15_130_000, 0) .saturating_add(::DbWeight::get().reads(1_u64)) .saturating_add(::DbWeight::get().writes(1_u64)))] pub fn sudo_set_commit_reveal_weights_interval( @@ -1623,6 +1627,29 @@ pub mod pallet { log::debug!("CKBurnSet( burn: {burn:?} ) "); Ok(()) } + /// The extrinsic sets the kappa for a subnet. + /// 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(74)] + #[pallet::weight(Weight::from_parts(16_740_000, 0) + .saturating_add(::DbWeight::get().reads(1_u64)) + .saturating_add(::DbWeight::get().writes(1_u64)))] + pub fn sudo_set_kappa_can_set_by_owner( + origin: OriginFor, + netuid: NetUid, + kappa_can_set_by_owner: bool, + ) -> DispatchResult { + ensure_root(origin)?; + + pallet_subtensor::Pallet::::set_kappa_can_set_by_owner( + netuid, + kappa_can_set_by_owner, + ); + log::debug!( + "KappaCanSetByOwnerSet( netuid: {netuid:?} kappaCanSet: {kappa_can_set_by_owner:?} ) " + ); + Ok(()) + } } } diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index c8efd1066..9494e8f56 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -585,6 +585,7 @@ fn test_sudo_set_kappa() { let to_be_set: u16 = 10; add_network(netuid, 10); let init_value: u16 = SubtensorModule::get_kappa(netuid); + let can_set_by_owner: bool = SubtensorModule::get_kappa_can_set_by_owner(netuid); assert_eq!( AdminUtils::sudo_set_kappa( <::RuntimeOrigin>::signed(U256::from(1)), @@ -601,6 +602,8 @@ fn test_sudo_set_kappa() { ), Err(Error::::SubnetDoesNotExist.into()) ); + + assert!(can_set_by_owner); assert_eq!(SubtensorModule::get_kappa(netuid), init_value); assert_ok!(AdminUtils::sudo_set_kappa( <::RuntimeOrigin>::root(), @@ -611,6 +614,65 @@ fn test_sudo_set_kappa() { }); } +#[test] +fn test_subnet_owner_set_kappa() { + new_test_ext().execute_with(|| { + let netuid = NetUid::from(1); + let to_be_set: u16 = 10; + add_network(netuid, 10); + + let owner = pallet_subtensor::pallet::SubnetOwner::::get(netuid); + let init_value: u16 = SubtensorModule::get_kappa(netuid); + let can_set_by_owner: bool = SubtensorModule::get_kappa_can_set_by_owner(netuid); + assert_eq!( + AdminUtils::sudo_set_kappa( + <::RuntimeOrigin>::signed(U256::from(1)), + netuid, + to_be_set + ), + Err(DispatchError::BadOrigin) + ); + assert_eq!( + AdminUtils::sudo_set_kappa( + <::RuntimeOrigin>::root(), + netuid.next(), + to_be_set + ), + Err(Error::::SubnetDoesNotExist.into()) + ); + + assert!(can_set_by_owner); + assert_eq!(SubtensorModule::get_kappa(netuid), init_value); + assert_ok!(AdminUtils::sudo_set_kappa( + <::RuntimeOrigin>::signed(owner), + netuid, + to_be_set + )); + assert_eq!(SubtensorModule::get_kappa(netuid), to_be_set); + + assert_ok!(AdminUtils::sudo_set_kappa_can_set_by_owner( + <::RuntimeOrigin>::root(), + netuid, + false + )); + assert!(!SubtensorModule::get_kappa_can_set_by_owner(netuid)); + + assert_eq!( + AdminUtils::sudo_set_kappa( + <::RuntimeOrigin>::signed(owner), + netuid, + to_be_set + ), + Err(DispatchError::BadOrigin) + ); + assert_ok!(AdminUtils::sudo_set_kappa( + <::RuntimeOrigin>::root(), + netuid, + to_be_set + )); + }); +} + #[test] fn test_sudo_set_rho() { new_test_ext().execute_with(|| { diff --git a/pallets/drand/src/lib.rs b/pallets/drand/src/lib.rs index 145aeb665..b191e4b32 100644 --- a/pallets/drand/src/lib.rs +++ b/pallets/drand/src/lib.rs @@ -332,7 +332,7 @@ pub mod pallet { impl Pallet { /// Verify and write a pulse from the beacon into the runtime #[pallet::call_index(0)] - #[pallet::weight(Weight::from_parts(4_294_000_000, 0) + #[pallet::weight(Weight::from_parts(5_228_000_000, 0) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)))] pub fn write_pulse( diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index ce4e41e35..7f118843c 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1474,6 +1474,10 @@ pub mod pallet { pub type SubtokenEnabled = StorageMap<_, Identity, NetUid, bool, ValueQuery, DefaultFalse>; + #[pallet::storage] + /// --- MAP ( netuid ) --> If Kappa can be set by owner + pub type KappaCanSetByOwner = + StorageMap<_, Identity, NetUid, bool, ValueQuery, DefaultTrue>; #[pallet::type_value] /// Default value for burn keys limit pub fn DefaultImmuneOwnerUidsLimit() -> u16 { diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index b89fe8e86..f8842259e 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -15,7 +15,7 @@ mod config { { /// call type type RuntimeCall: Parameter - + Dispatchable + + Dispatchable::RuntimeOrigin> + From> + IsType<::RuntimeCall> + From>; @@ -25,11 +25,11 @@ mod config { /// A sudo-able call. type SudoRuntimeCall: Parameter - + UnfilteredDispatchable + + UnfilteredDispatchable::RuntimeOrigin> + GetDispatchInfo; /// Origin checking for council majority - type CouncilOrigin: EnsureOrigin; + type CouncilOrigin: EnsureOrigin<::RuntimeOrigin>; /// Currency type that will be used to place deposits on neurons type Currency: fungible::Balanced diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index c84270920..5d9a6e1a0 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -2031,7 +2031,7 @@ mod dispatches { /// * commit_reveal_version (`u16`): /// - The client (bittensor-drand) version #[pallet::call_index(113)] - #[pallet::weight((Weight::from_parts(64_530_000, 0) + #[pallet::weight((Weight::from_parts(79_930_000, 0) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn commit_timelocked_weights( diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index f64962f09..d673ec960 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -248,6 +248,10 @@ impl Pallet { BlockAtRegistration::::get(netuid, neuron_uid) } + pub fn get_kappa_can_set_by_owner(netuid: NetUid) -> bool { + KappaCanSetByOwner::::get(netuid) + } + // ======================== // ===== Take checks ====== // ======================== @@ -805,6 +809,19 @@ impl Pallet { } } + /// Set if Kappa can be set by owner + /// + /// # Arguments + /// + /// * `netuid` - The unique identifier for the subnet. + /// * `can_set` - Whether Kappa can be set by owner. + /// + /// # Effects + /// + /// * Update the KappaCanSetByOwner storage. + pub fn set_kappa_can_set_by_owner(netuid: NetUid, can_set: bool) { + KappaCanSetByOwner::::insert(netuid, can_set); + } /// Set the per-subnet limit (for the given `netuid`) on the number of **owner-immune** /// neurons (UIDs). /// diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 8b4d0eff8..47bf38c97 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use frame_support::traits::ConstU32; use frame_system::RawOrigin; -use pallet_evm::{AddressMapping, PrecompileHandle}; +use pallet_evm::{AddressMapping, ExitError, PrecompileFailure, PrecompileHandle}; use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; use sp_runtime::traits::Dispatchable; @@ -373,16 +373,10 @@ where #[precompile::public("setKappa(uint16,uint16)")] #[precompile::payable] - fn set_kappa(handle: &mut impl PrecompileHandle, netuid: u16, kappa: u16) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_kappa { - netuid: netuid.into(), - kappa, - }; - - handle.try_dispatch_runtime_call::( - call, - RawOrigin::Signed(handle.caller_account_id::()), - ) + fn set_kappa(_handle: &mut impl PrecompileHandle, _netuid: u16, _kappa: u16) -> EvmResult<()> { + Err(PrecompileFailure::Error { + exit_status: ExitError::Other("Bad origin".into()), + }) } #[precompile::public("getRho(uint16)")]