From 721ee94a9e7f7c074f11d3699e2da3e3415d81a8 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 1 Jul 2024 17:20:50 +0400 Subject: [PATCH 1/4] fix: run emissions when reg is off --- pallets/subtensor/src/block_step.rs | 76 ++++++++++++++------------- pallets/subtensor/tests/block_step.rs | 39 ++++++++++++++ 2 files changed, 79 insertions(+), 36 deletions(-) diff --git a/pallets/subtensor/src/block_step.rs b/pallets/subtensor/src/block_step.rs index 80733e6b7..54713533c 100644 --- a/pallets/subtensor/src/block_step.rs +++ b/pallets/subtensor/src/block_step.rs @@ -27,9 +27,9 @@ impl Pallet { Ok(()) } - /// Helper function which returns the number of blocks remaining before we will run the epoch on this - /// network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 - /// + // Helper function which returns the number of blocks remaining before we will run the epoch on this + // network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 + // pub fn blocks_until_next_epoch(netuid: u16, tempo: u16, block_number: u64) -> u64 { // tempo | netuid | # first epoch block // 1 0 0 @@ -45,9 +45,9 @@ impl Pallet { tempo as u64 - (block_number + netuid as u64 + 1) % (tempo as u64 + 1) } - /// Helper function returns the number of tuples to drain on a particular step based on - /// the remaining tuples to sink and the block number - /// + // Helper function returns the number of tuples to drain on a particular step based on + // the remaining tuples to sink and the block number + // pub fn tuples_to_drain_this_block( netuid: u16, tempo: u16, @@ -78,9 +78,9 @@ impl Pallet { LoadedEmission::::get(netuid) } - /// Reads from the loaded emission storage which contains lists of pending emission tuples ( hotkey, amount ) - /// and distributes small chunks of them at a time. - /// + // Reads from the loaded emission storage which contains lists of pending emission tuples ( hotkey, amount ) + // and distributes small chunks of them at a time. + // pub fn drain_emission(_: u64) { // --- 1. We iterate across each network. for (netuid, _) in as IterableStorageMap>::iter() { @@ -102,21 +102,25 @@ impl Pallet { } } - /// Iterates through networks queues more emission onto their pending storage. - /// If a network has no blocks left until tempo, we run the epoch function and generate - /// more token emission tuples for later draining onto accounts. - /// + // Iterates through networks queues more emission onto their pending storage. + // If a network has no blocks left until tempo, we run the epoch function and generate + // more token emission tuples for later draining onto accounts. + // 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 or subnets with registrations turned off - if netuid == Self::get_root_netuid() || !Self::is_registration_allowed(netuid) { + if netuid == Self::get_root_netuid() { // Root emission or subnet emission is burned continue; } // --- 2. Queue the emission due to this network. - let new_queued_emission: u64 = Self::get_subnet_emission_value(netuid); + let mut new_queued_emission: u64 = Self::get_subnet_emission_value(netuid); + if !Self::is_registration_allowed(netuid) { + new_queued_emission = 0; // No emission for this network if registration is off. + } + log::debug!( "generate_emission for netuid: {:?} with tempo: {:?} and emission: {:?}", netuid, @@ -196,10 +200,10 @@ impl Pallet { Self::set_last_mechanism_step_block(netuid, block_number); } } - /// Distributes token inflation through the hotkey based on emission. The call ensures that the inflation - /// is distributed onto the accounts in proportion of the stake delegated minus the take. This function - /// is called after an epoch to distribute the newly minted stake according to delegation. - /// + // Distributes token inflation through the hotkey based on emission. The call ensures that the inflation + // is distributed onto the accounts in proportion of the stake delegated minus the take. This function + // is called after an epoch to distribute the newly minted stake according to delegation. + // pub fn emit_inflation_through_hotkey_account( hotkey: &T::AccountId, server_emission: u64, @@ -260,9 +264,9 @@ impl Pallet { Self::increase_stake_on_hotkey_account(hotkey, server_emission); } - /// Increases the stake on the cold - hot pairing by increment while also incrementing other counters. - /// This function should be called rather than set_stake under account. - /// + // Increases the stake on the cold - hot pairing by increment while also incrementing other counters. + // This function should be called rather than set_stake under account. + // pub fn block_step_increase_stake_on_coldkey_hotkey_account( coldkey: &T::AccountId, hotkey: &T::AccountId, @@ -281,8 +285,8 @@ impl Pallet { TotalStake::::put(TotalStake::::get().saturating_add(increment)); } - /// Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. - /// + // Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. + // pub fn block_step_decrease_stake_on_coldkey_hotkey_account( coldkey: &T::AccountId, hotkey: &T::AccountId, @@ -301,8 +305,8 @@ impl Pallet { TotalStake::::put(TotalStake::::get().saturating_sub(decrement)); } - /// Returns emission awarded to a hotkey as a function of its proportion of the total stake. - /// + // Returns emission awarded to a hotkey as a function of its proportion of the total stake. + // pub fn calculate_stake_proportional_emission( stake: u64, total_stake: u64, @@ -316,8 +320,8 @@ impl Pallet { proportional_emission.to_num::() } - /// Returns the delegated stake 'take' assigned to this key. (If exists, otherwise 0) - /// + // Returns the delegated stake 'take' assigned to this key. (If exists, otherwise 0) + // pub fn calculate_delegate_proportional_take(hotkey: &T::AccountId, emission: u64) -> u64 { if Self::hotkey_is_delegate(hotkey) { let take_proportion: I64F64 = @@ -329,8 +333,8 @@ impl Pallet { } } - /// Adjusts the network difficulties/burns of every active network. Resetting state parameters. - /// + // Adjusts the network difficulties/burns of every active network. Resetting state parameters. + // pub fn adjust_registration_terms_for_networks() { log::debug!("adjust_registration_terms_for_networks"); @@ -486,9 +490,9 @@ impl Pallet { } } - /// Calculates the upgraded difficulty by multiplying the current difficulty by the ratio ( reg_actual + reg_target / reg_target + reg_target ) - /// We use I110F18 to avoid any overflows on u64. Also min_difficulty and max_difficulty bound the range. - /// + // Calculates the upgraded difficulty by multiplying the current difficulty by the ratio ( reg_actual + reg_target / reg_target + reg_target ) + // We use I110F18 to avoid any overflows on u64. Also min_difficulty and max_difficulty bound the range. + // pub fn upgraded_difficulty( netuid: u16, current_difficulty: u64, @@ -513,9 +517,9 @@ impl Pallet { } } - /// Calculates the upgraded burn by multiplying the current burn by the ratio ( reg_actual + reg_target / reg_target + reg_target ) - /// We use I110F18 to avoid any overflows on u64. Also min_burn and max_burn bound the range. - /// + // Calculates the upgraded burn by multiplying the current burn by the ratio ( reg_actual + reg_target / reg_target + reg_target ) + // We use I110F18 to avoid any overflows on u64. Also min_burn and max_burn bound the range. + // pub fn upgraded_burn( netuid: u16, current_burn: u64, diff --git a/pallets/subtensor/tests/block_step.rs b/pallets/subtensor/tests/block_step.rs index 5df173906..502362d70 100644 --- a/pallets/subtensor/tests/block_step.rs +++ b/pallets/subtensor/tests/block_step.rs @@ -895,3 +895,42 @@ fn test_emission_based_on_registration_status() { ); }); } + +#[test] +fn test_epoch_runs_when_registration_disabled() { + new_test_ext(1).execute_with(|| { + let n: u16 = 100; + let netuid_off: u16 = 1; + let tempo: u16 = 1; + let netuids: Vec = vec![netuid_off]; + let emissions: Vec = vec![1000000000]; + + // Add subnets with registration turned off and on + add_network(netuid_off, tempo, 0); + SubtensorModule::set_max_allowed_uids(netuid_off, n); + SubtensorModule::set_emission_values(&netuids, emissions).unwrap(); + SubtensorModule::set_network_registration_allowed(netuid_off, false); + + // Populate the subnets with neurons + for i in 0..n { + SubtensorModule::append_neuron(netuid_off, &U256::from(i), 0); + } + + // Generate emission at block 1 + let block: u64 = 1; + SubtensorModule::generate_emission(block); + + step_block(1); // Now block 2 + + // Verify blocks since last step was set + assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 1); + + // Step to the next epoch block + let epoch_block: u16 = tempo; + step_block(epoch_block); + + // Verify blocks since last step was set, this indicates we ran the epoch + assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 0 as u64); + assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); + }); +} \ No newline at end of file From a8b71e90fb45db7d3eb3c520121020b3a982d911 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 1 Jul 2024 17:23:15 +0400 Subject: [PATCH 2/4] chore: bump spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 2364008fd..5564dca5d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -135,7 +135,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 152, + spec_version: 153, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 59b067970c366024146766acba257d09df27b6c1 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 1 Jul 2024 17:29:14 +0400 Subject: [PATCH 3/4] chore: add back rust docs --- pallets/subtensor/src/block_step.rs | 68 ++++++++++++++--------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/pallets/subtensor/src/block_step.rs b/pallets/subtensor/src/block_step.rs index 54713533c..091ccd736 100644 --- a/pallets/subtensor/src/block_step.rs +++ b/pallets/subtensor/src/block_step.rs @@ -27,9 +27,9 @@ impl Pallet { Ok(()) } - // Helper function which returns the number of blocks remaining before we will run the epoch on this - // network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 - // + /// Helper function which returns the number of blocks remaining before we will run the epoch on this + /// network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 + /// pub fn blocks_until_next_epoch(netuid: u16, tempo: u16, block_number: u64) -> u64 { // tempo | netuid | # first epoch block // 1 0 0 @@ -45,9 +45,9 @@ impl Pallet { tempo as u64 - (block_number + netuid as u64 + 1) % (tempo as u64 + 1) } - // Helper function returns the number of tuples to drain on a particular step based on - // the remaining tuples to sink and the block number - // + /// Helper function returns the number of tuples to drain on a particular step based on + /// the remaining tuples to sink and the block number + /// pub fn tuples_to_drain_this_block( netuid: u16, tempo: u16, @@ -78,9 +78,9 @@ impl Pallet { LoadedEmission::::get(netuid) } - // Reads from the loaded emission storage which contains lists of pending emission tuples ( hotkey, amount ) - // and distributes small chunks of them at a time. - // + /// Reads from the loaded emission storage which contains lists of pending emission tuples ( hotkey, amount ) + /// and distributes small chunks of them at a time. + /// pub fn drain_emission(_: u64) { // --- 1. We iterate across each network. for (netuid, _) in as IterableStorageMap>::iter() { @@ -102,10 +102,10 @@ impl Pallet { } } - // Iterates through networks queues more emission onto their pending storage. - // If a network has no blocks left until tempo, we run the epoch function and generate - // more token emission tuples for later draining onto accounts. - // + /// Iterates through networks queues more emission onto their pending storage. + /// If a network has no blocks left until tempo, we run the epoch function and generate + /// more token emission tuples for later draining onto accounts. + /// 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() { @@ -200,10 +200,10 @@ impl Pallet { Self::set_last_mechanism_step_block(netuid, block_number); } } - // Distributes token inflation through the hotkey based on emission. The call ensures that the inflation - // is distributed onto the accounts in proportion of the stake delegated minus the take. This function - // is called after an epoch to distribute the newly minted stake according to delegation. - // + /// Distributes token inflation through the hotkey based on emission. The call ensures that the inflation + /// is distributed onto the accounts in proportion of the stake delegated minus the take. This function + /// is called after an epoch to distribute the newly minted stake according to delegation. + /// pub fn emit_inflation_through_hotkey_account( hotkey: &T::AccountId, server_emission: u64, @@ -264,9 +264,9 @@ impl Pallet { Self::increase_stake_on_hotkey_account(hotkey, server_emission); } - // Increases the stake on the cold - hot pairing by increment while also incrementing other counters. - // This function should be called rather than set_stake under account. - // + /// Increases the stake on the cold - hot pairing by increment while also incrementing other counters. + /// This function should be called rather than set_stake under account. + /// pub fn block_step_increase_stake_on_coldkey_hotkey_account( coldkey: &T::AccountId, hotkey: &T::AccountId, @@ -285,8 +285,8 @@ impl Pallet { TotalStake::::put(TotalStake::::get().saturating_add(increment)); } - // Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. - // + /// Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. + /// pub fn block_step_decrease_stake_on_coldkey_hotkey_account( coldkey: &T::AccountId, hotkey: &T::AccountId, @@ -305,8 +305,8 @@ impl Pallet { TotalStake::::put(TotalStake::::get().saturating_sub(decrement)); } - // Returns emission awarded to a hotkey as a function of its proportion of the total stake. - // + /// Returns emission awarded to a hotkey as a function of its proportion of the total stake. + /// pub fn calculate_stake_proportional_emission( stake: u64, total_stake: u64, @@ -320,8 +320,8 @@ impl Pallet { proportional_emission.to_num::() } - // Returns the delegated stake 'take' assigned to this key. (If exists, otherwise 0) - // + /// Returns the delegated stake 'take' assigned to this key. (If exists, otherwise 0) + /// pub fn calculate_delegate_proportional_take(hotkey: &T::AccountId, emission: u64) -> u64 { if Self::hotkey_is_delegate(hotkey) { let take_proportion: I64F64 = @@ -333,8 +333,8 @@ impl Pallet { } } - // Adjusts the network difficulties/burns of every active network. Resetting state parameters. - // + /// Adjusts the network difficulties/burns of every active network. Resetting state parameters. + /// pub fn adjust_registration_terms_for_networks() { log::debug!("adjust_registration_terms_for_networks"); @@ -490,9 +490,9 @@ impl Pallet { } } - // Calculates the upgraded difficulty by multiplying the current difficulty by the ratio ( reg_actual + reg_target / reg_target + reg_target ) - // We use I110F18 to avoid any overflows on u64. Also min_difficulty and max_difficulty bound the range. - // + /// Calculates the upgraded difficulty by multiplying the current difficulty by the ratio ( reg_actual + reg_target / reg_target + reg_target ) + /// We use I110F18 to avoid any overflows on u64. Also min_difficulty and max_difficulty bound the range. + /// pub fn upgraded_difficulty( netuid: u16, current_difficulty: u64, @@ -517,9 +517,9 @@ impl Pallet { } } - // Calculates the upgraded burn by multiplying the current burn by the ratio ( reg_actual + reg_target / reg_target + reg_target ) - // We use I110F18 to avoid any overflows on u64. Also min_burn and max_burn bound the range. - // + /// Calculates the upgraded burn by multiplying the current burn by the ratio ( reg_actual + reg_target / reg_target + reg_target ) + /// We use I110F18 to avoid any overflows on u64. Also min_burn and max_burn bound the range. + /// pub fn upgraded_burn( netuid: u16, current_burn: u64, From 43f0402990a674d14e7a6b16c43fc1522005b243 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 1 Jul 2024 18:09:25 +0400 Subject: [PATCH 4/4] chore: lints --- justfile | 6 +++--- pallets/subtensor/tests/block_step.rs | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/justfile b/justfile index 691d5bca2..495f78a27 100644 --- a/justfile +++ b/justfile @@ -4,7 +4,7 @@ export RUST_BACKTRACE := "full" export SKIP_WASM_BUILD := "1" export RUST_BIN_DIR := "target/x86_64-unknown-linux-gnu" export TARGET := "x86_64-unknown-linux-gnu" -export RUSTV := "nightly-2024-03-05" +export RUSTV := "stable" export RELEASE_NAME := "development" fmt: @@ -25,13 +25,13 @@ benchmarks: clippy: @echo "Running cargo clippy..." - cargo +{{RUSTV}} clippy -- -D clippy::panic \ + cargo +{{RUSTV}} clippy --workspace --all-targets -- -D \ -D clippy::todo \ -D clippy::unimplemented clippy-fix: @echo "Running cargo clippy with automatic fixes on potentially dirty code..." - cargo +{{RUSTV}} clippy --fix --allow-dirty -- -A clippy::panic \ + cargo +{{RUSTV}} clippy --fix --allow-dirty --workspace --all-targets -- -A \ -A clippy::todo \ -A clippy::unimplemented fix: diff --git a/pallets/subtensor/tests/block_step.rs b/pallets/subtensor/tests/block_step.rs index 502362d70..9c81492e9 100644 --- a/pallets/subtensor/tests/block_step.rs +++ b/pallets/subtensor/tests/block_step.rs @@ -920,17 +920,20 @@ fn test_epoch_runs_when_registration_disabled() { let block: u64 = 1; SubtensorModule::generate_emission(block); - step_block(1); // Now block 2 + step_block(1); // Now block 2 - // Verify blocks since last step was set - assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 1); + // Verify blocks since last step was set + assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 1); // Step to the next epoch block let epoch_block: u16 = tempo; step_block(epoch_block); - // Verify blocks since last step was set, this indicates we ran the epoch - assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 0 as u64); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); + // Verify blocks since last step was set, this indicates we ran the epoch + assert_eq!( + SubtensorModule::get_blocks_since_last_step(netuid_off), + 0_u64 + ); + assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); }); -} \ No newline at end of file +}