From 1a3e3f9d30788cdceb50f60f1ab4b23ab4d477af Mon Sep 17 00:00:00 2001 From: camfairchild Date: Thu, 19 Dec 2024 20:17:42 -0500 Subject: [PATCH] move block emission adjustment to explicit step --- .../subtensor/src/coinbase/block_emission.rs | 27 ++++++++++-------- pallets/subtensor/src/coinbase/block_step.rs | 3 ++ .../subtensor/src/coinbase/run_coinbase.rs | 2 +- pallets/subtensor/src/tests/block_emission.rs | 28 +++++++++++++------ pallets/subtensor/src/tests/coinbase.rs | 8 +++--- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/pallets/subtensor/src/coinbase/block_emission.rs b/pallets/subtensor/src/coinbase/block_emission.rs index 332775a5e..e0b1ef27a 100644 --- a/pallets/subtensor/src/coinbase/block_emission.rs +++ b/pallets/subtensor/src/coinbase/block_emission.rs @@ -4,7 +4,7 @@ use substrate_fixed::transcendental::log2; use substrate_fixed::types::I96F32; impl Pallet { - /// Calculates the block emission based on the total issuance. + /// Calculates the block emission based on the total issuance and updates the chain if applicable. /// /// This function computes the block emission by applying a logarithmic function /// to the total issuance of the network. The formula used takes into account @@ -15,9 +15,21 @@ impl Pallet { /// # Returns /// * 'Result': The calculated block emission rate or error. /// - pub fn get_block_emission() -> Result { - // Convert the total issuance to a fixed-point number for calculation. - Self::get_block_emission_for_issuance(Self::get_total_issuance()) + pub fn block_emission_step() -> Result { + let issuance = Self::get_total_issuance(); + Self::block_emission_step_with_issuance(issuance) + } + + pub fn block_emission_step_with_issuance(issuance: u64) -> Result { + let block_emission: u64 = Self::get_block_emission_for_issuance(issuance)?; + + // Update the BlockEmission storage if the calculated emission is different from the current value + if BlockEmission::::get() != block_emission { + // Call the on_halving hook. + Self::on_halving(block_emission); + } + + Ok(block_emission) } /// Returns the block emission for an issuance value. @@ -76,13 +88,6 @@ impl Pallet { // Convert the calculated emission to u64 let block_emission_u64: u64 = block_emission.to_num::(); - // Update the BlockEmission storage if the calculated emission is different from the current value - if BlockEmission::::get() != block_emission_u64 { - log::debug!("Updating BlockEmission storage"); - BlockEmission::::put(block_emission_u64); - Self::on_halving(block_emission_u64); - } - // Return the calculated block emission Ok(block_emission_u64) } diff --git a/pallets/subtensor/src/coinbase/block_step.rs b/pallets/subtensor/src/coinbase/block_step.rs index fc2a96db1..58ebe3539 100644 --- a/pallets/subtensor/src/coinbase/block_step.rs +++ b/pallets/subtensor/src/coinbase/block_step.rs @@ -251,6 +251,9 @@ impl Pallet { /// Called when the network emission is halved. pub fn on_halving(new_emission: u64) { + log::debug!("Updating BlockEmission storage"); + BlockEmission::::put(new_emission); + let current_block: u64 = Self::get_current_block_as_u64(); HalvingBlock::::insert(current_block, new_emission); diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 40eaaf8ce..c89c2bd78 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -60,7 +60,7 @@ impl Pallet { // replaces root epoch and uses a different algorithm to calculate EmissionValues and // PendingEmission for each subnet. // --- 2. Get the current coinbase emission. - let block_emission: I96F32 = I96F32::from_num(Self::get_block_emission().unwrap_or(0)); + let block_emission: I96F32 = I96F32::from_num(Self::block_emission_step().unwrap_or(0)); log::debug!("Block emission: {:?}", block_emission); // --- 3. Total subnet TAO. diff --git a/pallets/subtensor/src/tests/block_emission.rs b/pallets/subtensor/src/tests/block_emission.rs index 2efa9c970..5e9df4382 100644 --- a/pallets/subtensor/src/tests/block_emission.rs +++ b/pallets/subtensor/src/tests/block_emission.rs @@ -64,7 +64,7 @@ fn test_minimum_non_zero_issuance() { #[allow(clippy::unwrap_used)] fn test_default_block_emission() { new_test_ext(1).execute_with(|| { - let result = SubtensorModule::get_block_emission(); + let result = SubtensorModule::block_emission_step(); assert!(result.is_ok()); let emission = result.unwrap(); assert!(emission > 0); @@ -221,8 +221,8 @@ fn test_block_emission_storage_update() { let initial_emission = BlockEmission::::get(); let new_issuance = TotalSupply::::get() / 2; - // Call get_block_emission_for_issuance to trigger an update - let _ = SubtensorModule::get_block_emission_for_issuance(new_issuance).unwrap(); + // Call the block_emission_step_with_issuance to trigger an update + let _ = SubtensorModule::block_emission_step_with_issuance(new_issuance).unwrap(); let updated_emission = BlockEmission::::get(); assert_ne!( @@ -231,7 +231,7 @@ fn test_block_emission_storage_update() { ); // Call again with the same issuance to ensure no unnecessary updates - let _ = SubtensorModule::get_block_emission_for_issuance(new_issuance).unwrap(); + let _ = SubtensorModule::block_emission_step_with_issuance(new_issuance).unwrap(); assert_eq!( updated_emission, BlockEmission::::get(), @@ -240,19 +240,19 @@ fn test_block_emission_storage_update() { }); } -// 15. Test Consistency Between get_block_emission() and get_block_emission_for_issuance() +// 15. Test Consistency Between block_emission_step() and block_emission_step_with_issuance() // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test block_emission test_emission_consistency -- --exact --nocapture #[test] #[allow(clippy::unwrap_used)] fn test_emission_consistency() { new_test_ext(1).execute_with(|| { - let emission_from_get = SubtensorModule::get_block_emission().unwrap(); + let emission_no_params = SubtensorModule::block_emission_step().unwrap(); let total_issuance = SubtensorModule::get_total_issuance(); let emission_for_issuance = - SubtensorModule::get_block_emission_for_issuance(total_issuance).unwrap(); + SubtensorModule::block_emission_step_with_issuance(total_issuance).unwrap(); assert_eq!( - emission_from_get, emission_for_issuance, + emission_no_params, emission_for_issuance, "Emissions should be consistent between methods" ); }); @@ -594,3 +594,15 @@ fn test_floating_point_precision_impact() { } }); } + +#[test] +fn test_block_emission_step_updates_halving_block_storage() { + new_test_ext(1).execute_with(|| { + let total_supply = TotalSupply::::get(); + let issuance = total_supply / 2; + let emission = SubtensorModule::block_emission_step_with_issuance(issuance).unwrap(); + assert!(emission > 0, "Emission should be positive"); + let curr_block = SubtensorModule::get_current_block_as_u64(); + assert_eq!(HalvingBlock::::get(curr_block), emission, "Halving block should be updated"); + }); +} diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 1c32e6770..ddb182e33 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -84,7 +84,7 @@ fn test_coinbase_basic() { assert_eq!(get_total_stake_for_hotkey(hotkey), stake); // Ensure that subnet PendingEmission accumulates - let block_emission = SubtensorModule::get_block_emission(); + let block_emission = SubtensorModule::block_emission_step(); let subnet_emission_before = SubtensorModule::get_pending_emission(netuid); step_block(1); assert_eq!( @@ -191,7 +191,7 @@ fn test_run_coinbase_single_subnet() { // Set initial values let initial_issuance = 1_000_000; TotalIssuance::::put(initial_issuance); - let block_emission = SubtensorModule::get_block_emission().unwrap(); + let block_emission = SubtensorModule::block_emission_step().unwrap(); SubnetTAO::::insert(netuid, initial_issuance); // Run coinbase @@ -225,7 +225,7 @@ fn test_run_coinbase_multiple_subnets() { // Set initial values let initial_issuance = 1_000_000; TotalIssuance::::put(initial_issuance); - let block_emission = SubtensorModule::get_block_emission().unwrap(); + let block_emission = SubtensorModule::block_emission_step().unwrap(); let subnet_emission = block_emission / netuids.len() as u64; for netuid in &netuids { @@ -303,7 +303,7 @@ fn test_run_coinbase_different_mechanisms() { // Set initial values let initial_issuance = 1_000_000; - let block_emission = SubtensorModule::get_block_emission().unwrap(); + let block_emission = SubtensorModule::block_emission_step().unwrap(); TotalIssuance::::put(initial_issuance); SubnetTAO::::insert(netuid1, initial_issuance / 2); SubnetTAO::::insert(netuid2, initial_issuance / 2);