Skip to content

Commit

Permalink
Merge pull request #475 from opentensor/backport/dev_no_registration_…
Browse files Browse the repository at this point in the history
…no_emission

Backport/dev no registration no emission
  • Loading branch information
distributedstatemachine committed May 29, 2024
2 parents 396b035 + bb73abf commit 8b91ed4
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 266 deletions.
102 changes: 0 additions & 102 deletions .github/workflows/publish-tag.yml

This file was deleted.

2 changes: 1 addition & 1 deletion pallets/admin-utils/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ parameter_types! {
pub const InitialStakePruningMin: u16 = 0;
pub const InitialFoundationDistribution: u64 = 0;
pub const InitialDefaultTake: u16 = 11_796; // 18% honest number.
pub const InitialMinTake: u16 = 0;
pub const InitialMinTake: u16 = 5_898; // 9%;
pub const InitialWeightsVersionKey: u16 = 0;
pub const InitialServingRateLimit: u64 = 0; // No limit.
pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing
Expand Down
4 changes: 2 additions & 2 deletions pallets/admin-utils/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ mod sudo_set_nominator_min_required_stake {
assert_ok!(SubtensorModule::do_become_delegate(
<<Test as Config>::RuntimeOrigin>::signed(cold1),
hot1,
0
u16::MAX / 10
));
assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hot1), cold1);

Expand All @@ -954,7 +954,7 @@ mod sudo_set_nominator_min_required_stake {
assert_ok!(SubtensorModule::do_become_delegate(
<<Test as Config>::RuntimeOrigin>::signed(cold2),
hot2,
0
u16::MAX / 10
));
assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hot2), cold2);

Expand Down
6 changes: 3 additions & 3 deletions pallets/subtensor/src/block_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ impl<T: Config> Pallet<T> {
pub fn generate_emission(block_number: u64) {
// --- 1. Iterate across each network and add pending emission into stash.
for (netuid, tempo) in <Tempo<T> as IterableStorageMap<u16, u16>>::iter() {
// Skip the root network.
if netuid == Self::get_root_netuid() {
// Root emission is burned.
// Skip the root network or subnets with registrations turned off
if netuid == Self::get_root_netuid() || !Self::is_registration_allowed(netuid) {
// Root emission or subnet emission is burned
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2226,7 +2226,7 @@ where
Pallet::<T>::get_registrations_this_interval(*netuid);
let max_registrations_per_interval =
Pallet::<T>::get_target_registrations_per_interval(*netuid);
if registrations_this_interval >= max_registrations_per_interval {
if registrations_this_interval >= (max_registrations_per_interval * 3) {
// If the registration limit for the interval is exceeded, reject the transaction
return InvalidTransaction::ExhaustsResources.into();
}
Expand Down
18 changes: 18 additions & 0 deletions pallets/subtensor/src/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,24 @@ impl<T: Config> Pallet<T> {
Self::deposit_event(Event::NetworkRateLimitSet(limit));
}

/// Checks if registrations are allowed for a given subnet.
///
/// This function retrieves the subnet hyperparameters for the specified subnet and checks the `registration_allowed` flag.
/// If the subnet doesn't exist or doesn't have hyperparameters defined, it returns `false`.
///
/// # Arguments
///
/// * `netuid` - The unique identifier of the subnet.
///
/// # Returns
///
/// * `bool` - `true` if registrations are allowed for the subnet, `false` otherwise.
pub fn is_registration_allowed(netuid: u16) -> bool {
Self::get_subnet_hyperparams(netuid)
.map(|params| params.registration_allowed)
.unwrap_or(false)
}

/// Computes and sets emission values for the root network which determine the emission for all subnets.
///
/// This function is responsible for calculating emission based on network weights, stake values,
Expand Down
35 changes: 17 additions & 18 deletions pallets/subtensor/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,26 +432,18 @@ impl<T: Config> Pallet<T> {
Error::<T>::UnstakeRateLimitExceeded
);

// If this is a nomination stake, check if total stake after removing will be above
// the minimum required stake.

// If coldkey is not owner of the hotkey, it's a nomination stake.
if !Self::coldkey_owns_hotkey(&coldkey, &hotkey) {
let total_stake_after_remove =
Stake::<T>::get(&hotkey, &coldkey).saturating_sub(stake_to_be_removed);

ensure!(
total_stake_after_remove >= NominatorMinRequiredStake::<T>::get(),
Error::<T>::NomStakeBelowMinimumThreshold
);
}

// We remove the balance from the hotkey.
Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake_to_be_removed);

// We add the balancer to the coldkey. If the above fails we will not credit this coldkey.
// We add the balance to the coldkey. If the above fails we will not credit this coldkey.
Self::add_balance_to_coldkey_account(&coldkey, stake_to_be_removed);

// If the stake is below the minimum, we clear the nomination from storage.
// This only applies to nominator stakes.
// If the coldkey does not own the hotkey, it's a nominator stake.
let new_stake = Self::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey);
Self::clear_small_nomination_if_required(&hotkey, &coldkey, new_stake);

// Set last block for rate limiting
let block: u64 = Self::get_current_block_as_u64();
Self::set_last_tx_block(&coldkey, block);
Expand Down Expand Up @@ -675,17 +667,24 @@ impl<T: Config> Pallet<T> {
/// It also removes the stake entry for the hotkey-coldkey pairing and adjusts the TotalStake
/// and TotalIssuance by subtracting the removed stake amount.
///
/// Returns the amount of stake that was removed.
///
/// # Arguments
///
/// * `coldkey` - A reference to the AccountId of the coldkey involved in the staking.
/// * `hotkey` - A reference to the AccountId of the hotkey associated with the coldkey.
pub fn empty_stake_on_coldkey_hotkey_account(coldkey: &T::AccountId, hotkey: &T::AccountId) {
pub fn empty_stake_on_coldkey_hotkey_account(
coldkey: &T::AccountId,
hotkey: &T::AccountId,
) -> u64 {
let current_stake: u64 = Stake::<T>::get(hotkey, coldkey);
TotalColdkeyStake::<T>::mutate(coldkey, |old| *old = old.saturating_sub(current_stake));
TotalHotkeyStake::<T>::mutate(hotkey, |stake| *stake = stake.saturating_sub(current_stake));
Stake::<T>::remove(hotkey, coldkey);
TotalStake::<T>::mutate(|stake| *stake = stake.saturating_sub(current_stake));
TotalIssuance::<T>::mutate(|issuance| *issuance = issuance.saturating_sub(current_stake));

current_stake
}

/// Clears the nomination for an account, if it is a nominator account and the stake is below the minimum required threshold.
Expand All @@ -700,9 +699,9 @@ impl<T: Config> Pallet<T> {
if stake < Self::get_nominator_min_required_stake() {
// Remove the stake from the nominator account. (this is a more forceful unstake operation which )
// Actually deletes the staking account.
Self::empty_stake_on_coldkey_hotkey_account(coldkey, hotkey);
let cleared_stake = Self::empty_stake_on_coldkey_hotkey_account(coldkey, hotkey);
// Add the stake to the coldkey account.
Self::add_balance_to_coldkey_account(coldkey, stake);
Self::add_balance_to_coldkey_account(coldkey, cleared_stake);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/subnet_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct SubnetHyperparams {
weights_rate_limit: Compact<u64>,
adjustment_interval: Compact<u16>,
activity_cutoff: Compact<u16>,
registration_allowed: bool,
pub registration_allowed: bool,
target_regs_per_interval: Compact<u16>,
min_burn: Compact<u64>,
max_burn: Compact<u64>,
Expand Down
67 changes: 67 additions & 0 deletions pallets/subtensor/tests/block_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,3 +803,70 @@ fn test_burn_adjustment_case_e_zero_registrations() {
assert_eq!(adjusted_diff, 5_000);
});
}

#[test]
fn test_emission_based_on_registration_status() {
new_test_ext(1).execute_with(|| {
let n: u16 = 100;
let netuid_off: u16 = 1;
let netuid_on: u16 = 2;
let tempo: u16 = 1;
let netuids: Vec<u16> = vec![netuid_off, netuid_on];
let emissions: Vec<u64> = vec![1000000000, 1000000000];

// Add subnets with registration turned off and on
add_network(netuid_off, tempo, 0);
add_network(netuid_on, tempo, 0);
SubtensorModule::set_max_allowed_uids(netuid_off, n);
SubtensorModule::set_max_allowed_uids(netuid_on, n);
SubtensorModule::set_emission_values(&netuids, emissions).unwrap();
SubtensorModule::set_network_registration_allowed(netuid_off, false);
SubtensorModule::set_network_registration_allowed(netuid_on, true);

// Populate the subnets with neurons
for i in 0..n {
SubtensorModule::append_neuron(netuid_off, &U256::from(i), 0);
SubtensorModule::append_neuron(netuid_on, &U256::from(i), 0);
}

// Generate emission at block 0
let block: u64 = 0;
SubtensorModule::generate_emission(block);

// Verify that no emission tuples are loaded for the subnet with registration off
assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_none());

// Verify that emission tuples are loaded for the subnet with registration on
assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_some());
assert_eq!(
SubtensorModule::get_loaded_emission_tuples(netuid_on)
.unwrap()
.len(),
n as usize
);

// Step to the next epoch block
let epoch_block: u16 = tempo;
step_block(epoch_block);

// Verify that no emission tuples are loaded for the subnet with registration off
assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_none());
log::info!(
"Emissions for netuid with registration off: {:?}",
SubtensorModule::get_loaded_emission_tuples(netuid_off)
);

// Verify that emission tuples are loaded for the subnet with registration on
assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_some());
log::info!(
"Emissions for netuid with registration on: {:?}",
SubtensorModule::get_loaded_emission_tuples(netuid_on)
);
assert_eq!(
SubtensorModule::get_loaded_emission_tuples(netuid_on)
.unwrap()
.len(),
n as usize
);
});
}
2 changes: 1 addition & 1 deletion pallets/subtensor/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ parameter_types! {
pub const InitialStakePruningMin: u16 = 0;
pub const InitialFoundationDistribution: u64 = 0;
pub const InitialDefaultTake: u16 = 11_796; // 18%, same as in production
pub const InitialMinTake: u16 = 0;
pub const InitialMinTake: u16 =5_898; // 9%;
pub const InitialWeightsVersionKey: u16 = 0;
pub const InitialServingRateLimit: u64 = 0; // No limit.
pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing
Expand Down
Loading

0 comments on commit 8b91ed4

Please sign in to comment.