Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 16 additions & 25 deletions pallets/subtensor/src/coinbase/subnet_emissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Config> Pallet<T> {
pub fn get_subnets_to_emit_to(subnets: &[NetUid]) -> Vec<NetUid> {
Expand Down Expand Up @@ -56,32 +55,24 @@ impl<T: Config> Pallet<T> {

// Calculate net ema flow for the next block
let block_flow = I64F64::saturating_from_num(SubnetTaoFlow::<T>::get(netuid));
if let Some((last_block, last_block_ema)) = SubnetEmaTaoFlow::<T>::get(netuid) {
// EMA flow already initialized
if last_block != current_block {
let flow_alpha = I64F64::saturating_from_num(FlowEmaSmoothingFactor::<T>::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::<T>::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::<T>::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::<T>::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::<T>::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
}
}

Expand Down
5 changes: 4 additions & 1 deletion pallets/subtensor/src/tests/claim_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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::<Test>::insert(netuid, 2222_i64);

// Check total issuance (saved to pending alpha divs)
run_to_block(2);

Expand Down
35 changes: 23 additions & 12 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Test>::get();
SubnetMovingPrice::<Test>::insert(netuid, I96F32::from(3141) / I96F32::from(1000));
// Set subnet TAO flow to non-zero
SubnetTaoFlow::<Test>::insert(netuid, 1234567_i64);
let tao_in_before = SubnetTAO::<Test>::get(netuid);
let total_stake_before = TotalStake::<Test>::get();
SubtensorModule::run_coinbase(U96F32::from_num(emission));
Expand All @@ -111,6 +112,8 @@ fn test_coinbase_tao_issuance_base_low() {
let emission = TaoCurrency::from(1);
add_network(netuid, 1, 0);
assert_eq!(SubnetTAO::<Test>::get(netuid), TaoCurrency::ZERO);
// Set subnet flow to non-zero
SubnetTaoFlow::<Test>::insert(netuid, 33433_i64);
SubtensorModule::run_coinbase(U96F32::from_num(emission));
assert_eq!(SubnetTAO::<Test>::get(netuid), emission);
assert_eq!(TotalIssuance::<Test>::get(), emission);
Expand Down Expand Up @@ -162,6 +165,10 @@ fn test_coinbase_tao_issuance_multiple() {
assert_eq!(SubnetTAO::<Test>::get(netuid1), TaoCurrency::ZERO);
assert_eq!(SubnetTAO::<Test>::get(netuid2), TaoCurrency::ZERO);
assert_eq!(SubnetTAO::<Test>::get(netuid3), TaoCurrency::ZERO);
// Set Tao flows to equal and non-zero
SubnetTaoFlow::<Test>::insert(netuid1, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid2, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid3, 100_000_000_i64);
SubtensorModule::run_coinbase(U96F32::from_num(emission));
assert_abs_diff_eq!(
SubnetTAO::<Test>::get(netuid1),
Expand Down Expand Up @@ -225,9 +232,10 @@ fn test_coinbase_tao_issuance_different_prices() {
SubnetMechanism::<Test>::insert(netuid1, 1);
SubnetMechanism::<Test>::insert(netuid2, 1);

// Set subnet prices.
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(1));
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(2));
// Set subnet flows
// Subnet 2 has twice the flow of subnet 1.
SubnetTaoFlow::<Test>::insert(netuid1, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid2, 200_000_000_i64);

// Assert initial TAO reserves.
assert_eq!(SubnetTAO::<Test>::get(netuid1), initial_tao.into());
Expand Down Expand Up @@ -474,8 +482,9 @@ fn test_coinbase_alpha_issuance_base() {
SubnetAlphaIn::<Test>::insert(netuid1, AlphaCurrency::from(initial));
SubnetTAO::<Test>::insert(netuid2, TaoCurrency::from(initial));
SubnetAlphaIn::<Test>::insert(netuid2, AlphaCurrency::from(initial));
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from(1));
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from(1));
// Equal flow
SubnetTaoFlow::<Test>::insert(netuid1, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid2, 100_000_000_i64);
// Check initial
SubtensorModule::run_coinbase(U96F32::from_num(emission));
// tao_in = 500_000
Expand Down Expand Up @@ -514,9 +523,9 @@ fn test_coinbase_alpha_issuance_different() {
SubnetAlphaIn::<Test>::insert(netuid1, AlphaCurrency::from(initial));
SubnetTAO::<Test>::insert(netuid2, TaoCurrency::from(2 * initial));
SubnetAlphaIn::<Test>::insert(netuid2, AlphaCurrency::from(initial));
// Set subnet ema prices to 1 and 2
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(1));
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(2));
// Set subnet TAO flows to non-zero and 1:2 ratio
SubnetTaoFlow::<Test>::insert(netuid1, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid2, 200_000_000_i64);
// Do NOT Set tao flow, let it initialize
// Run coinbase
SubtensorModule::run_coinbase(U96F32::from_num(emission));
Expand Down Expand Up @@ -593,8 +602,9 @@ fn test_coinbase_alpha_issuance_with_cap_trigger_and_block_emission() {
// Enable emission
FirstEmissionBlockNumber::<Test>::insert(netuid1, 0);
FirstEmissionBlockNumber::<Test>::insert(netuid2, 0);
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(1));
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(2));
// Set subnet TAO flows to non-zero and 1:2 ratio
SubnetTaoFlow::<Test>::insert(netuid1, 100_000_000_i64);
SubnetTaoFlow::<Test>::insert(netuid2, 200_000_000_i64);

// Force the swap to initialize
SubtensorModule::swap_tao_for_alpha(
Expand Down Expand Up @@ -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::<Test>::insert(netuid, 8348383_i64);
FirstEmissionBlockNumber::<Test>::insert(netuid, 0);
SubnetMovingPrice::<Test>::insert(netuid, I96F32::from_num(0.5));
SubtensorModule::run_coinbase(U96F32::from_num(emission));

let position_after = pallet_subtensor_swap::Positions::<Test>::get((
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading