Skip to content
Draft
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
2 changes: 2 additions & 0 deletions chain-extensions/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ parameter_types! {
pub const InitialYuma3On: bool = false; // Default value for Yuma3On
// pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialDeregistrationPriorityScheduleDelay: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // Default as 1 day
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialTaoWeight: u64 = 0; // 100% global weight.
Expand Down Expand Up @@ -398,6 +399,7 @@ impl pallet_subtensor::Config for Test {
type Yuma3On = InitialYuma3On;
type Preimages = Preimage;
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialDeregistrationPriorityScheduleDelay = InitialDeregistrationPriorityScheduleDelay;
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
Expand Down
6 changes: 6 additions & 0 deletions pallets/admin-utils/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,12 @@ mod benchmarks {
_(RawOrigin::Root, 100u32.into());
}

#[benchmark]
fn sudo_set_deregistration_priority_schedule_delay() {
#[extrinsic_call]
_(RawOrigin::Root, 100u32.into());
}

#[benchmark]
fn sudo_set_dissolve_network_schedule_duration() {
#[extrinsic_call]
Expand Down
22 changes: 21 additions & 1 deletion pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,26 @@ pub mod pallet {
Ok(())
}

/// Sets the delay for deregistration priority scheduling.
#[pallet::call_index(55)]
#[pallet::weight((
Weight::from_parts(5_000_000, 0)
.saturating_add(T::DbWeight::get().reads(0_u64))
.saturating_add(T::DbWeight::get().writes(1_u64)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn sudo_set_deregistration_priority_schedule_delay(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_deregistration_priority_schedule_delay(duration);
log::trace!("DeregistrationPriorityScheduleDelaySet( duration: {duration:?} )");

Ok(())
}

/// Sets the duration of the dissolve network schedule.
///
/// This extrinsic allows the root account to set the duration for the dissolve network schedule.
Expand All @@ -1400,7 +1420,7 @@ pub mod pallet {
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(55)]
#[pallet::call_index(56)]
#[pallet::weight((
Weight::from_parts(5_000_000, 0)
.saturating_add(T::DbWeight::get().reads(0_u64))
Expand Down
2 changes: 2 additions & 0 deletions pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ parameter_types! {
// pub const InitialHotkeyEmissionTempo: u64 = 1; // (DEPRECATED)
// pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialDeregistrationPriorityScheduleDelay: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // 1 day
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight.
Expand Down Expand Up @@ -211,6 +212,7 @@ impl pallet_subtensor::Config for Test {
type Yuma3On = InitialYuma3On;
type Preimages = ();
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialDeregistrationPriorityScheduleDelay = InitialDeregistrationPriorityScheduleDelay;
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
Expand Down
33 changes: 33 additions & 0 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,39 @@ fn test_sudo_set_coldkey_swap_schedule_duration() {
});
}

#[test]
fn test_sudo_set_deregistration_priority_schedule_delay() {
new_test_ext().execute_with(|| {
let root = RuntimeOrigin::root();
let non_root = RuntimeOrigin::signed(U256::from(1));
let new_duration = 150u32.into();

assert_noop!(
AdminUtils::sudo_set_deregistration_priority_schedule_delay(non_root, new_duration),
DispatchError::BadOrigin
);

assert_ok!(AdminUtils::sudo_set_deregistration_priority_schedule_delay(
root.clone(),
new_duration
));

assert_eq!(
pallet_subtensor::DeregistrationPriorityScheduleDelay::<Test>::get(),
new_duration
);

System::assert_last_event(
Event::DeregistrationPriorityScheduleDelaySet(new_duration).into(),
);

assert_ok!(AdminUtils::sudo_set_deregistration_priority_schedule_delay(
root,
new_duration
));
});
}

#[test]
fn test_sudo_set_dissolve_network_schedule_duration() {
new_test_ext().execute_with(|| {
Expand Down
9 changes: 7 additions & 2 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ impl<T: Config> Pallet<T> {

// --- 5. Remove various network-related storages.
NetworkRegisteredAt::<T>::remove(netuid);
let _ = Self::remove_subnet_from_deregistration_priority_queue(netuid);

// --- 6. Remove incentive mechanism memory.
let _ = Uids::<T>::clear_prefix(netuid, u32::MAX, None);
Expand Down Expand Up @@ -592,6 +593,10 @@ impl<T: Config> Pallet<T> {
pub fn get_network_to_prune() -> Option<NetUid> {
let current_block: u64 = Self::get_current_block_as_u64();

if let Some(priority_netuid) = Self::pop_ready_subnet_from_deregistration_priority_queue() {
return Some(priority_netuid);
}

let mut candidate_netuid: Option<NetUid> = None;
let mut candidate_price: U96F32 = U96F32::saturating_from_num(u128::MAX);
let mut candidate_timestamp: u64 = u64::MAX;
Expand All @@ -610,8 +615,8 @@ impl<T: Config> Pallet<T> {

let price: U96F32 = Self::get_moving_alpha_price(netuid);

// If tie on price, earliest registration wins.
if price < candidate_price
if candidate_netuid.is_none()
|| price < candidate_price
|| (price == candidate_price && registered_at < candidate_timestamp)
{
candidate_netuid = Some(netuid);
Expand Down
25 changes: 25 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,12 @@ pub mod pallet {
T::InitialColdkeySwapScheduleDuration::get()
}

/// Default value for deregistration priority schedule delay
#[pallet::type_value]
pub fn DefaultDeregistrationPriorityScheduleDelay<T: Config>() -> BlockNumberFor<T> {
T::InitialDeregistrationPriorityScheduleDelay::get()
}

/// Default value for coldkey swap reschedule duration
#[pallet::type_value]
pub fn DefaultColdkeySwapRescheduleDuration<T: Config>() -> BlockNumberFor<T> {
Expand Down Expand Up @@ -1605,6 +1611,25 @@ pub mod pallet {
pub type NetworkRegisteredAt<T: Config> =
StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultNetworkRegisteredAt<T>>;

/// --- FIFO queue of netuids pending deregistration
#[pallet::storage]
pub type SubnetDeregistrationPriorityQueue<T: Config> =
StorageValue<_, sp_std::vec::Vec<NetUid>, ValueQuery>;

/// --- MAP ( netuid ) --> scheduled block for enqueuing deregistration priority
#[pallet::storage]
pub type SubnetDeregistrationPrioritySchedule<T: Config> =
StorageMap<_, Identity, NetUid, BlockNumberFor<T>, OptionQuery>;

/// --- Global delay for scheduled deregistration priority activations
#[pallet::storage]
pub type DeregistrationPriorityScheduleDelay<T: Config> = StorageValue<
_,
BlockNumberFor<T>,
ValueQuery,
DefaultDeregistrationPriorityScheduleDelay<T>,
>;

/// --- MAP ( netuid ) --> pending_server_emission
#[pallet::storage]
pub type PendingServerEmission<T> =
Expand Down
3 changes: 3 additions & 0 deletions pallets/subtensor/src/macros/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ mod config {
/// Coldkey swap schedule duartion.
#[pallet::constant]
type InitialColdkeySwapScheduleDuration: Get<BlockNumberFor<Self>>;
/// Deregistration priority schedule delay.
#[pallet::constant]
type InitialDeregistrationPriorityScheduleDelay: Get<BlockNumberFor<Self>>;
/// Coldkey swap reschedule duration.
#[pallet::constant]
type InitialColdkeySwapRescheduleDuration: Get<BlockNumberFor<Self>>;
Expand Down
134 changes: 134 additions & 0 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,7 @@ mod dispatches {
.map_err(|_| Error::<T>::FailedToSchedule)?;

ColdkeySwapScheduled::<T>::insert(&who, (when, new_coldkey.clone()));
Self::cancel_deregistration_priority_schedule_for_owner(&who);
// Emit the SwapScheduled event
Self::deposit_event(Event::ColdkeySwapScheduled {
old_coldkey: who.clone(),
Expand Down Expand Up @@ -2152,6 +2153,139 @@ mod dispatches {
Ok(())
}

/// Schedules the subnet to be appended to the deregistration priority queue.
///
/// Accessible by the subnet owner or root origin.
///
/// # Errors
/// * [`Error::SubnetNotExists`] if the subnet does not exist.
/// * [`Error::SubnetDeregistrationPriorityAlreadyScheduled`] if a set operation is already
/// scheduled.
#[pallet::call_index(125)]
#[pallet::weight((
Weight::from_parts(40_000_000, 0)
.saturating_add(T::DbWeight::get().reads_writes(4, 2)),
DispatchClass::Normal,
Pays::Yes
))]
pub fn schedule_deregistration_priority(
origin: OriginFor<T>,
netuid: NetUid,
) -> DispatchResult {
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);
Self::ensure_subnet_owner_or_root(origin, netuid)?;

ensure!(
SubnetDeregistrationPrioritySchedule::<T>::get(netuid).is_none(),
Error::<T>::SubnetDeregistrationPriorityAlreadyScheduled
);

let current_block: BlockNumberFor<T> = <frame_system::Pallet<T>>::block_number();
let delay: BlockNumberFor<T> = DeregistrationPriorityScheduleDelay::<T>::get();
let when: BlockNumberFor<T> = current_block.saturating_add(delay);

let call = Call::<T>::enqueue_subnet_deregistration { netuid };
let bound_call = <T as Config>::Preimages::bound(LocalCallOf::<T>::from(call))
.map_err(|_| Error::<T>::FailedToSchedule)?;

T::Scheduler::schedule(
DispatchTime::At(when),
None,
63,
frame_system::RawOrigin::Root.into(),
bound_call,
)
.map_err(|_| Error::<T>::FailedToSchedule)?;

SubnetDeregistrationPrioritySchedule::<T>::insert(netuid, when);
Self::deposit_event(Event::SubnetDeregistrationPriorityScheduleAdded(
netuid, when,
));

Ok(())
}

/// Enqueues the subnet for deregistration immediately.
///
/// This call is intended to be used by the scheduler and requires root origin.
#[pallet::call_index(126)]
#[pallet::weight((
Weight::from_parts(15_000_000, 0)
.saturating_add(T::DbWeight::get().reads_writes(3, 2)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn enqueue_subnet_deregistration(
origin: OriginFor<T>,
netuid: NetUid,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);

if SubnetDeregistrationPrioritySchedule::<T>::take(netuid).is_some() {
Self::deposit_event(Event::SubnetDeregistrationPriorityScheduleRemoved(netuid));
}

Self::enqueue_subnet_to_deregistration_priority_queue(netuid);
Self::deposit_event(Event::SubnetDeregistrationPriorityQueueAdded(netuid));

Ok(())
}

/// Cancels a pending deregistration priority schedule.
///
/// Accessible by the subnet owner or root origin.
#[pallet::call_index(127)]
#[pallet::weight((
Weight::from_parts(20_000_000, 0)
.saturating_add(T::DbWeight::get().reads_writes(2, 1)),
DispatchClass::Normal,
Pays::Yes
))]
pub fn cancel_deregistration_priority_schedules(
origin: OriginFor<T>,
netuid: NetUid,
) -> DispatchResult {
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);
Self::ensure_subnet_owner_or_root(origin, netuid)?;

if SubnetDeregistrationPrioritySchedule::<T>::take(netuid).is_some() {
Self::deposit_event(Event::SubnetDeregistrationPriorityScheduleRemoved(netuid));
}

Ok(())
}

/// Clears any deregistration priority queue entry and pending schedule for a subnet.
///
/// Only callable by root origin.
#[pallet::call_index(128)]
#[pallet::weight((
Weight::from_parts(20_000_000, 0)
.saturating_add(T::DbWeight::get().reads_writes(2, 2)),
DispatchClass::Normal,
Pays::Yes
))]
pub fn clear_deregistration_priority(
origin: OriginFor<T>,
netuid: NetUid,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);

let was_queued = Self::remove_subnet_from_deregistration_priority_queue(netuid);
let had_schedule = SubnetDeregistrationPrioritySchedule::<T>::take(netuid).is_some();

if was_queued {
Self::deposit_event(Event::SubnetDeregistrationPriorityQueueRemoved(netuid));
}
if had_schedule {
Self::deposit_event(Event::SubnetDeregistrationPriorityScheduleRemoved(netuid));
}

Ok(())
}

/// ---- Used to commit timelock encrypted commit-reveal weight values to later be revealed.
///
/// # Args:
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/macros/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ mod errors {
TxRateLimitExceeded,
/// Swap already scheduled.
SwapAlreadyScheduled,
/// Deregistration priority already scheduled.
SubnetDeregistrationPriorityAlreadyScheduled,
/// failed to swap coldkey
FailedToSchedule,
/// New coldkey is hotkey
Expand Down
10 changes: 10 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ mod events {
NetworkAdded(NetUid, u16),
/// a network is removed.
NetworkRemoved(NetUid),
/// a subnet's deregistration queue entry was scheduled.
SubnetDeregistrationPriorityScheduleAdded(NetUid, BlockNumberFor<T>),
/// a subnet was enqueued for deregistration.
SubnetDeregistrationPriorityQueueAdded(NetUid),
/// network deregistration queue entry cleared or canceled.
SubnetDeregistrationPriorityQueueRemoved(NetUid),
/// pending deregistration schedule cleared or canceled.
SubnetDeregistrationPriorityScheduleRemoved(NetUid),
/// deregistration priority schedule delay updated.
DeregistrationPriorityScheduleDelaySet(BlockNumberFor<T>),
/// stake has been transferred from the a coldkey account onto the hotkey staking account.
StakeAdded(
T::AccountId,
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ parameter_types! {
pub const InitialYuma3On: bool = false; // Default value for Yuma3On
// pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialDeregistrationPriorityScheduleDelay: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // Default as 1 day
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialTaoWeight: u64 = 0; // 100% global weight.
Expand Down Expand Up @@ -285,6 +286,7 @@ impl crate::Config for Test {
type Yuma3On = InitialYuma3On;
type Preimages = Preimage;
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialDeregistrationPriorityScheduleDelay = InitialDeregistrationPriorityScheduleDelay;
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
Expand Down
Loading
Loading