Skip to content

Commit 30475f1

Browse files
committed
Merge branch 'nonclaim' of github.com:opentensor/subtensor into nonclaim
2 parents ba80bbb + e4ccdfa commit 30475f1

File tree

2 files changed

+208
-3
lines changed

2 files changed

+208
-3
lines changed

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ impl<T: Config> Pallet<T> {
4848
let mut total_moving_prices: I96F32 = I96F32::from_num(0.0);
4949
for netuid_i in subnets.iter() {
5050
// Get and update the moving price of each subnet adding the total together.
51-
Self::update_moving_price(*netuid_i);
52-
total_moving_prices =
53-
total_moving_prices.saturating_add(Self::get_moving_alpha_price(*netuid_i));
51+
total_moving_prices = total_moving_prices.saturating_add( Self::get_moving_alpha_price( *netuid_i ) );
5452
}
5553
log::debug!("total_moving_prices: {:?}", total_moving_prices);
5654

@@ -188,6 +186,12 @@ impl<T: Config> Pallet<T> {
188186
});
189187
}
190188

189+
// --- 7 Update moving prices after using them in the emission calculation.
190+
for netuid_i in subnets.iter() {
191+
// Update moving prices after using them above.
192+
Self::update_moving_price( *netuid_i );
193+
}
194+
191195
// --- 7. Drain pending emission through the subnet based on tempo.
192196
for &netuid in subnets.iter() {
193197
// Pass on subnets that have not reached their tempo.

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,204 @@ fn test_dynamic_function_various_values() {
4848
}
4949
});
5050
}
51+
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+
// Test moving price updates with different alpha values.
147+
// This test verifies that:
148+
// - Moving price stays constant when alpha is 1.0
149+
// - Moving price converges to real price at expected rate with alpha 0.1
150+
// - Moving price updates correctly over multiple iterations
151+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_moving_prices --exact --show-output --nocapture
152+
#[test]
153+
fn test_coinbase_moving_prices() {
154+
new_test_ext(1).execute_with(|| {
155+
let netuid: u16 = 1;
156+
add_network(netuid, 1, 0);
157+
// Set price to 1.0
158+
SubnetTAO::<Test>::insert(netuid, 1_000_000);
159+
SubnetAlphaIn::<Test>::insert(netuid, 1_000_000);
160+
SubnetMechanism::<Test>::insert(netuid, 1);
161+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(1) );
162+
// Updating the moving price keeps it the same.
163+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1) );
164+
SubtensorModule::update_moving_price( netuid );
165+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1) );
166+
// Check alpha of 1.
167+
// Set price to zero.
168+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(0) );
169+
SubnetMovingAlpha::<Test>::set( I96F32::from_num(1.0) );
170+
// Run moving 1 times.
171+
SubtensorModule::update_moving_price( netuid );
172+
// Assert price is == 100% of the real price.
173+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1.0) );
174+
// Set price to zero.
175+
SubnetMovingPrice::<Test>::insert( netuid, I96F32::from_num(0) );
176+
SubnetMovingAlpha::<Test>::set( I96F32::from_num(0.1) );
177+
// Run moving 6 times.
178+
SubtensorModule::update_moving_price( netuid );
179+
SubtensorModule::update_moving_price( netuid );
180+
SubtensorModule::update_moving_price( netuid );
181+
SubtensorModule::update_moving_price( netuid );
182+
SubtensorModule::update_moving_price( netuid );
183+
SubtensorModule::update_moving_price( netuid );
184+
// Assert price is > 50% of the real price.
185+
assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(0.468559) );
186+
});
187+
}
188+
189+
// Test basic alpha issuance in coinbase mechanism.
190+
// This test verifies that:
191+
// - Alpha issuance is initialized to 0 for new subnets
192+
// - Alpha issuance is split evenly between subnets during coinbase
193+
// - Each subnet receives the expected fraction of total emission
194+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_alpha_issuance --exact --show-output --nocapture
195+
#[test]
196+
fn test_coinbase_alpha_issuance_base() {
197+
new_test_ext(1).execute_with(|| {
198+
let netuid1: u16 = 1;
199+
let netuid2: u16 = 2;
200+
let emission: u64 = 1_000_000;
201+
add_network(netuid1, 1, 0);
202+
add_network(netuid2, 1, 0);
203+
// Set up prices 1 and 1
204+
SubnetTAO::<Test>::insert(netuid1, 1_000_000);
205+
SubnetAlphaIn::<Test>::insert(netuid1, 1_000_000);
206+
SubnetTAO::<Test>::insert(netuid2, 1_000_000);
207+
SubnetAlphaIn::<Test>::insert(netuid2, 1_000_000);
208+
// Check initial
209+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid1 ), 0);
210+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid2 ), 0);
211+
SubtensorModule::run_coinbase( I96F32::from_num( emission ) );
212+
// tao_in = 500_000
213+
// alpha_in = 500_000/price = 500_000
214+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid1 ), emission/2);
215+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid2 ), emission/2);
216+
});
217+
}
218+
219+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_coinbase_alpha_issuance_different --exact --show-output --nocapture
220+
#[test]
221+
fn test_coinbase_alpha_issuance_different() {
222+
new_test_ext(1).execute_with(|| {
223+
let netuid1: u16 = 1;
224+
let netuid2: u16 = 2;
225+
let emission: u64 = 1_000_000;
226+
add_network(netuid1, 1, 0);
227+
add_network(netuid2, 1, 0);
228+
// Make subnets dynamic.
229+
SubnetMechanism::<Test>::insert(netuid1, 1);
230+
SubnetMechanism::<Test>::insert(netuid2, 1);
231+
// Setup prices 1 and 1
232+
let initial: u64 = 1_000_000;
233+
SubnetTAO::<Test>::insert(netuid1, initial);
234+
SubnetAlphaIn::<Test>::insert(netuid1, initial);
235+
SubnetTAO::<Test>::insert(netuid2, initial);
236+
SubnetAlphaIn::<Test>::insert(netuid2, initial);
237+
// Set subnet prices.
238+
SubnetMovingPrice::<Test>::insert( netuid1, I96F32::from_num(1) );
239+
SubnetMovingPrice::<Test>::insert( netuid2, I96F32::from_num(2) );
240+
// Run coinbase
241+
SubtensorModule::run_coinbase( I96F32::from_num( emission ) );
242+
// tao_in = 333_333
243+
// alpha_in = 333_333/price = 333_333 + initial
244+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid1 ), initial + emission/3);
245+
// tao_in = 666_666
246+
// alpha_in = 666_666/price = 666_666 + initial
247+
assert_eq!( SubnetAlphaIn::<Test>::get( netuid2 ), initial + emission/3 + emission/3);
248+
});
249+
}
250+
251+

0 commit comments

Comments
 (0)