Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 4 additions & 4 deletions eco-tests/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,9 @@ pub fn setup_neuron_with_stake(netuid: NetUid, hotkey: U256, coldkey: U256, stak
}

pub fn wait_set_pending_children_cooldown(netuid: NetUid) {
let cooldown = DefaultPendingCooldown::<Test>::get();
step_block(cooldown as u16); // Wait for cooldown to pass
let cooldown = u64::from(SubtensorModule::get_tempo(netuid))
.saturating_mul(u64::from(ChildKeyCooldownTempos::<Test>::get()));
run_to_block(System::block_number().saturating_add(cooldown));
step_epochs(1, netuid); // Run next epoch
}

Expand Down Expand Up @@ -276,8 +277,7 @@ pub fn mock_set_children_no_epochs(netuid: NetUid, parent: &U256, child_vec: &[(
let backup_block = SubtensorModule::get_current_block_as_u64();
PendingChildKeys::<Test>::insert(netuid, parent, (child_vec, 0));
FirstEmissionBlockNumber::<Test>::insert(netuid, 0);
let cooldown = PendingChildKeyCooldown::<Test>::get();
System::set_block_number(cooldown + 1);
System::set_block_number(1);
SubtensorModule::do_set_pending_children(netuid);
System::set_block_number(backup_block);
}
Expand Down
4 changes: 3 additions & 1 deletion eco-tests/src/tests_mentat_indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ fn indexer_root_claim_type() {
}

#[test]
fn indexer_pending_childkey_cooldown() {
fn indexer_childkey_cooldown_tempos() {
new_test_ext(1).execute_with(|| {
#[allow(deprecated)]
let _: u64 = PendingChildKeyCooldown::<Test>::get();
let _: u16 = ChildKeyCooldownTempos::<Test>::get();
});
}

Expand Down
10 changes: 10 additions & 0 deletions pallets/admin-utils/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,16 @@ mod benchmarks {
_(RawOrigin::Root, u64::MAX);
}

#[benchmark]
fn sudo_set_childkey_cooldown_tempos() {
let tempos = 2u16;

#[extrinsic_call]
_(RawOrigin::Root, tempos);

assert_eq!(pallet_subtensor::ChildKeyCooldownTempos::<T>::get(), tempos);
}

#[benchmark]
fn sudo_set_burn_half_life() {
let netuid = NetUid::from(1);
Expand Down
20 changes: 20 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ pub mod pallet {
/// Indicates if the Bonds Reset was enabled or disabled.
enabled: bool,
},
/// Event emitted when the childkey activation cooldown is set.
ChildKeyCooldownTemposSet {
/// The new cooldown, measured in subnet tempos.
tempos: u16,
},
/// Event emitted when the burn half-life parameter is set for a subnet.
BurnHalfLifeSet {
/// The network identifier.
Expand Down Expand Up @@ -2413,6 +2418,21 @@ pub mod pallet {

Ok(())
}

/// Sets the childkey activation cooldown as a number of subnet tempos.
/// Only callable by root.
#[pallet::call_index(102)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::sudo_set_childkey_cooldown_tempos())]
pub fn sudo_set_childkey_cooldown_tempos(
origin: OriginFor<T>,
tempos: u16,
) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_childkey_cooldown_tempos(tempos);
Self::deposit_event(Event::ChildKeyCooldownTemposSet { tempos });
log::debug!("ChildKeyCooldownTemposSet( tempos: {tempos:?} ) ");
Ok(())
}
}
}

Expand Down
24 changes: 24 additions & 0 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3383,3 +3383,27 @@ fn test_sudo_set_start_call_delay_permissions_and_zero_delay() {
);
});
}

#[test]
fn test_sudo_set_childkey_cooldown_tempos() {
new_test_ext().execute_with(|| {
assert_eq!(pallet_subtensor::ChildKeyCooldownTempos::<Test>::get(), 2);

assert_noop!(
AdminUtils::sudo_set_childkey_cooldown_tempos(
<<Test as Config>::RuntimeOrigin>::signed(U256::from(1)),
3,
),
DispatchError::BadOrigin
);

assert_ok!(AdminUtils::sudo_set_childkey_cooldown_tempos(
<<Test as Config>::RuntimeOrigin>::root(),
3,
));
assert_eq!(pallet_subtensor::ChildKeyCooldownTempos::<Test>::get(), 3);
frame_system::Pallet::<Test>::assert_last_event(RuntimeEvent::AdminUtils(
crate::Event::ChildKeyCooldownTemposSet { tempos: 3 },
));
});
}
13 changes: 13 additions & 0 deletions pallets/admin-utils/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub trait WeightInfo {
fn sudo_set_net_tao_flow_enabled() -> Weight;
fn sudo_set_max_mechanism_count() -> Weight;
fn sudo_set_start_call_delay() -> Weight;
fn sudo_set_childkey_cooldown_tempos() -> Weight;
fn sudo_set_burn_half_life() -> Weight;
fn sudo_set_burn_increase_mult() -> Weight;
fn sudo_set_owner_cut_enabled() -> Weight;
Expand Down Expand Up @@ -1039,6 +1040,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
Weight::from_parts(5_831_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::ChildKeyCooldownTempos` (r:0 w:1)
/// Proof: `SubtensorModule::ChildKeyCooldownTempos` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn sudo_set_childkey_cooldown_tempos() -> Weight {
Weight::from_parts(5_731_000, 0)
.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::PendingEpochAt` (r:1 w:0)
Expand Down Expand Up @@ -2412,6 +2419,12 @@ impl WeightInfo for () {
Weight::from_parts(5_831_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `SubtensorModule::ChildKeyCooldownTempos` (r:0 w:1)
/// Proof: `SubtensorModule::ChildKeyCooldownTempos` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn sudo_set_childkey_cooldown_tempos() -> Weight {
Weight::from_parts(5_731_000, 0)
.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::PendingEpochAt` (r:1 w:0)
Expand Down
21 changes: 17 additions & 4 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,12 +1111,18 @@ pub mod pallet {
T::InitialColdkeySwapReannouncementDelay::get()
}

/// Default value for applying pending items (e.g. childkeys).
/// Deprecated block-based default for applying pending childkeys.
#[pallet::type_value]
pub fn DefaultPendingCooldown<T: Config>() -> u64 {
prod_or_fast!(7_200, 15)
}

/// Default childkey cooldown, measured in subnet tempos.
#[pallet::type_value]
pub fn DefaultChildKeyCooldownTempos<T: Config>() -> u16 {
2
}

/// Default minimum stake.
#[pallet::type_value]
pub fn DefaultMinStake<T: Config>() -> TaoBalance {
Expand Down Expand Up @@ -2979,18 +2985,25 @@ pub mod pallet {
#[pallet::storage]
pub type HasMigrationRun<T: Config> = StorageMap<_, Identity, Vec<u8>, bool, ValueQuery>;

/// Default value for pending childkey cooldown (settable by root).
/// Uses the same value as DefaultPendingCooldown for consistency.
/// Deprecated block-based pending childkey cooldown default.
///
/// Use [`DefaultChildKeyCooldownTempos`] instead.
#[pallet::type_value]
pub fn DefaultPendingChildKeyCooldown<T: Config>() -> u64 {
DefaultPendingCooldown::<T>::get()
}

/// Storage value for pending childkey cooldown, settable by root.
/// Deprecated block-based childkey cooldown retained for storage compatibility.
#[deprecated(note = "Use `ChildKeyCooldownTempos` instead")]
#[pallet::storage]
pub type PendingChildKeyCooldown<T: Config> =
StorageValue<_, u64, ValueQuery, DefaultPendingChildKeyCooldown<T>>;

/// Number of subnet tempos before a pending childkey update can be applied.
#[pallet::storage]
pub type ChildKeyCooldownTempos<T: Config> =
StorageValue<_, u16, ValueQuery, DefaultChildKeyCooldownTempos<T>>;

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
/// Stakes record in genesis.
Expand Down
6 changes: 5 additions & 1 deletion pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,14 +1630,18 @@ mod dispatches {
Self::do_burn_alpha(origin, hotkey, amount, netuid).map(|_| ())
}

/// Sets the pending childkey cooldown (in blocks). Root only.
/// Deprecated block-based setting retained for call-index and storage compatibility.
/// This setting no longer controls childkey activation.
/// Use `AdminUtils::sudo_set_childkey_cooldown_tempos` instead.
#[deprecated(note = "Use `AdminUtils::sudo_set_childkey_cooldown_tempos` instead")]
#[pallet::call_index(109)]
#[pallet::weight(<T as crate::pallet::Config>::WeightInfo::set_pending_childkey_cooldown())]
pub fn set_pending_childkey_cooldown(
origin: OriginFor<T>,
cooldown: u64,
) -> DispatchResult {
ensure_root(origin)?;
#[allow(deprecated)]
PendingChildKeyCooldown::<T>::put(cooldown);
Ok(())
}
Expand Down
9 changes: 5 additions & 4 deletions pallets/subtensor/src/staking/set_children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,9 +558,10 @@ impl<T: Config> Pallet<T> {
return Ok(());
}

// Calculate cool-down block
let cooldown_block =
Self::get_current_block_as_u64().saturating_add(PendingChildKeyCooldown::<T>::get());
// Calculate the cooldown from this subnet's tempo.
let cooldown = u64::from(Self::get_tempo(netuid))
.saturating_mul(u64::from(ChildKeyCooldownTempos::<T>::get()));
let cooldown_block = Self::get_current_block_as_u64().saturating_add(cooldown);
Comment thread
UnArbosSix marked this conversation as resolved.
Outdated

// Insert or update PendingChildKeys
PendingChildKeys::<T>::insert(netuid, hotkey.clone(), (children.clone(), cooldown_block));
Expand Down Expand Up @@ -604,7 +605,7 @@ impl<T: Config> Pallet<T> {
pub fn do_set_pending_children(netuid: NetUid) {
let current_block = Self::get_current_block_as_u64();

// If the childkey cools down before the subnet start call + PendingChildKeyCooldown:
// If the childkey cools down before the subnet start call + configured cooldown:
// - If Start call happened: Normal track
// - If Start call didn't happen: Apply immediately
// TODO: This check may be removed after all ck are applied after the runtime upgrade
Expand Down
42 changes: 19 additions & 23 deletions pallets/subtensor/src/tests/children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4088,8 +4088,6 @@ fn test_dividend_distribution_with_children_same_coldkey_owner() {
#[test]
fn test_pending_cooldown_as_expected() {
let curr_block = 1;
// TODO: Fix when CHK splitting patched
// let expected_cooldown = prod_or_fast!(7200, 15);

new_test_ext(curr_block).execute_with(|| {
let coldkey = U256::from(1);
Expand All @@ -4099,10 +4097,11 @@ fn test_pending_cooldown_as_expected() {
let netuid = NetUid::from(1);
let proportion1: u64 = 1000;
let proportion2: u64 = 2000;
let expected_cooldown = PendingChildKeyCooldown::<Test>::get();
let tempo = 13;
let expected_cooldown = u64::from(tempo) * u64::from(ChildKeyCooldownTempos::<Test>::get());

// Add network and register hotkey
add_network(netuid, 13, 0);
add_network(netuid, tempo, 0);
register_ok_neuron(netuid, hotkey, coldkey, 0);

// Set multiple children
Expand All @@ -4123,6 +4122,19 @@ fn test_pending_cooldown_as_expected() {
});
}

#[test]
#[allow(deprecated)]
fn test_deprecated_pending_childkey_cooldown_is_retained() {
new_test_ext(1).execute_with(|| {
assert_ok!(SubtensorModule::set_pending_childkey_cooldown(
RuntimeOrigin::root(),
1,
));

assert_eq!(PendingChildKeyCooldown::<Test>::get(), 1);
});
}

#[test]
fn test_do_set_childkey_take_success() {
new_test_ext(1).execute_with(|| {
Expand Down Expand Up @@ -4419,15 +4431,11 @@ fn test_root_children_enable_subnet_owner_set_weights() {
));

// --- Verify do_set_root_validators_for_subnet creates parent-child relationships ---
assert_ok!(SubtensorModule::set_pending_childkey_cooldown(
RuntimeOrigin::root(),
0,
));

assert_ok!(SubtensorModule::do_set_root_validators_for_subnet(netuid));

// Activate pending children (cooldown is 0, advance 1 block)
step_block(1);
// Activate pending children after the two-tempo cooldown.
let cooldown_block = PendingChildKeys::<Test>::get(netuid, root_val_hotkey_1).1;
run_to_block(cooldown_block.saturating_add(1));
SubtensorModule::do_set_pending_children(netuid);

// Each root validator should have the subnet owner hotkey as a child on netuid
Expand Down Expand Up @@ -4496,12 +4504,6 @@ fn test_register_network_schedules_root_validators() {
root_stake,
);

// --- Minimize cooldown so pending children activate quickly ---
assert_ok!(SubtensorModule::set_pending_childkey_cooldown(
RuntimeOrigin::root(),
0,
));

// --- Set a high stake threshold ---
let high_threshold = 500_000_000u64;
SubtensorModule::set_stake_threshold(high_threshold);
Expand Down Expand Up @@ -4619,12 +4621,6 @@ fn test_register_network_schedules_root_validators_auto_parent_delegation_flag()
root_stake,
);

// --- Minimize cooldown so pending children activate quickly ---
assert_ok!(SubtensorModule::set_pending_childkey_cooldown(
RuntimeOrigin::root(),
0,
));

// --- Set a high stake threshold ---
let high_threshold = 500_000_000u64;
SubtensorModule::set_stake_threshold(high_threshold);
Expand Down
8 changes: 4 additions & 4 deletions pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,8 +985,9 @@ pub fn setup_neuron_with_stake(netuid: NetUid, hotkey: U256, coldkey: U256, stak

#[allow(dead_code)]
pub fn wait_set_pending_children_cooldown(netuid: NetUid) {
let cooldown = DefaultPendingCooldown::<Test>::get();
step_block(cooldown as u16); // Wait for cooldown to pass
let cooldown = u64::from(SubtensorModule::get_tempo(netuid))
.saturating_mul(u64::from(ChildKeyCooldownTempos::<Test>::get()));
run_to_block(System::block_number().saturating_add(cooldown));
step_epochs(1, netuid); // Run next epoch
}

Expand Down Expand Up @@ -1028,8 +1029,7 @@ pub fn mock_set_children_no_epochs(netuid: NetUid, parent: &U256, child_vec: &[(
let backup_block = SubtensorModule::get_current_block_as_u64();
PendingChildKeys::<Test>::insert(netuid, parent, (child_vec, 0));
FirstEmissionBlockNumber::<Test>::insert(netuid, 0);
let cooldown = PendingChildKeyCooldown::<Test>::get();
System::set_block_number(cooldown + 1);
System::set_block_number(1);
SubtensorModule::do_set_pending_children(netuid);
System::set_block_number(backup_block);
}
Expand Down
5 changes: 5 additions & 0 deletions pallets/subtensor/src/utils/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ impl<T: Config> Pallet<T> {
Self::deposit_event(Event::OwnerHyperparamRateLimitSet(epochs));
}

/// Set the number of subnet tempos before a pending childkey update can activate.
pub fn set_childkey_cooldown_tempos(tempos: u16) {
ChildKeyCooldownTempos::<T>::set(tempos);
}

/// If owner is `Some`, record last-blocks for the provided `TransactionType`s.
pub fn record_owner_rl(
maybe_owner: Option<<T as frame_system::Config>::AccountId>,
Expand Down
Loading
Loading