Skip to content
Merged
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
90 changes: 7 additions & 83 deletions pallets/subtensor/src/coinbase/subnet_emissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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_subnet_block_emissions(
Expand Down Expand Up @@ -73,8 +74,11 @@ impl<T: Config> Pallet<T> {
last_block_ema
}
} else {
// Initialize EMA flow, set S(current_block) = 0
let ema_flow = I64F64::saturating_from_num(0);
// Initialize EMA flow, set S(current_block) = min(price, ema_price) * init_factor
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 = moving_price.min(current_price);
SubnetEmaTaoFlow::<T>::insert(netuid, (current_block, ema_flow));
ema_flow
}
Expand Down Expand Up @@ -206,88 +210,8 @@ impl<T: Config> Pallet<T> {
offset_flows
}

// DEPRECATED: Implementation of shares that uses EMA prices will be gradually deprecated
fn get_shares_price_ema(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
// Get sum of alpha moving prices
let total_moving_prices = subnets_to_emit_to
.iter()
.map(|netuid| U64F64::saturating_from_num(Self::get_moving_alpha_price(*netuid)))
.fold(U64F64::saturating_from_num(0.0), |acc, ema| {
acc.saturating_add(ema)
});
log::debug!("total_moving_prices: {total_moving_prices:?}");

// Calculate shares.
subnets_to_emit_to
.iter()
.map(|netuid| {
let moving_price =
U64F64::saturating_from_num(Self::get_moving_alpha_price(*netuid));
log::debug!("moving_price_i: {moving_price:?}");

let share = moving_price
.checked_div(total_moving_prices)
.unwrap_or(U64F64::saturating_from_num(0));

(*netuid, share)
})
.collect::<BTreeMap<NetUid, U64F64>>()
}

// Combines ema price method and tao flow method linearly over FlowHalfLife blocks
pub(crate) fn get_shares(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
let current_block: u64 = Self::get_current_block_as_u64();

// Weight of tao flow method
let period = FlowHalfLife::<T>::get();
let one = U64F64::saturating_from_num(1);
let zero = U64F64::saturating_from_num(0);
let tao_flow_weight = if let Some(start_block) = FlowFirstBlock::<T>::get() {
if (current_block > start_block) && (current_block < start_block.saturating_add(period))
{
// Combination period in progress
let start_fixed = U64F64::saturating_from_num(start_block);
let current_fixed = U64F64::saturating_from_num(current_block);
let period_fixed = U64F64::saturating_from_num(period);
current_fixed
.saturating_sub(start_fixed)
.safe_div(period_fixed)
} else if current_block >= start_block.saturating_add(period) {
// Over combination period
one
} else {
// Not yet in combination period
zero
}
} else {
zero
};

// Get shares for each method as needed
let shares_flow = if tao_flow_weight > zero {
Self::get_shares_flow(subnets_to_emit_to)
} else {
BTreeMap::new()
};

let shares_prices = if tao_flow_weight < one {
Self::get_shares_price_ema(subnets_to_emit_to)
} else {
BTreeMap::new()
};

// Combine
let mut shares_combined = BTreeMap::new();
for netuid in subnets_to_emit_to.iter() {
let share_flow = shares_flow.get(netuid).unwrap_or(&zero);
let share_prices = shares_prices.get(netuid).unwrap_or(&zero);
shares_combined.insert(
*netuid,
share_flow.saturating_mul(tao_flow_weight).saturating_add(
share_prices.saturating_mul(one.saturating_sub(tao_flow_weight)),
),
);
}
shares_combined
Self::get_shares_flow(subnets_to_emit_to)
}
}
8 changes: 2 additions & 6 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ pub mod pallet {
use frame_system::pallet_prelude::*;
use pallet_drand::types::RoundNumber;
use runtime_common::prod_or_fast;
use safe_math::FixedExt;
use sp_core::{ConstU32, H160, H256};
use sp_runtime::traits::{Dispatchable, TrailingZeroInput};
use sp_std::collections::btree_map::BTreeMap;
Expand Down Expand Up @@ -1292,7 +1291,7 @@ pub mod pallet {
#[pallet::type_value]
/// Default value for flow normalization exponent.
pub fn DefaultFlowNormExponent<T: Config>() -> U64F64 {
U64F64::saturating_from_num(15).safe_div(U64F64::saturating_from_num(10))
U64F64::saturating_from_num(1)
}
#[pallet::storage]
/// --- ITEM --> Flow Normalization Exponent (p)
Expand All @@ -1302,7 +1301,7 @@ pub mod pallet {
/// Default value for flow EMA smoothing.
pub fn DefaultFlowEmaSmoothingFactor<T: Config>() -> u64 {
// Example values:
// half-life factor value i64 normalized
// half-life factor value i64 normalized (x 2^63)
// 216000 (1 month) --> 0.000003209009576 ( 29_597_889_189_277)
// 50400 (1 week) --> 0.000013752825678 (126_847_427_788_335)
29_597_889_189_277
Expand All @@ -1316,9 +1315,6 @@ pub mod pallet {
/// --- ITEM --> Flow EMA smoothing factor (flow alpha), u64 normalized
pub type FlowEmaSmoothingFactor<T: Config> =
StorageValue<_, u64, ValueQuery, DefaultFlowEmaSmoothingFactor<T>>;
#[pallet::storage]
/// --- ITEM --> Block when TAO flow calculation starts(ed)
pub type FlowFirstBlock<T: Config> = StorageValue<_, u64, OptionQuery>;

/// ============================
/// ==== Global Parameters =====
Expand Down
2 changes: 0 additions & 2 deletions pallets/subtensor/src/macros/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ mod hooks {
.saturating_add(migrations::migrate_auto_stake_destination::migrate_auto_stake_destination::<T>())
// Migrate Kappa to default (0.5)
.saturating_add(migrations::migrate_kappa_map_to_default::migrate_kappa_map_to_default::<T>())
// Set the first block of tao flow
.saturating_add(migrations::migrate_set_first_tao_flow_block::migrate_set_first_tao_flow_block::<T>())
// Remove obsolete map entries
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>());
weight
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion pallets/subtensor/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub mod migrate_remove_zero_total_hotkey_alpha;
pub mod migrate_reset_bonds_moving_average;
pub mod migrate_reset_max_burn;
pub mod migrate_set_first_emission_block_number;
pub mod migrate_set_first_tao_flow_block;
pub mod migrate_set_min_burn;
pub mod migrate_set_min_difficulty;
pub mod migrate_set_nominator_min_stake;
Expand Down
25 changes: 10 additions & 15 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ fn test_coinbase_tao_issuance_base_low_flow() {
// 100% tao flow method
let block_num = FlowHalfLife::<Test>::get();
SubnetEmaTaoFlow::<Test>::insert(netuid, (block_num, I64F64::from_num(1_000_000_000)));
FlowFirstBlock::<Test>::set(Some(0_u64));
System::set_block_number(block_num);

let tao_in_before = SubnetTAO::<Test>::get(netuid);
Expand Down Expand Up @@ -237,12 +236,12 @@ fn test_coinbase_tao_issuance_different_prices() {
assert_abs_diff_eq!(
SubnetTAO::<Test>::get(netuid1),
TaoCurrency::from(initial_tao + emission / 3),
epsilon = 1.into(),
epsilon = 10.into(),
);
assert_abs_diff_eq!(
SubnetTAO::<Test>::get(netuid2),
TaoCurrency::from(initial_tao + 2 * emission / 3),
epsilon = 1.into(),
epsilon = 10.into(),
);

// Prices are low => we limit tao issued (buy alpha with it)
Expand Down Expand Up @@ -298,11 +297,9 @@ fn test_coinbase_tao_issuance_different_flows() {
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(1));

// Set subnet tao flow ema.
// 100% tao flow method
let block_num = FlowHalfLife::<Test>::get();
SubnetEmaTaoFlow::<Test>::insert(netuid1, (block_num, I64F64::from_num(1)));
SubnetEmaTaoFlow::<Test>::insert(netuid2, (block_num, I64F64::from_num(2)));
FlowFirstBlock::<Test>::set(Some(0_u64));
System::set_block_number(block_num);

// Set normalization exponent to 1 for simplicity
Expand Down Expand Up @@ -490,9 +487,9 @@ fn test_coinbase_alpha_issuance_base() {
});
}

// Test alpha issuance with different subnet prices.
// Test alpha issuance with different subnet flows.
// This test verifies that:
// - Alpha issuance is proportional to subnet prices
// - Alpha issuance is proportional to subnet flows
// - Higher priced subnets receive more TAO emission
// - Alpha issuance is correctly calculated based on price ratios
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_alpha_issuance_different --exact --show-output --nocapture
Expand All @@ -507,18 +504,16 @@ fn test_coinbase_alpha_issuance_different() {
// Make subnets dynamic.
SubnetMechanism::<Test>::insert(netuid1, 1);
SubnetMechanism::<Test>::insert(netuid2, 1);
// Setup prices 1 and 1
// Setup prices 1 and 2
let initial: u64 = 1_000_000;
SubnetTAO::<Test>::insert(netuid1, TaoCurrency::from(initial));
SubnetAlphaIn::<Test>::insert(netuid1, AlphaCurrency::from(initial));
SubnetTAO::<Test>::insert(netuid2, TaoCurrency::from(initial));
SubnetTAO::<Test>::insert(netuid2, TaoCurrency::from(2 * initial));
SubnetAlphaIn::<Test>::insert(netuid2, AlphaCurrency::from(initial));
// Set subnet prices.
// 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 tao flow
SubnetEmaTaoFlow::<Test>::insert(netuid1, (1u64, I64F64::from_num(1)));
SubnetEmaTaoFlow::<Test>::insert(netuid2, (1u64, I64F64::from_num(2)));
// Do NOT Set tao flow, let it initialize
// Run coinbase
SubtensorModule::run_coinbase(U96F32::from_num(emission));
// tao_in = 333_333
Expand All @@ -528,10 +523,10 @@ fn test_coinbase_alpha_issuance_different() {
(initial + emission / 3).into()
);
// tao_in = 666_666
// alpha_in = 666_666/price = 666_666 + initial
// alpha_in = 666_666/price = 333_333 + initial
assert_eq!(
SubnetAlphaIn::<Test>::get(netuid2),
(initial + emission / 3 + emission / 3).into()
(initial + (emission * 2 / 3) / 2).into()
);
});
}
Expand Down
Loading
Loading