diff --git a/.rustfmt.toml b/.rustfmt.toml index 14c1023f6..24876acd9 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -75,7 +75,7 @@ # required_version = "1.5.1" # unstable_features = false # disable_all_formatting = false -skip_children = true +# skip_children = true # hide_parse_errors = false # error_on_line_overflow = false # error_on_unformatted = false diff --git a/pallets/subtensor/src/block_step.rs b/pallets/subtensor/src/block_step.rs index 84530d279..22ded6324 100644 --- a/pallets/subtensor/src/block_step.rs +++ b/pallets/subtensor/src/block_step.rs @@ -109,9 +109,9 @@ impl Pallet { pub fn generate_emission(block_number: u64) { // --- 1. Iterate across each network and add pending emission into stash. for (netuid, tempo) in as IterableStorageMap>::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; } diff --git a/pallets/subtensor/src/root.rs b/pallets/subtensor/src/root.rs index 635f93266..196311ce3 100644 --- a/pallets/subtensor/src/root.rs +++ b/pallets/subtensor/src/root.rs @@ -286,6 +286,24 @@ impl Pallet { 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, diff --git a/pallets/subtensor/src/subnet_info.rs b/pallets/subtensor/src/subnet_info.rs index b9203da0e..df768b0cd 100644 --- a/pallets/subtensor/src/subnet_info.rs +++ b/pallets/subtensor/src/subnet_info.rs @@ -40,7 +40,7 @@ pub struct SubnetHyperparams { weights_rate_limit: Compact, adjustment_interval: Compact, activity_cutoff: Compact, - registration_allowed: bool, + pub registration_allowed: bool, target_regs_per_interval: Compact, min_burn: Compact, max_burn: Compact, diff --git a/pallets/subtensor/tests/block_step.rs b/pallets/subtensor/tests/block_step.rs index 5d9cbdd7b..eb97fe692 100644 --- a/pallets/subtensor/tests/block_step.rs +++ b/pallets/subtensor/tests/block_step.rs @@ -803,3 +803,94 @@ 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 = vec![netuid_off, netuid_on]; + let emissions: Vec = 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 + ); + + // drain the emission tuples for the subnet with registration on + SubtensorModule::drain_emission(next_block as u64); + // Turn on registration for the subnet with registration off + SubtensorModule::set_network_registration_allowed(netuid_off, true); + SubtensorModule::set_network_registration_allowed(netuid_on, false); + + // Generate emission at the next block + let next_block: u64 = block + 1; + SubtensorModule::generate_emission(next_block); + + // Verify that emission tuples are now loaded for the subnet with registration turned on + assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); + log::info!( + "Emissions for netuid with registration on: {:?}", + SubtensorModule::get_loaded_emission_tuples(netuid_on) + ); + assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_none()); + assert_eq!( + SubtensorModule::get_loaded_emission_tuples(netuid_off) + .unwrap() + .len(), + n as usize + ); + }); +}