Skip to content

Commit 1f520ed

Browse files
authored
Merge pull request #2177 from opentensor/testnet
hotfix 11/4/2025
2 parents 6218ecc + 71455aa commit 1f520ed

File tree

7 files changed

+507
-430
lines changed

7 files changed

+507
-430
lines changed

pallets/subtensor/src/coinbase/subnet_emissions.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl<T: Config> Pallet<T> {
5151

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

@@ -75,10 +76,11 @@ impl<T: Config> Pallet<T> {
7576
}
7677
} else {
7778
// Initialize EMA flow, set S(current_block) = min(price, ema_price) * init_factor
79+
let init_factor = I64F64::saturating_from_num(1_000_000_000);
7880
let moving_price = I64F64::saturating_from_num(Self::get_moving_alpha_price(netuid));
7981
let current_price =
8082
I64F64::saturating_from_num(T::SwapInterface::current_alpha_price(netuid));
81-
let ema_flow = moving_price.min(current_price);
83+
let ema_flow = init_factor.saturating_mul(moving_price.min(current_price));
8284
SubnetEmaTaoFlow::<T>::insert(netuid, (current_block, ema_flow));
8385
ema_flow
8486
}
@@ -87,6 +89,7 @@ impl<T: Config> Pallet<T> {
8789
// Either the minimal EMA flow L = min{Si}, or an artificial
8890
// cut off at some higher value A (TaoFlowCutoff)
8991
// L = max {A, min{min{S[i], 0}}}
92+
#[allow(dead_code)]
9093
fn get_lower_limit(ema_flows: &BTreeMap<NetUid, I64F64>) -> I64F64 {
9194
let zero = I64F64::saturating_from_num(0);
9295
let min_flow = ema_flows
@@ -178,6 +181,7 @@ impl<T: Config> Pallet<T> {
178181
}
179182

180183
// Implementation of shares that uses TAO flow
184+
#[allow(dead_code)]
181185
fn get_shares_flow(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
182186
// Get raw flows
183187
let ema_flows = subnets_to_emit_to
@@ -213,5 +217,35 @@ impl<T: Config> Pallet<T> {
213217
// Combines ema price method and tao flow method linearly over FlowHalfLife blocks
214218
pub(crate) fn get_shares(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
215219
Self::get_shares_flow(subnets_to_emit_to)
220+
// Self::get_shares_price_ema(subnets_to_emit_to)
221+
}
222+
223+
// DEPRECATED: Implementation of shares that uses EMA prices will be gradually deprecated
224+
#[allow(dead_code)]
225+
fn get_shares_price_ema(subnets_to_emit_to: &[NetUid]) -> BTreeMap<NetUid, U64F64> {
226+
// Get sum of alpha moving prices
227+
let total_moving_prices = subnets_to_emit_to
228+
.iter()
229+
.map(|netuid| U64F64::saturating_from_num(Self::get_moving_alpha_price(*netuid)))
230+
.fold(U64F64::saturating_from_num(0.0), |acc, ema| {
231+
acc.saturating_add(ema)
232+
});
233+
log::debug!("total_moving_prices: {total_moving_prices:?}");
234+
235+
// Calculate shares.
236+
subnets_to_emit_to
237+
.iter()
238+
.map(|netuid| {
239+
let moving_price =
240+
U64F64::saturating_from_num(Self::get_moving_alpha_price(*netuid));
241+
log::debug!("moving_price_i: {moving_price:?}");
242+
243+
let share = moving_price
244+
.checked_div(total_moving_prices)
245+
.unwrap_or(U64F64::saturating_from_num(0));
246+
247+
(*netuid, share)
248+
})
249+
.collect::<BTreeMap<NetUid, U64F64>>()
216250
}
217251
}

pallets/subtensor/src/macros/hooks.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ mod hooks {
159159
// Migrate Kappa to default (0.5)
160160
.saturating_add(migrations::migrate_kappa_map_to_default::migrate_kappa_map_to_default::<T>())
161161
// Remove obsolete map entries
162-
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>());
162+
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>())
163+
// Re-init tao flows
164+
.saturating_add(migrations::migrate_init_tao_flow::migrate_init_tao_flow::<T>());
163165
weight
164166
}
165167

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use alloc::string::String;
2+
3+
use frame_support::{traits::Get, weights::Weight};
4+
5+
use super::*;
6+
7+
pub fn migrate_init_tao_flow<T: Config>() -> Weight {
8+
let migration_name = b"migrate_init_tao_flow".to_vec();
9+
10+
// Initialize the weight with one read operation.
11+
let mut weight = T::DbWeight::get().reads(1);
12+
13+
// Check if the migration has already run
14+
if HasMigrationRun::<T>::get(&migration_name) {
15+
log::info!(
16+
"Migration '{:?}' has already run. Skipping.",
17+
String::from_utf8_lossy(&migration_name)
18+
);
19+
return weight;
20+
}
21+
log::info!(
22+
"Running migration '{}'",
23+
String::from_utf8_lossy(&migration_name)
24+
);
25+
26+
let _ = SubnetEmaTaoFlow::<T>::clear(u32::MAX, None);
27+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
28+
29+
// Mark the migration as completed
30+
HasMigrationRun::<T>::insert(&migration_name, true);
31+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
32+
33+
log::info!(
34+
"Migration '{:?}' completed.",
35+
String::from_utf8_lossy(&migration_name)
36+
);
37+
38+
// Return the migration weight.
39+
weight
40+
}

pallets/subtensor/src/migrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub mod migrate_fix_is_network_member;
2020
pub mod migrate_fix_root_subnet_tao;
2121
pub mod migrate_fix_root_tao_and_alpha_in;
2222
pub mod migrate_identities_v2;
23+
pub mod migrate_init_tao_flow;
2324
pub mod migrate_init_total_issuance;
2425
pub mod migrate_kappa_map_to_default;
2526
pub mod migrate_network_immunity_period;

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -115,28 +115,28 @@ fn test_coinbase_tao_issuance_base_low() {
115115
}
116116

117117
// 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
118-
#[test]
119-
fn test_coinbase_tao_issuance_base_low_flow() {
120-
new_test_ext(1).execute_with(|| {
121-
let emission = TaoCurrency::from(1_234_567);
122-
let subnet_owner_ck = U256::from(1001);
123-
let subnet_owner_hk = U256::from(1002);
124-
let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
125-
let emission = TaoCurrency::from(1);
126-
127-
// 100% tao flow method
128-
let block_num = FlowHalfLife::<Test>::get();
129-
SubnetEmaTaoFlow::<Test>::insert(netuid, (block_num, I64F64::from_num(1_000_000_000)));
130-
System::set_block_number(block_num);
131-
132-
let tao_in_before = SubnetTAO::<Test>::get(netuid);
133-
let total_stake_before = TotalStake::<Test>::get();
134-
SubtensorModule::run_coinbase(U96F32::from_num(emission));
135-
assert_eq!(SubnetTAO::<Test>::get(netuid), tao_in_before + emission);
136-
assert_eq!(TotalIssuance::<Test>::get(), emission);
137-
assert_eq!(TotalStake::<Test>::get(), total_stake_before + emission);
138-
});
139-
}
118+
// #[test]
119+
// fn test_coinbase_tao_issuance_base_low_flow() {
120+
// new_test_ext(1).execute_with(|| {
121+
// let emission = TaoCurrency::from(1_234_567);
122+
// let subnet_owner_ck = U256::from(1001);
123+
// let subnet_owner_hk = U256::from(1002);
124+
// let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
125+
// let emission = TaoCurrency::from(1);
126+
127+
// // 100% tao flow method
128+
// let block_num = FlowHalfLife::<Test>::get();
129+
// SubnetEmaTaoFlow::<Test>::insert(netuid, (block_num, I64F64::from_num(1_000_000_000)));
130+
// System::set_block_number(block_num);
131+
132+
// let tao_in_before = SubnetTAO::<Test>::get(netuid);
133+
// let total_stake_before = TotalStake::<Test>::get();
134+
// SubtensorModule::run_coinbase(U96F32::from_num(emission));
135+
// assert_eq!(SubnetTAO::<Test>::get(netuid), tao_in_before + emission);
136+
// assert_eq!(TotalIssuance::<Test>::get(), emission);
137+
// assert_eq!(TotalStake::<Test>::get(), total_stake_before + emission);
138+
// });
139+
// }
140140

141141
// Test emission distribution across multiple subnets.
142142
// This test verifies that:
@@ -260,85 +260,85 @@ fn test_coinbase_tao_issuance_different_prices() {
260260
}
261261

262262
// 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
263-
#[test]
264-
fn test_coinbase_tao_issuance_different_flows() {
265-
new_test_ext(1).execute_with(|| {
266-
let subnet_owner_ck = U256::from(1001);
267-
let subnet_owner_hk = U256::from(1002);
268-
let netuid1 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
269-
let netuid2 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
270-
let emission = 100_000_000;
271-
272-
// Setup prices 0.1 and 0.2
273-
let initial_tao: u64 = 100_000_u64;
274-
let initial_alpha1: u64 = initial_tao * 10;
275-
let initial_alpha2: u64 = initial_tao * 5;
276-
mock::setup_reserves(netuid1, initial_tao.into(), initial_alpha1.into());
277-
mock::setup_reserves(netuid2, initial_tao.into(), initial_alpha2.into());
278-
279-
// Force the swap to initialize
280-
SubtensorModule::swap_tao_for_alpha(
281-
netuid1,
282-
TaoCurrency::ZERO,
283-
1_000_000_000_000.into(),
284-
false,
285-
)
286-
.unwrap();
287-
SubtensorModule::swap_tao_for_alpha(
288-
netuid2,
289-
TaoCurrency::ZERO,
290-
1_000_000_000_000.into(),
291-
false,
292-
)
293-
.unwrap();
294-
295-
// Set subnet prices to reversed proportion to ensure they don't affect emissions.
296-
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(2));
297-
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(1));
298-
299-
// Set subnet tao flow ema.
300-
let block_num = FlowHalfLife::<Test>::get();
301-
SubnetEmaTaoFlow::<Test>::insert(netuid1, (block_num, I64F64::from_num(1)));
302-
SubnetEmaTaoFlow::<Test>::insert(netuid2, (block_num, I64F64::from_num(2)));
303-
System::set_block_number(block_num);
304-
305-
// Set normalization exponent to 1 for simplicity
306-
FlowNormExponent::<Test>::set(U64F64::from(1_u64));
307-
308-
// Assert initial TAO reserves.
309-
assert_eq!(SubnetTAO::<Test>::get(netuid1), initial_tao.into());
310-
assert_eq!(SubnetTAO::<Test>::get(netuid2), initial_tao.into());
311-
let total_stake_before = TotalStake::<Test>::get();
312-
313-
// Run the coinbase with the emission amount.
314-
SubtensorModule::run_coinbase(U96F32::from_num(emission));
315-
316-
// Assert tao emission is split evenly.
317-
assert_abs_diff_eq!(
318-
SubnetTAO::<Test>::get(netuid1),
319-
TaoCurrency::from(initial_tao + emission / 3),
320-
epsilon = 10.into(),
321-
);
322-
assert_abs_diff_eq!(
323-
SubnetTAO::<Test>::get(netuid2),
324-
TaoCurrency::from(initial_tao + 2 * emission / 3),
325-
epsilon = 10.into(),
326-
);
263+
// #[test]
264+
// fn test_coinbase_tao_issuance_different_flows() {
265+
// new_test_ext(1).execute_with(|| {
266+
// let subnet_owner_ck = U256::from(1001);
267+
// let subnet_owner_hk = U256::from(1002);
268+
// let netuid1 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
269+
// let netuid2 = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
270+
// let emission = 100_000_000;
271+
272+
// // Setup prices 0.1 and 0.2
273+
// let initial_tao: u64 = 100_000_u64;
274+
// let initial_alpha1: u64 = initial_tao * 10;
275+
// let initial_alpha2: u64 = initial_tao * 5;
276+
// mock::setup_reserves(netuid1, initial_tao.into(), initial_alpha1.into());
277+
// mock::setup_reserves(netuid2, initial_tao.into(), initial_alpha2.into());
278+
279+
// // Force the swap to initialize
280+
// SubtensorModule::swap_tao_for_alpha(
281+
// netuid1,
282+
// TaoCurrency::ZERO,
283+
// 1_000_000_000_000.into(),
284+
// false,
285+
// )
286+
// .unwrap();
287+
// SubtensorModule::swap_tao_for_alpha(
288+
// netuid2,
289+
// TaoCurrency::ZERO,
290+
// 1_000_000_000_000.into(),
291+
// false,
292+
// )
293+
// .unwrap();
294+
295+
// // Set subnet prices to reversed proportion to ensure they don't affect emissions.
296+
// SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(2));
297+
// SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(1));
298+
299+
// // Set subnet tao flow ema.
300+
// let block_num = FlowHalfLife::<Test>::get();
301+
// SubnetEmaTaoFlow::<Test>::insert(netuid1, (block_num, I64F64::from_num(1)));
302+
// SubnetEmaTaoFlow::<Test>::insert(netuid2, (block_num, I64F64::from_num(2)));
303+
// System::set_block_number(block_num);
304+
305+
// // Set normalization exponent to 1 for simplicity
306+
// FlowNormExponent::<Test>::set(U64F64::from(1_u64));
307+
308+
// // Assert initial TAO reserves.
309+
// assert_eq!(SubnetTAO::<Test>::get(netuid1), initial_tao.into());
310+
// assert_eq!(SubnetTAO::<Test>::get(netuid2), initial_tao.into());
311+
// let total_stake_before = TotalStake::<Test>::get();
312+
313+
// // Run the coinbase with the emission amount.
314+
// SubtensorModule::run_coinbase(U96F32::from_num(emission));
315+
316+
// // Assert tao emission is split evenly.
317+
// assert_abs_diff_eq!(
318+
// SubnetTAO::<Test>::get(netuid1),
319+
// TaoCurrency::from(initial_tao + emission / 3),
320+
// epsilon = 10.into(),
321+
// );
322+
// assert_abs_diff_eq!(
323+
// SubnetTAO::<Test>::get(netuid2),
324+
// TaoCurrency::from(initial_tao + 2 * emission / 3),
325+
// epsilon = 10.into(),
326+
// );
327327

328-
// Prices are low => we limit tao issued (buy alpha with it)
329-
let tao_issued = TaoCurrency::from(((0.1 + 0.2) * emission as f64) as u64);
330-
assert_abs_diff_eq!(
331-
TotalIssuance::<Test>::get(),
332-
tao_issued,
333-
epsilon = 10.into()
334-
);
335-
assert_abs_diff_eq!(
336-
TotalStake::<Test>::get(),
337-
total_stake_before + emission.into(),
338-
epsilon = 10.into()
339-
);
340-
});
341-
}
328+
// // Prices are low => we limit tao issued (buy alpha with it)
329+
// let tao_issued = TaoCurrency::from(((0.1 + 0.2) * emission as f64) as u64);
330+
// assert_abs_diff_eq!(
331+
// TotalIssuance::<Test>::get(),
332+
// tao_issued,
333+
// epsilon = 10.into()
334+
// );
335+
// assert_abs_diff_eq!(
336+
// TotalStake::<Test>::get(),
337+
// total_stake_before + emission.into(),
338+
// epsilon = 10.into()
339+
// );
340+
// });
341+
// }
342342

343343
// Test moving price updates with different alpha values.
344344
// This test verifies that:

0 commit comments

Comments
 (0)