diff --git a/pallets/subtensor/src/coinbase/subnet_emissions.rs b/pallets/subtensor/src/coinbase/subnet_emissions.rs index 895a908ba8..379a5c4bb1 100644 --- a/pallets/subtensor/src/coinbase/subnet_emissions.rs +++ b/pallets/subtensor/src/coinbase/subnet_emissions.rs @@ -3,7 +3,6 @@ use alloc::collections::BTreeMap; use safe_math::FixedExt; use substrate_fixed::transcendental::{exp, ln}; use substrate_fixed::types::{I32F32, I64F64, U64F64, U96F32}; -use subtensor_swap_interface::SwapHandler; impl Pallet { pub fn get_subnets_to_emit_to(subnets: &[NetUid]) -> Vec { @@ -56,32 +55,24 @@ impl Pallet { // Calculate net ema flow for the next block let block_flow = I64F64::saturating_from_num(SubnetTaoFlow::::get(netuid)); - if let Some((last_block, last_block_ema)) = SubnetEmaTaoFlow::::get(netuid) { - // EMA flow already initialized - if last_block != current_block { - let flow_alpha = I64F64::saturating_from_num(FlowEmaSmoothingFactor::::get()) - .safe_div(I64F64::saturating_from_num(i64::MAX)); - let one = I64F64::saturating_from_num(1); - let ema_flow = (one.saturating_sub(flow_alpha)) - .saturating_mul(last_block_ema) - .saturating_add(flow_alpha.saturating_mul(block_flow)); - SubnetEmaTaoFlow::::insert(netuid, (current_block, ema_flow)); - - // Drop the accumulated flow in the last block - Self::reset_tao_outflow(netuid); - ema_flow - } else { - last_block_ema - } - } else { - // Initialize EMA flow, set S(current_block) = min(price, ema_price) * init_factor - let init_factor = I64F64::saturating_from_num(1_000_000_000); - let moving_price = I64F64::saturating_from_num(Self::get_moving_alpha_price(netuid)); - let current_price = - I64F64::saturating_from_num(T::SwapInterface::current_alpha_price(netuid)); - let ema_flow = init_factor.saturating_mul(moving_price.min(current_price)); + let (last_block, last_block_ema) = + SubnetEmaTaoFlow::::get(netuid).unwrap_or((0, I64F64::saturating_from_num(0))); + + // EMA flow already initialized + if last_block != current_block { + let flow_alpha = I64F64::saturating_from_num(FlowEmaSmoothingFactor::::get()) + .safe_div(I64F64::saturating_from_num(i64::MAX)); + let one = I64F64::saturating_from_num(1); + let ema_flow = (one.saturating_sub(flow_alpha)) + .saturating_mul(last_block_ema) + .saturating_add(flow_alpha.saturating_mul(block_flow)); SubnetEmaTaoFlow::::insert(netuid, (current_block, ema_flow)); + + // Drop the accumulated flow in the last block + Self::reset_tao_outflow(netuid); ema_flow + } else { + last_block_ema } } diff --git a/pallets/subtensor/src/tests/claim_root.rs b/pallets/subtensor/src/tests/claim_root.rs index c11d88033f..3128674d31 100644 --- a/pallets/subtensor/src/tests/claim_root.rs +++ b/pallets/subtensor/src/tests/claim_root.rs @@ -7,7 +7,7 @@ use crate::{ DefaultMinRootClaimAmount, Error, MAX_NUM_ROOT_CLAIMS, MAX_ROOT_CLAIM_THRESHOLD, NetworksAdded, NumRootClaim, NumStakingColdkeys, PendingRootAlphaDivs, RootClaimable, RootClaimableThreshold, StakingColdkeys, StakingColdkeysByIndex, SubnetAlphaIn, SubnetMechanism, SubnetMovingPrice, - SubnetTAO, SubtokenEnabled, Tempo, pallet, + SubnetTAO, SubnetTaoFlow, SubtokenEnabled, Tempo, pallet, }; use crate::{RootClaimType, RootClaimTypeEnum, RootClaimed}; use approx::assert_abs_diff_eq; @@ -1037,6 +1037,9 @@ fn test_claim_root_coinbase_distribution() { let root_sell_flag = SubtensorModule::get_network_root_sell_flag(&[netuid]); assert!(root_sell_flag, "Root sell flag should be true"); + // Set TAOFlow > 0 + SubnetTaoFlow::::insert(netuid, 2222_i64); + // Check total issuance (saved to pending alpha divs) run_to_block(2); diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 66779012b2..12b3392397 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -90,7 +90,8 @@ fn test_coinbase_tao_issuance_base() { let subnet_owner_hk = U256::from(1002); let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck); let total_issuance_before = TotalIssuance::::get(); - SubnetMovingPrice::::insert(netuid, I96F32::from(3141) / I96F32::from(1000)); + // Set subnet TAO flow to non-zero + SubnetTaoFlow::::insert(netuid, 1234567_i64); let tao_in_before = SubnetTAO::::get(netuid); let total_stake_before = TotalStake::::get(); SubtensorModule::run_coinbase(U96F32::from_num(emission)); @@ -111,6 +112,8 @@ fn test_coinbase_tao_issuance_base_low() { let emission = TaoCurrency::from(1); add_network(netuid, 1, 0); assert_eq!(SubnetTAO::::get(netuid), TaoCurrency::ZERO); + // Set subnet flow to non-zero + SubnetTaoFlow::::insert(netuid, 33433_i64); SubtensorModule::run_coinbase(U96F32::from_num(emission)); assert_eq!(SubnetTAO::::get(netuid), emission); assert_eq!(TotalIssuance::::get(), emission); @@ -162,6 +165,10 @@ fn test_coinbase_tao_issuance_multiple() { assert_eq!(SubnetTAO::::get(netuid1), TaoCurrency::ZERO); assert_eq!(SubnetTAO::::get(netuid2), TaoCurrency::ZERO); assert_eq!(SubnetTAO::::get(netuid3), TaoCurrency::ZERO); + // Set Tao flows to equal and non-zero + SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid2, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid3, 100_000_000_i64); SubtensorModule::run_coinbase(U96F32::from_num(emission)); assert_abs_diff_eq!( SubnetTAO::::get(netuid1), @@ -225,9 +232,10 @@ fn test_coinbase_tao_issuance_different_prices() { SubnetMechanism::::insert(netuid1, 1); SubnetMechanism::::insert(netuid2, 1); - // Set subnet prices. - SubnetMovingPrice::::insert(netuid1, I96F32::from_num(1)); - SubnetMovingPrice::::insert(netuid2, I96F32::from_num(2)); + // Set subnet flows + // Subnet 2 has twice the flow of subnet 1. + SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid2, 200_000_000_i64); // Assert initial TAO reserves. assert_eq!(SubnetTAO::::get(netuid1), initial_tao.into()); @@ -474,8 +482,9 @@ fn test_coinbase_alpha_issuance_base() { SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial)); SubnetTAO::::insert(netuid2, TaoCurrency::from(initial)); SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial)); - SubnetMovingPrice::::insert(netuid1, I96F32::from(1)); - SubnetMovingPrice::::insert(netuid2, I96F32::from(1)); + // Equal flow + SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid2, 100_000_000_i64); // Check initial SubtensorModule::run_coinbase(U96F32::from_num(emission)); // tao_in = 500_000 @@ -514,9 +523,9 @@ fn test_coinbase_alpha_issuance_different() { SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial)); SubnetTAO::::insert(netuid2, TaoCurrency::from(2 * initial)); SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial)); - // Set subnet ema prices to 1 and 2 - SubnetMovingPrice::::insert(netuid1, I96F32::from_num(1)); - SubnetMovingPrice::::insert(netuid2, I96F32::from_num(2)); + // Set subnet TAO flows to non-zero and 1:2 ratio + SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid2, 200_000_000_i64); // Do NOT Set tao flow, let it initialize // Run coinbase SubtensorModule::run_coinbase(U96F32::from_num(emission)); @@ -593,8 +602,9 @@ fn test_coinbase_alpha_issuance_with_cap_trigger_and_block_emission() { // Enable emission FirstEmissionBlockNumber::::insert(netuid1, 0); FirstEmissionBlockNumber::::insert(netuid2, 0); - SubnetMovingPrice::::insert(netuid1, I96F32::from_num(1)); - SubnetMovingPrice::::insert(netuid2, I96F32::from_num(2)); + // Set subnet TAO flows to non-zero and 1:2 ratio + SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); + SubnetTaoFlow::::insert(netuid2, 200_000_000_i64); // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( @@ -2741,8 +2751,9 @@ fn test_coinbase_v3_liquidity_update() { // Enable emissions and run coinbase (which will increase position liquidity) let emission: u64 = 1_234_567; + // Set the TAO flow to non-zero + SubnetTaoFlow::::insert(netuid, 8348383_i64); FirstEmissionBlockNumber::::insert(netuid, 0); - SubnetMovingPrice::::insert(netuid, I96F32::from_num(0.5)); SubtensorModule::run_coinbase(U96F32::from_num(emission)); let position_after = pallet_subtensor_swap::Positions::::get(( diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 9ece1dd025..2171708685 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -220,7 +220,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: 347, + spec_version: 348, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,