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
36 changes: 35 additions & 1 deletion pallets/subtensor/src/coinbase/subnet_emissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl<T: Config> Pallet<T> {

// Update SubnetEmaTaoFlow if needed and return its value for
// the current block
#[allow(dead_code)]
fn get_ema_flow(netuid: NetUid) -> I64F64 {
let current_block: u64 = Self::get_current_block_as_u64();

Expand All @@ -75,10 +76,11 @@ impl<T: Config> Pallet<T> {
}
} 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 = moving_price.min(current_price);
let ema_flow = init_factor.saturating_mul(moving_price.min(current_price));
SubnetEmaTaoFlow::<T>::insert(netuid, (current_block, ema_flow));
ema_flow
}
Expand All @@ -87,6 +89,7 @@ impl<T: Config> Pallet<T> {
// Either the minimal EMA flow L = min{Si}, or an artificial
// cut off at some higher value A (TaoFlowCutoff)
// L = max {A, min{min{S[i], 0}}}
#[allow(dead_code)]
fn get_lower_limit(ema_flows: &BTreeMap<NetUid, I64F64>) -> I64F64 {
let zero = I64F64::saturating_from_num(0);
let min_flow = ema_flows
Expand Down Expand Up @@ -178,6 +181,7 @@ impl<T: Config> Pallet<T> {
}

// Implementation of shares that uses TAO flow
#[allow(dead_code)]
fn get_shares_flow(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
// Get raw flows
let ema_flows = subnets_to_emit_to
Expand Down Expand Up @@ -213,5 +217,35 @@ impl<T: Config> Pallet<T> {
// 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> {
Self::get_shares_flow(subnets_to_emit_to)
// Self::get_shares_price_ema(subnets_to_emit_to)
}

// DEPRECATED: Implementation of shares that uses EMA prices will be gradually deprecated
#[allow(dead_code)]
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>>()
}
}
4 changes: 3 additions & 1 deletion pallets/subtensor/src/macros/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ mod hooks {
// Migrate Kappa to default (0.5)
.saturating_add(migrations::migrate_kappa_map_to_default::migrate_kappa_map_to_default::<T>())
// Remove obsolete map entries
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>());
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>())
// Re-init tao flows
.saturating_add(migrations::migrate_init_tao_flow::migrate_init_tao_flow::<T>());
weight
}

Expand Down
40 changes: 40 additions & 0 deletions pallets/subtensor/src/migrations/migrate_init_tao_flow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use alloc::string::String;

use frame_support::{traits::Get, weights::Weight};

use super::*;

pub fn migrate_init_tao_flow<T: Config>() -> Weight {
let migration_name = b"migrate_init_tao_flow".to_vec();

// Initialize the weight with one read operation.
let mut weight = T::DbWeight::get().reads(1);

// Check if the migration has already run
if HasMigrationRun::<T>::get(&migration_name) {
log::info!(
"Migration '{:?}' has already run. Skipping.",
String::from_utf8_lossy(&migration_name)
);
return weight;
}
log::info!(
"Running migration '{}'",
String::from_utf8_lossy(&migration_name)
);

let _ = SubnetEmaTaoFlow::<T>::clear(u32::MAX, None);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

// Mark the migration as completed
HasMigrationRun::<T>::insert(&migration_name, true);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

log::info!(
"Migration '{:?}' completed.",
String::from_utf8_lossy(&migration_name)
);

// Return the migration weight.
weight
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod migrate_fix_is_network_member;
pub mod migrate_fix_root_subnet_tao;
pub mod migrate_fix_root_tao_and_alpha_in;
pub mod migrate_identities_v2;
pub mod migrate_init_tao_flow;
pub mod migrate_init_total_issuance;
pub mod migrate_kappa_map_to_default;
pub mod migrate_network_immunity_period;
Expand Down
200 changes: 100 additions & 100 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,28 +115,28 @@ fn test_coinbase_tao_issuance_base_low() {
}

// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_tao_issuance_base_low_flow --exact --show-output --nocapture
#[test]
fn test_coinbase_tao_issuance_base_low_flow() {
new_test_ext(1).execute_with(|| {
let emission = TaoCurrency::from(1_234_567);
let subnet_owner_ck = U256::from(1001);
let subnet_owner_hk = U256::from(1002);
let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
let emission = TaoCurrency::from(1);

// 100% tao flow method
let block_num = FlowHalfLife::<Test>::get();
SubnetEmaTaoFlow::<Test>::insert(netuid, (block_num, I64F64::from_num(1_000_000_000)));
System::set_block_number(block_num);

let tao_in_before = SubnetTAO::<Test>::get(netuid);
let total_stake_before = TotalStake::<Test>::get();
SubtensorModule::run_coinbase(U96F32::from_num(emission));
assert_eq!(SubnetTAO::<Test>::get(netuid), tao_in_before + emission);
assert_eq!(TotalIssuance::<Test>::get(), emission);
assert_eq!(TotalStake::<Test>::get(), total_stake_before + emission);
});
}
// #[test]
// fn test_coinbase_tao_issuance_base_low_flow() {
// new_test_ext(1).execute_with(|| {
// let emission = TaoCurrency::from(1_234_567);
// let subnet_owner_ck = U256::from(1001);
// let subnet_owner_hk = U256::from(1002);
// let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
// let emission = TaoCurrency::from(1);

// // 100% tao flow method
// let block_num = FlowHalfLife::<Test>::get();
// SubnetEmaTaoFlow::<Test>::insert(netuid, (block_num, I64F64::from_num(1_000_000_000)));
// System::set_block_number(block_num);

// let tao_in_before = SubnetTAO::<Test>::get(netuid);
// let total_stake_before = TotalStake::<Test>::get();
// SubtensorModule::run_coinbase(U96F32::from_num(emission));
// assert_eq!(SubnetTAO::<Test>::get(netuid), tao_in_before + emission);
// assert_eq!(TotalIssuance::<Test>::get(), emission);
// assert_eq!(TotalStake::<Test>::get(), total_stake_before + emission);
// });
// }

// Test emission distribution across multiple subnets.
// This test verifies that:
Expand Down Expand Up @@ -260,85 +260,85 @@ fn test_coinbase_tao_issuance_different_prices() {
}

// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_tao_issuance_different_flows --exact --show-output --nocapture
#[test]
fn test_coinbase_tao_issuance_different_flows() {
new_test_ext(1).execute_with(|| {
let subnet_owner_ck = U256::from(1001);
let subnet_owner_hk = U256::from(1002);
let netuid1 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
let netuid2 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
let emission = 100_000_000;

// Setup prices 0.1 and 0.2
let initial_tao: u64 = 100_000_u64;
let initial_alpha1: u64 = initial_tao * 10;
let initial_alpha2: u64 = initial_tao * 5;
mock::setup_reserves(netuid1, initial_tao.into(), initial_alpha1.into());
mock::setup_reserves(netuid2, initial_tao.into(), initial_alpha2.into());

// Force the swap to initialize
SubtensorModule::swap_tao_for_alpha(
netuid1,
TaoCurrency::ZERO,
1_000_000_000_000.into(),
false,
)
.unwrap();
SubtensorModule::swap_tao_for_alpha(
netuid2,
TaoCurrency::ZERO,
1_000_000_000_000.into(),
false,
)
.unwrap();

// Set subnet prices to reversed proportion to ensure they don't affect emissions.
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(2));
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(1));

// Set subnet tao flow ema.
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)));
System::set_block_number(block_num);

// Set normalization exponent to 1 for simplicity
FlowNormExponent::<Test>::set(U64F64::from(1_u64));

// Assert initial TAO reserves.
assert_eq!(SubnetTAO::<Test>::get(netuid1), initial_tao.into());
assert_eq!(SubnetTAO::<Test>::get(netuid2), initial_tao.into());
let total_stake_before = TotalStake::<Test>::get();

// Run the coinbase with the emission amount.
SubtensorModule::run_coinbase(U96F32::from_num(emission));

// Assert tao emission is split evenly.
assert_abs_diff_eq!(
SubnetTAO::<Test>::get(netuid1),
TaoCurrency::from(initial_tao + emission / 3),
epsilon = 10.into(),
);
assert_abs_diff_eq!(
SubnetTAO::<Test>::get(netuid2),
TaoCurrency::from(initial_tao + 2 * emission / 3),
epsilon = 10.into(),
);
// #[test]
// fn test_coinbase_tao_issuance_different_flows() {
// new_test_ext(1).execute_with(|| {
// let subnet_owner_ck = U256::from(1001);
// let subnet_owner_hk = U256::from(1002);
// let netuid1 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
// let netuid2 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
// let emission = 100_000_000;

// // Setup prices 0.1 and 0.2
// let initial_tao: u64 = 100_000_u64;
// let initial_alpha1: u64 = initial_tao * 10;
// let initial_alpha2: u64 = initial_tao * 5;
// mock::setup_reserves(netuid1, initial_tao.into(), initial_alpha1.into());
// mock::setup_reserves(netuid2, initial_tao.into(), initial_alpha2.into());

// // Force the swap to initialize
// SubtensorModule::swap_tao_for_alpha(
// netuid1,
// TaoCurrency::ZERO,
// 1_000_000_000_000.into(),
// false,
// )
// .unwrap();
// SubtensorModule::swap_tao_for_alpha(
// netuid2,
// TaoCurrency::ZERO,
// 1_000_000_000_000.into(),
// false,
// )
// .unwrap();

// // Set subnet prices to reversed proportion to ensure they don't affect emissions.
// SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(2));
// SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(1));

// // Set subnet tao flow ema.
// 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)));
// System::set_block_number(block_num);

// // Set normalization exponent to 1 for simplicity
// FlowNormExponent::<Test>::set(U64F64::from(1_u64));

// // Assert initial TAO reserves.
// assert_eq!(SubnetTAO::<Test>::get(netuid1), initial_tao.into());
// assert_eq!(SubnetTAO::<Test>::get(netuid2), initial_tao.into());
// let total_stake_before = TotalStake::<Test>::get();

// // Run the coinbase with the emission amount.
// SubtensorModule::run_coinbase(U96F32::from_num(emission));

// // Assert tao emission is split evenly.
// assert_abs_diff_eq!(
// SubnetTAO::<Test>::get(netuid1),
// TaoCurrency::from(initial_tao + emission / 3),
// epsilon = 10.into(),
// );
// assert_abs_diff_eq!(
// SubnetTAO::<Test>::get(netuid2),
// TaoCurrency::from(initial_tao + 2 * emission / 3),
// epsilon = 10.into(),
// );

// Prices are low => we limit tao issued (buy alpha with it)
let tao_issued = TaoCurrency::from(((0.1 + 0.2) * emission as f64) as u64);
assert_abs_diff_eq!(
TotalIssuance::<Test>::get(),
tao_issued,
epsilon = 10.into()
);
assert_abs_diff_eq!(
TotalStake::<Test>::get(),
total_stake_before + emission.into(),
epsilon = 10.into()
);
});
}
// // Prices are low => we limit tao issued (buy alpha with it)
// let tao_issued = TaoCurrency::from(((0.1 + 0.2) * emission as f64) as u64);
// assert_abs_diff_eq!(
// TotalIssuance::<Test>::get(),
// tao_issued,
// epsilon = 10.into()
// );
// assert_abs_diff_eq!(
// TotalStake::<Test>::get(),
// total_stake_before + emission.into(),
// epsilon = 10.into()
// );
// });
// }

// Test moving price updates with different alpha values.
// This test verifies that:
Expand Down
Loading
Loading