@@ -74,6 +74,231 @@ fn test_dynamic_function_price_equal_emission() {
74
74
} ) ;
75
75
}
76
76
77
+ // Verifies that the total stake after the coinbase is only increased by the coinbase emission.
78
+ // Avoids TAO weight.
79
+ // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_total_stake_after_coinbase_no_tao_weight --exact --show-output --nocapture
80
+ #[ test]
81
+ fn test_total_stake_after_coinbase_no_tao_weight ( ) {
82
+ new_test_ext ( 1 ) . execute_with ( || {
83
+ let netuid: u16 = 1 ;
84
+ add_network ( netuid, 1 , 0 ) ;
85
+ // Set TAO weight to 0
86
+ SubtensorModule :: set_tao_weight ( 0 ) ;
87
+ // Set owner cut to ~11.11%
88
+ SubtensorModule :: set_subnet_owner_cut ( u16:: MAX / 9 ) ;
89
+ let total_coinbase_emission: I96F32 = I96F32 :: from_num ( 1_123_456_789 ) ;
90
+ let epsilon: u64 = 100 ;
91
+
92
+ // Define hotkeys and coldkeys
93
+ let hotkey_a: U256 = U256 :: from ( 1 ) ;
94
+ let hotkey_b: U256 = U256 :: from ( 2 ) ;
95
+ let hotkey_c: U256 = U256 :: from ( 3 ) ;
96
+ let coldkey_a: U256 = U256 :: from ( 100 ) ;
97
+ let coldkey_b: U256 = U256 :: from ( 101 ) ;
98
+ let coldkey_c: U256 = U256 :: from ( 102 ) ;
99
+
100
+ // Register neurons with decreasing stakes
101
+ register_ok_neuron ( netuid, hotkey_a, coldkey_a, 0 ) ;
102
+ register_ok_neuron ( netuid, hotkey_b, coldkey_b, 0 ) ;
103
+ register_ok_neuron ( netuid, hotkey_c, coldkey_c, 0 ) ;
104
+
105
+ // Add initial stakes
106
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_a, 1_000 ) ;
107
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_b, 1_000 ) ;
108
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_c, 1_000 ) ;
109
+
110
+ // Swap to alpha
111
+ let total_tao: I96F32 = I96F32 :: from_num ( 300_000 + 100_000 + 50_000 ) ;
112
+ let total_alpha: I96F32 = I96F32 :: from_num ( SubtensorModule :: swap_tao_for_alpha (
113
+ netuid,
114
+ total_tao. saturating_to_num :: < u64 > ( ) ,
115
+ ) ) ;
116
+
117
+ // Set the stakes directly
118
+ // This avoids needing to swap tao to alpha, impacting the initial stake distribution.
119
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
120
+ & hotkey_a,
121
+ & coldkey_a,
122
+ netuid,
123
+ ( total_alpha * I96F32 :: from_num ( 300_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
124
+ ) ;
125
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
126
+ & hotkey_b,
127
+ & coldkey_b,
128
+ netuid,
129
+ ( total_alpha * I96F32 :: from_num ( 100_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
130
+ ) ;
131
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
132
+ & hotkey_c,
133
+ & coldkey_c,
134
+ netuid,
135
+ ( total_alpha * I96F32 :: from_num ( 50_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
136
+ ) ;
137
+
138
+ // Get the total stake on the network
139
+ let mut total_stake_before = 0 ;
140
+ for ( hotkey, netuid_i, alpha) in TotalHotkeyAlpha :: < Test > :: iter ( ) {
141
+ if netuid_i == netuid {
142
+ total_stake_before += alpha;
143
+ } else {
144
+ assert ! (
145
+ alpha == 0 ,
146
+ "Alpha should be 0 for non-subnet hotkeys, but is {:?} on netuid {:?}" ,
147
+ alpha,
148
+ netuid_i
149
+ ) ;
150
+ }
151
+ }
152
+
153
+ log:: info!( "total_stake_before: {:?}" , total_stake_before) ;
154
+
155
+ // Run the coinbase
156
+ SubtensorModule :: run_coinbase ( total_coinbase_emission) ;
157
+
158
+ // Get the total stake on the network
159
+ let mut total_stake_after = 0 ;
160
+ for ( hotkey, netuid_i, alpha) in TotalHotkeyAlpha :: < Test > :: iter ( ) {
161
+ if netuid_i == netuid {
162
+ total_stake_after += alpha;
163
+ } else {
164
+ assert ! (
165
+ alpha == 0 ,
166
+ "Alpha should be 0 for non-subnet hotkeys, but is {:?} on netuid {:?}" ,
167
+ alpha,
168
+ netuid_i
169
+ ) ;
170
+ }
171
+ }
172
+ assert_abs_diff_eq ! (
173
+ total_stake_after,
174
+ total_stake_before + total_coinbase_emission. saturating_to_num:: <u64 >( ) ,
175
+ epsilon = epsilon
176
+ ) ;
177
+ } ) ;
178
+ }
179
+
180
+ // Verifies that the total stake after the coinbase is only increased by the coinbase emission.
181
+ // Includes TAO weight.
182
+ // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_total_stake_after_coinbase --exact --show-output --nocapture
183
+ #[ test]
184
+ fn test_total_stake_after_coinbase ( ) {
185
+ new_test_ext ( 1 ) . execute_with ( || {
186
+ let netuid: u16 = 1 ;
187
+ add_network ( netuid, 1 , 0 ) ;
188
+ // Set TAO weight to 18%
189
+ SubtensorModule :: set_tao_weight ( I96F32 :: from_num ( 0.18 ) . saturating_to_num :: < u64 > ( ) ) ;
190
+ // Set owner cut to ~11.11%
191
+ SubtensorModule :: set_subnet_owner_cut ( u16:: MAX / 9 ) ;
192
+ let total_coinbase_emission: I96F32 = I96F32 :: from_num ( 1_123_456_789 ) ;
193
+ let epsilon: u64 = 100 ;
194
+
195
+ // Define hotkeys and coldkeys
196
+ let hotkey_a: U256 = U256 :: from ( 1 ) ;
197
+ let hotkey_b: U256 = U256 :: from ( 2 ) ;
198
+ let hotkey_c: U256 = U256 :: from ( 3 ) ;
199
+ let coldkey_a: U256 = U256 :: from ( 100 ) ;
200
+ let coldkey_b: U256 = U256 :: from ( 101 ) ;
201
+ let coldkey_c: U256 = U256 :: from ( 102 ) ;
202
+
203
+ // Register neurons with decreasing stakes
204
+ register_ok_neuron ( netuid, hotkey_a, coldkey_a, 0 ) ;
205
+ register_ok_neuron ( netuid, hotkey_b, coldkey_b, 0 ) ;
206
+ register_ok_neuron ( netuid, hotkey_c, coldkey_c, 0 ) ;
207
+
208
+ // Add initial stakes
209
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_a, 1_000 ) ;
210
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_b, 1_000 ) ;
211
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_c, 1_000 ) ;
212
+
213
+ // Swap to alpha
214
+ let total_tao: I96F32 = I96F32 :: from_num ( 300_000 + 100_000 + 50_000 ) ;
215
+ let total_alpha: I96F32 = I96F32 :: from_num ( SubtensorModule :: swap_tao_for_alpha (
216
+ netuid,
217
+ total_tao. saturating_to_num :: < u64 > ( ) ,
218
+ ) ) ;
219
+
220
+ // Set the stakes directly
221
+ // This avoids needing to swap tao to alpha, impacting the initial stake distribution.
222
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
223
+ & hotkey_a,
224
+ & coldkey_a,
225
+ netuid,
226
+ ( total_alpha * I96F32 :: from_num ( 300_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
227
+ ) ;
228
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
229
+ & hotkey_b,
230
+ & coldkey_b,
231
+ netuid,
232
+ ( total_alpha * I96F32 :: from_num ( 100_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
233
+ ) ;
234
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
235
+ & hotkey_c,
236
+ & coldkey_c,
237
+ netuid,
238
+ ( total_alpha * I96F32 :: from_num ( 50_000 ) / total_tao) . saturating_to_num :: < u64 > ( ) ,
239
+ ) ;
240
+
241
+ // Stake some to root
242
+ let stake_to_root: u64 = 10_000_000 ;
243
+ SubtensorModule :: add_balance_to_coldkey_account ( & coldkey_a, stake_to_root) ;
244
+ SubtensorModule :: increase_stake_for_hotkey_and_coldkey_on_subnet (
245
+ & hotkey_a,
246
+ & coldkey_a,
247
+ netuid,
248
+ stake_to_root,
249
+ ) ;
250
+
251
+ let alpha_price = SubtensorModule :: get_alpha_price ( netuid) ;
252
+ log:: info!( "alpha_price: {:?}" , alpha_price) ;
253
+
254
+ // Get the total stake on the network
255
+ let mut total_stake_before = 0 ;
256
+ for ( hotkey, netuid_i, alpha) in TotalHotkeyAlpha :: < Test > :: iter ( ) {
257
+ if netuid_i == netuid {
258
+ total_stake_before += alpha;
259
+ } else if netuid == SubtensorModule :: get_root_netuid ( ) {
260
+ let as_alpha: I96F32 = I96F32 :: from_num ( alpha) / alpha_price;
261
+ total_stake_before += as_alpha. saturating_to_num :: < u64 > ( ) ;
262
+ } else {
263
+ assert ! (
264
+ alpha == 0 ,
265
+ "Alpha should be 0 for non-subnet hotkeys, but is {:?} on netuid {:?}" ,
266
+ alpha,
267
+ netuid_i
268
+ ) ;
269
+ }
270
+ }
271
+
272
+ log:: info!( "total_stake_before: {:?}" , total_stake_before) ;
273
+
274
+ // Run the coinbase
275
+ SubtensorModule :: run_coinbase ( total_coinbase_emission) ;
276
+
277
+ // Get the total stake on the network
278
+ let mut total_stake_after = 0 ;
279
+ for ( hotkey, netuid_i, alpha) in TotalHotkeyAlpha :: < Test > :: iter ( ) {
280
+ if netuid_i == netuid {
281
+ total_stake_after += alpha;
282
+ } else if netuid == SubtensorModule :: get_root_netuid ( ) {
283
+ let as_alpha: I96F32 = I96F32 :: from_num ( alpha) / alpha_price;
284
+ total_stake_after += as_alpha. saturating_to_num :: < u64 > ( ) ;
285
+ } else {
286
+ assert ! (
287
+ alpha == 0 ,
288
+ "Alpha should be 0 for non-subnet hotkeys, but is {:?} on netuid {:?}" ,
289
+ alpha,
290
+ netuid_i
291
+ ) ;
292
+ }
293
+ }
294
+ assert_abs_diff_eq ! (
295
+ total_stake_after,
296
+ total_stake_before + total_coinbase_emission. saturating_to_num:: <u64 >( ) ,
297
+ epsilon = epsilon
298
+ ) ;
299
+ } ) ;
300
+ }
301
+
77
302
// Verifies that the total issuance after the coinbase is only increased by the coinbase emission.
78
303
// Includes TAO weight.
79
304
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_total_issuance_after_coinbase --exact --show-output --nocapture
0 commit comments