Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,45 @@ pub mod pallet {
Ok(())
}

/// The extrinsic sets the minimum childkey take for a subnet.
/// It is callable by root or the subnet owner.
/// The subnet minimum can only make the global minimum stricter.
#[pallet::call_index(93)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::sudo_set_min_childkey_take_per_subnet())]
pub fn sudo_set_min_childkey_take_per_subnet(
origin: OriginFor<T>,
netuid: NetUid,
take: u16,
) -> DispatchResult {
let maybe_owner = pallet_subtensor::Pallet::<T>::ensure_sn_owner_or_root_with_limits(
origin,
netuid,
&[Hyperparameter::MinChildkeyTake.into()],
)?;
pallet_subtensor::Pallet::<T>::ensure_admin_window_open(netuid)?;

ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Error::<T>::SubnetDoesNotExist
);
ensure!(
take >= pallet_subtensor::Pallet::<T>::get_min_childkey_take()
&& take <= pallet_subtensor::Pallet::<T>::get_max_childkey_take(),
Error::<T>::InvalidValue
);

pallet_subtensor::Pallet::<T>::set_min_childkey_take_for_subnet(netuid, take);
pallet_subtensor::Pallet::<T>::record_owner_rl(
maybe_owner,
netuid,
&[Hyperparameter::MinChildkeyTake.into()],
);
log::debug!(
"MinChildkeyTakePerSubnetSet( netuid: {netuid:?}, min_childkey_take: {take:?} ) "
);
Ok(())
}

/// The extrinsic enabled/disables commit/reaveal for a given subnet.
/// It is only callable by the root account or subnet owner.
/// The extrinsic will call the Subtensor pallet to set the value.
Expand Down
61 changes: 61 additions & 0 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,67 @@ fn test_sudo_set_min_delegate_take() {
});
}

#[test]
fn test_sudo_set_min_childkey_take_per_subnet() {
new_test_ext().execute_with(|| {
let netuid = NetUid::from(1);
let owner = U256::from(10);
let non_owner = U256::from(11);
let take = SubtensorModule::get_max_childkey_take() / 2;

add_network(netuid, 10);
SubnetOwner::<Test>::insert(netuid, owner);

assert_eq!(
AdminUtils::sudo_set_min_childkey_take_per_subnet(
<<Test as Config>::RuntimeOrigin>::signed(non_owner),
netuid,
take
),
Err(DispatchError::BadOrigin)
);

assert_ok!(AdminUtils::sudo_set_min_childkey_take_per_subnet(
<<Test as Config>::RuntimeOrigin>::signed(owner),
netuid,
take
));
assert_eq!(
SubtensorModule::get_min_childkey_take_for_subnet(netuid),
take
);
assert_eq!(
SubtensorModule::get_effective_min_childkey_take(netuid),
take
);
});
}

#[test]
fn test_sudo_set_min_childkey_take_per_subnet_rejects_below_global() {
new_test_ext().execute_with(|| {
let netuid = NetUid::from(1);
let global_min = 100;

add_network(netuid, 10);
SubtensorModule::set_min_childkey_take(global_min);

assert_noop!(
AdminUtils::sudo_set_min_childkey_take_per_subnet(
<<Test as Config>::RuntimeOrigin>::root(),
netuid,
global_min - 1
),
Error::<Test>::InvalidValue
);
assert_ok!(AdminUtils::sudo_set_min_childkey_take_per_subnet(
<<Test as Config>::RuntimeOrigin>::root(),
netuid,
global_min
));
});
}

#[test]
fn test_sudo_set_commit_reveal_weights_enabled() {
new_test_ext().execute_with(|| {
Expand Down
19 changes: 19 additions & 0 deletions pallets/admin-utils/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub trait WeightInfo {
fn sudo_set_nominator_min_required_stake() -> Weight;
fn sudo_set_tx_delegate_take_rate_limit() -> Weight;
fn sudo_set_min_delegate_take() -> Weight;
fn sudo_set_min_childkey_take_per_subnet() -> Weight;
fn sudo_set_liquid_alpha_enabled() -> Weight;
fn sudo_set_alpha_values() -> Weight;
fn sudo_set_coldkey_swap_announcement_delay() -> Weight;
Expand Down Expand Up @@ -641,6 +642,15 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
Weight::from_parts(5_410_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::MinChildkeyTake` (r:1 w:0)
/// Proof: `SubtensorModule::MinChildkeyTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `SubtensorModule::MinChildkeyTakePerSubnet` (r:0 w:1)
/// Proof: `SubtensorModule::MinChildkeyTakePerSubnet` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn sudo_set_min_childkey_take_per_subnet() -> Weight {
Weight::from_parts(6_000_000, 0)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::Tempo` (r:1 w:0)
/// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0)
Expand Down Expand Up @@ -1456,6 +1466,15 @@ impl WeightInfo for () {
Weight::from_parts(5_410_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::MinChildkeyTake` (r:1 w:0)
/// Proof: `SubtensorModule::MinChildkeyTake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `SubtensorModule::MinChildkeyTakePerSubnet` (r:0 w:1)
/// Proof: `SubtensorModule::MinChildkeyTakePerSubnet` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn sudo_set_min_childkey_take_per_subnet() -> Weight {
Weight::from_parts(6_000_000, 0)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::Tempo` (r:1 w:0)
/// Proof: `SubtensorModule::Tempo` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `SubtensorModule::AdminFreezeWindow` (r:1 w:0)
Expand Down
4 changes: 4 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,10 @@ pub mod pallet {
#[pallet::storage]
pub type MinChildkeyTake<T> = StorageValue<_, u16, ValueQuery, DefaultMinChildKeyTake<T>>;

/// MAP ( netuid ) --> take | Returns the subnet-specific minimum childkey take.
#[pallet::storage]
pub type MinChildkeyTakePerSubnet<T: Config> = StorageMap<_, Identity, NetUid, u16, ValueQuery>;

/// MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey
#[pallet::storage]
pub type Owner<T: Config> =
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ mod events {
OwnerHyperparamRateLimitSet(u16),
/// minimum childkey take set
MinChildKeyTakeSet(u16),
/// subnet-specific minimum childkey take set
MinChildKeyTakePerSubnetSet(NetUid, u16),
/// maximum childkey take set
MaxChildKeyTakeSet(u16),
/// childkey take set
Expand Down
5 changes: 3 additions & 2 deletions pallets/subtensor/src/staking/set_children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,8 @@ impl<T: Config> Pallet<T> {

// Ensure the take value is valid
ensure!(
take <= Self::get_max_childkey_take(),
take >= Self::get_effective_min_childkey_take(netuid)
&& take <= Self::get_max_childkey_take(),
Error::<T>::InvalidChildkeyTake
);

Expand Down Expand Up @@ -789,7 +790,7 @@ impl<T: Config> Pallet<T> {
/// - The childkey take value. This is a percentage represented as a value between 0
/// and 10000, where 10000 represents 100%.
pub fn get_childkey_take(hotkey: &T::AccountId, netuid: NetUid) -> u16 {
ChildkeyTake::<T>::get(hotkey, netuid)
ChildkeyTake::<T>::get(hotkey, netuid).max(Self::get_effective_min_childkey_take(netuid))
}

pub fn get_auto_parent_delegation_enabled(root_validator_hotkey: &T::AccountId) -> bool {
Expand Down
46 changes: 46 additions & 0 deletions pallets/subtensor/src/tests/children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,52 @@ fn test_childkey_take_functionality() {
});
}

#[test]
fn test_childkey_take_respects_effective_subnet_minimum() {
new_test_ext(1).execute_with(|| {
let coldkey = U256::from(1);
let hotkey = U256::from(2);
let netuid = NetUid::from(1);
let subnet_min = SubtensorModule::get_max_childkey_take() / 2;

add_network(netuid, 13, 0);
register_ok_neuron(netuid, hotkey, coldkey, 0);
SubtensorModule::set_min_childkey_take_for_subnet(netuid, subnet_min);

assert_eq!(
SubtensorModule::get_effective_min_childkey_take(netuid),
subnet_min
);
assert_eq!(
SubtensorModule::get_childkey_take(&hotkey, netuid),
subnet_min
);

assert_noop!(
SubtensorModule::set_childkey_take(
RuntimeOrigin::signed(coldkey),
hotkey,
netuid,
subnet_min - 1
),
Error::<Test>::InvalidChildkeyTake
);

assert_ok!(SubtensorModule::set_childkey_take(
RuntimeOrigin::signed(coldkey),
hotkey,
netuid,
subnet_min
));

ChildkeyTake::<Test>::insert(hotkey, netuid, subnet_min - 1);
assert_eq!(
SubtensorModule::get_childkey_take(&hotkey, netuid),
subnet_min
);
});
}

// 25: Test childkey take rate limiting
// This test verifies the rate limiting functionality for setting childkey take:
// - Sets up a network and registers a hotkey
Expand Down
10 changes: 10 additions & 0 deletions pallets/subtensor/src/utils/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,23 @@ impl<T: Config> Pallet<T> {
MinChildkeyTake::<T>::put(take);
Self::deposit_event(Event::MinChildKeyTakeSet(take));
}
pub fn set_min_childkey_take_for_subnet(netuid: NetUid, take: u16) {
MinChildkeyTakePerSubnet::<T>::insert(netuid, take);
Self::deposit_event(Event::MinChildKeyTakePerSubnetSet(netuid, take));
}
pub fn set_max_childkey_take(take: u16) {
MaxChildkeyTake::<T>::put(take);
Self::deposit_event(Event::MaxChildKeyTakeSet(take));
}
pub fn get_min_childkey_take() -> u16 {
MinChildkeyTake::<T>::get()
}
pub fn get_min_childkey_take_for_subnet(netuid: NetUid) -> u16 {
MinChildkeyTakePerSubnet::<T>::get(netuid)
}
pub fn get_effective_min_childkey_take(netuid: NetUid) -> u16 {
Self::get_min_childkey_take().max(Self::get_min_childkey_take_for_subnet(netuid))
}

pub fn get_max_childkey_take() -> u16 {
MaxChildkeyTake::<T>::get()
Expand Down
1 change: 1 addition & 0 deletions pallets/subtensor/src/utils/rate_limiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ pub enum Hyperparameter {
BurnHalfLife = 26,
BurnIncreaseMult = 27,
SubnetEmissionEnabled = 28,
MinChildkeyTake = 29,
}

impl<T: Config> Pallet<T> {
Expand Down
3 changes: 3 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,9 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
| RuntimeCall::AdminUtils(
pallet_admin_utils::Call::sudo_set_subnet_emission_enabled { .. }
)
| RuntimeCall::AdminUtils(
pallet_admin_utils::Call::sudo_set_min_childkey_take_per_subnet { .. }
)
),
ProxyType::RootClaim => matches!(
c,
Expand Down
Loading