Skip to content

Commit f91e7ca

Browse files
author
unconst
committed
add moving price tests
1 parent b2639e7 commit f91e7ca

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ impl<T: Config> Pallet<T> {
4747
let mut total_moving_prices: I96F32 = I96F32::from_num(0.0);
4848
for netuid_i in subnets.iter() {
4949
// Get and update the moving price of each subnet adding the total together.
50-
Self::update_moving_price( *netuid_i );
5150
total_moving_prices = total_moving_prices.saturating_add( Self::get_moving_alpha_price( *netuid_i ) );
5251
}
5352
log::debug!("total_moving_prices: {:?}", total_moving_prices);
@@ -180,6 +179,12 @@ impl<T: Config> Pallet<T> {
180179
});
181180
}
182181

182+
// --- 7 Update moving prices after using them in the emission calculation.
183+
for netuid_i in subnets.iter() {
184+
// Update moving prices after using them above.
185+
Self::update_moving_price( *netuid_i );
186+
}
187+
183188
// --- 7. Drain pending emission through the subnet based on tempo.
184189
for &netuid in subnets.iter() {
185190
// Pass on subnets that have not reached their tempo.

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,137 @@ fn test_dynamic_function_various_values() {
4949
});
5050
}
5151

52+
53+
// Test the base case of running coinbase with zero emission.
54+
// This test verifies that the coinbase mechanism can handle the edge case
55+
// of zero emission without errors or unexpected behavior.
56+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_basecase --exact --show-output --nocapture
57+
#[test]
58+
fn test_coinbase_basecase() {
59+
new_test_ext(1).execute_with(|| {
60+
SubtensorModule::run_coinbase( I96F32::from_num(0.0) );
61+
});
62+
}
63+
64+
// Test the emission distribution for a single subnet.
65+
// This test verifies that:
66+
// - A single subnet receives the full emission amount
67+
// - The emission is correctly reflected in SubnetTAO
68+
// - Total issuance and total stake are updated appropriately
69+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_tao_issuance_base --exact --show-output --nocapture
70+
#[test]
71+
fn test_coinbase_tao_issuance_base() {
72+
new_test_ext(1).execute_with(|| {
73+
let netuid: u16 = 1;
74+
let emission: u64 = 1_234_567;
75+
add_network(netuid, 1, 0);
76+
assert_eq!( SubnetTAO::<Test>::get( netuid ), 0);
77+
SubtensorModule::run_coinbase( I96F32::from_num( emission ) );
78+
assert_eq!( SubnetTAO::<Test>::get( netuid ), emission);
79+
assert_eq!( TotalIssuance::<Test>::get(), emission);
80+
assert_eq!( TotalStake::<Test>::get(), emission);
81+
});
82+
}
83+
84+
// Test emission distribution across multiple subnets.
85+
// This test verifies that:
86+
// - Multiple subnets receive equal portions of the total emission
87+
// - Each subnet's TAO balance is updated correctly
88+
// - Total issuance and total stake reflect the full emission amount
89+
// - The emission is split evenly between all subnets
90+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_tao_issuance_multiple --exact --show-output --nocapture
91+
#[test]
92+
fn test_coinbase_tao_issuance_multiple() {
93+
new_test_ext(1).execute_with(|| {
94+
let netuid1: u16 = 1;
95+
let netuid2: u16 = 2;
96+
let netuid3: u16 = 3;
97+
let emission: u64 = 3_333_333;
98+
add_network(netuid1, 1, 0);
99+
add_network(netuid2, 1, 0);
100+
add_network(netuid3, 1, 0);
101+
assert_eq!( SubnetTAO::<Test>::get( netuid1 ), 0);
102+
assert_eq!( SubnetTAO::<Test>::get( netuid2 ), 0);
103+
assert_eq!( SubnetTAO::<Test>::get( netuid3 ), 0);
104+
SubtensorModule::run_coinbase( I96F32::from_num( emission ) );
105+
assert_eq!( SubnetTAO::<Test>::get( netuid1 ), emission/3);
106+
assert_eq!( SubnetTAO::<Test>::get( netuid2 ), emission/3);
107+
assert_eq!( SubnetTAO::<Test>::get( netuid3 ), emission/3);
108+
assert_eq!( TotalIssuance::<Test>::get(), emission);
109+
assert_eq!( TotalStake::<Test>::get(), emission);
110+
});
111+
}
112+
113+
// Test emission distribution with different subnet prices.
114+
// This test verifies that:
115+
// - Subnets with different prices receive proportional emission shares
116+
// - A subnet with double the price receives double the emission
117+
// - Total issuance and total stake reflect the full emission amount
118+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_tao_issuance_different_prices --exact --show-output --nocapture
119+
#[test]
120+
fn test_coinbase_tao_issuance_different_prices() {
121+
new_test_ext(1).execute_with(|| {
122+
let netuid1: u16 = 1;
123+
let netuid2: u16 = 2;
124+
let emission: u64 = 100_000_000;
125+
add_network(netuid1, 1, 0);
126+
add_network(netuid2, 1, 0);
127+
// Make subnets dynamic.
128+
SubnetMechanism::<Test>::insert(netuid1, 1);
129+
SubnetMechanism::<Test>::insert(netuid2, 1);
130+
// Set subnet prices.
131+
SubnetMovingPrice::<Test>::insert( netuid1, I96F32::from_num(1) );
132+
SubnetMovingPrice::<Test>::insert( netuid2, I96F32::from_num(2) );
133+
// Assert initial TAO reserves.
134+
assert_eq!( SubnetTAO::<Test>::get( netuid1 ), 0);
135+
assert_eq!( SubnetTAO::<Test>::get( netuid2 ), 0);
136+
// Run the coinbase with the emission amount.
137+
SubtensorModule::run_coinbase( I96F32::from_num( emission ) );
138+
// Assert tao emission is split evenly.
139+
assert_eq!( SubnetTAO::<Test>::get( netuid1 ), emission/3 );
140+
assert_eq!( SubnetTAO::<Test>::get( netuid2 ), emission/3 + emission/3);
141+
close( TotalIssuance::<Test>::get(), emission, 2);
142+
close( TotalStake::<Test>::get(), emission, 2);
143+
});
144+
}
145+
146+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_moving_prices --exact --show-output --nocapture
147+
#[test]
148+
fn test_coinbase_moving_prices() {
149+
new_test_ext(1).execute_with(|| {
150+
let netuid: u16 = 1;
151+
add_network(netuid, 1, 0);
152+
// Set price to 1.0
153+
SubnetTAO::<Test>::insert(netuid, 1_000_000);
154+
SubnetAlphaIn::<Test>::insert(netuid, 1_000_000);
155+
SubnetMechanism::<Test>::insert(netuid, 1);
156+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(1) );
157+
// Updating the moving price keeps it the same.
158+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1) );
159+
SubtensorModule::update_moving_price( netuid );
160+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1) );
161+
// Check alpha of 1.
162+
// Set price to zero.
163+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(0) );
164+
SubnetMovingAlpha::<Test>::set( I96F32::from_num(1.0) );
165+
// Run moving 1 times.
166+
SubtensorModule::update_moving_price( netuid );
167+
// Assert price is == 100% of the real price.
168+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1.0) );
169+
// Set price to zero.
170+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(0) );
171+
SubnetMovingAlpha::<Test>::set( I96F32::from_num(0.1) );
172+
// Run moving 6 times.
173+
SubtensorModule::update_moving_price( netuid );
174+
SubtensorModule::update_moving_price( netuid );
175+
SubtensorModule::update_moving_price( netuid );
176+
SubtensorModule::update_moving_price( netuid );
177+
SubtensorModule::update_moving_price( netuid );
178+
SubtensorModule::update_moving_price( netuid );
179+
// Assert price is > 50% of the real price.
180+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(0.468559) );
181+
});
182+
}
183+
184+
185+

0 commit comments

Comments
 (0)