@@ -199,59 +199,73 @@ impl<T: Config> Pallet<T> {
199
199
mining_emission : u64 ,
200
200
) {
201
201
// --- 1. First, calculate the hotkey's share of the emission.
202
- let take_proportion: I64F64 = I64F64 :: from_num ( Self :: get_childkey_take ( hotkey, netuid) )
203
- . saturating_div ( I64F64 :: from_num ( u16:: MAX ) ) ;
204
- let hotkey_take: u64 = take_proportion
205
- . saturating_mul ( I64F64 :: from_num ( validating_emission) )
206
- . to_num :: < u64 > ( ) ;
207
- // NOTE: Only the validation emission should be split amongst parents.
208
-
209
- // --- 2. Compute the remaining emission after the hotkey's share is deducted.
210
- let emission_minus_take: u64 = validating_emission. saturating_sub ( hotkey_take) ;
211
-
212
- // --- 3. Track the remaining emission for accounting purposes.
213
- let mut remaining_emission: u64 = emission_minus_take;
214
-
215
- // --- 4. Calculate the total stake of the hotkey, adjusted by the stakes of parents and children.
202
+ let childkey_take_proportion: I64F64 =
203
+ I64F64 :: from_num ( Self :: get_childkey_take ( hotkey, netuid) )
204
+ . saturating_div ( I64F64 :: from_num ( u16:: MAX ) ) ;
205
+ let mut total_childkey_take: u64 = 0 ;
206
+
207
+ // --- 2. Track the remaining emission for accounting purposes.
208
+ let mut remaining_emission: u64 = validating_emission;
209
+
210
+ // --- 3. Calculate the total stake of the hotkey, adjusted by the stakes of parents and children.
216
211
// Parents contribute to the stake, while children reduce it.
217
212
// If this value is zero, no distribution to anyone is necessary.
218
213
let total_hotkey_stake: u64 = Self :: get_stake_for_hotkey_on_subnet ( hotkey, netuid) ;
219
214
if total_hotkey_stake != 0 {
220
- // --- 5 . If the total stake is not zero, iterate over each parent to determine their contribution to the hotkey's stake,
215
+ // --- 4 . If the total stake is not zero, iterate over each parent to determine their contribution to the hotkey's stake,
221
216
// and calculate their share of the emission accordingly.
222
217
for ( proportion, parent) in Self :: get_parents ( hotkey, netuid) {
223
- // --- 5 .1 Retrieve the parent's stake. This is the raw stake value including nominators.
218
+ // --- 4 .1 Retrieve the parent's stake. This is the raw stake value including nominators.
224
219
let parent_stake: u64 = Self :: get_total_stake_for_hotkey ( & parent) ;
225
220
226
- // --- 5 .2 Calculate the portion of the hotkey's total stake contributed by this parent.
221
+ // --- 4 .2 Calculate the portion of the hotkey's total stake contributed by this parent.
227
222
// Then, determine the parent's share of the remaining emission.
228
223
let stake_from_parent: I96F32 = I96F32 :: from_num ( parent_stake) . saturating_mul (
229
224
I96F32 :: from_num ( proportion) . saturating_div ( I96F32 :: from_num ( u64:: MAX ) ) ,
230
225
) ;
231
226
let proportion_from_parent: I96F32 =
232
227
stake_from_parent. saturating_div ( I96F32 :: from_num ( total_hotkey_stake) ) ;
233
- let parent_emission_take : u64 = proportion_from_parent
234
- . saturating_mul ( I96F32 :: from_num ( emission_minus_take ) )
228
+ let parent_emission : u64 = proportion_from_parent
229
+ . saturating_mul ( I96F32 :: from_num ( validating_emission ) )
235
230
. to_num :: < u64 > ( ) ;
236
231
237
- // --- 5.5. Accumulate emissions for the parent hotkey.
232
+ // --- 4.3 Childkey take as part of parent emission
233
+ let child_emission_take: u64 = childkey_take_proportion
234
+ . saturating_mul ( I64F64 :: from_num ( parent_emission) )
235
+ . to_num :: < u64 > ( ) ;
236
+ total_childkey_take = total_childkey_take. saturating_add ( child_emission_take) ;
237
+ // NOTE: Only the validation emission should be split amongst parents.
238
+
239
+ // --- 4.4 Compute the remaining parent emission after the childkey's share is deducted.
240
+ let parent_emission_take: u64 = parent_emission. saturating_sub ( child_emission_take) ;
241
+
242
+ // --- 4.5. Accumulate emissions for the parent hotkey.
238
243
PendingdHotkeyEmission :: < T > :: mutate ( parent, |parent_accumulated| {
239
244
* parent_accumulated = parent_accumulated. saturating_add ( parent_emission_take)
240
245
} ) ;
241
246
242
- // --- 5.6. Subtract the parent's share from the remaining emission for this hotkey.
243
- remaining_emission = remaining_emission. saturating_sub ( parent_emission_take) ;
247
+ // --- 4.6. Subtract the parent's share from the remaining emission for this hotkey.
248
+ remaining_emission = remaining_emission
249
+ . saturating_sub ( parent_emission_take)
250
+ . saturating_sub ( child_emission_take) ;
244
251
}
245
252
}
246
253
247
- // --- 6 . Add the remaining emission plus the hotkey's initial take to the pending emission for this hotkey.
254
+ // --- 5 . Add the remaining emission plus the hotkey's initial take to the pending emission for this hotkey.
248
255
PendingdHotkeyEmission :: < T > :: mutate ( hotkey, |hotkey_pending| {
249
256
* hotkey_pending = hotkey_pending. saturating_add (
250
257
remaining_emission
251
- . saturating_add ( hotkey_take )
258
+ . saturating_add ( total_childkey_take )
252
259
. saturating_add ( mining_emission) ,
253
260
)
254
261
} ) ;
262
+
263
+ // --- 6. Update untouchable part of hotkey emission (that will not be distributed to nominators)
264
+ // This doesn't include remaining_emission, which should be distributed in drain_hotkey_emission
265
+ PendingdHotkeyEmissionUntouchable :: < T > :: mutate ( hotkey, |hotkey_pending| {
266
+ * hotkey_pending =
267
+ hotkey_pending. saturating_add ( total_childkey_take. saturating_add ( mining_emission) )
268
+ } ) ;
255
269
}
256
270
257
271
//. --- 4. Drains the accumulated hotkey emission through to the nominators. The hotkey takes a proportion of the emission.
@@ -270,8 +284,14 @@ impl<T: Config> Pallet<T> {
270
284
// --- 0. For accounting purposes record the total new added stake.
271
285
let mut total_new_tao: u64 = 0 ;
272
286
287
+ // Get the untouchable part of pending hotkey emission, so that we don't distribute this part of
288
+ // PendingdHotkeyEmission to nominators
289
+ let untouchable_emission = PendingdHotkeyEmissionUntouchable :: < T > :: get ( hotkey) ;
290
+ let emission_to_distribute = emission. saturating_sub ( untouchable_emission) ;
291
+
273
292
// --- 1.0 Drain the hotkey emission.
274
293
PendingdHotkeyEmission :: < T > :: insert ( hotkey, 0 ) ;
294
+ PendingdHotkeyEmissionUntouchable :: < T > :: insert ( hotkey, 0 ) ;
275
295
276
296
// --- 2 Update the block value to the current block number.
277
297
LastHotkeyEmissionDrain :: < T > :: insert ( hotkey, block_number) ;
@@ -280,13 +300,16 @@ impl<T: Config> Pallet<T> {
280
300
let total_hotkey_stake: u64 = Self :: get_total_stake_for_hotkey ( hotkey) ;
281
301
282
302
// --- 4 Calculate the emission take for the hotkey.
303
+ // This is only the hotkey take. Childkey take was already deducted from validator emissions in
304
+ // accumulate_hotkey_emission and now it is included in untouchable_emission.
283
305
let take_proportion: I64F64 = I64F64 :: from_num ( Delegates :: < T > :: get ( hotkey) )
284
306
. saturating_div ( I64F64 :: from_num ( u16:: MAX ) ) ;
285
- let hotkey_take: u64 =
286
- ( take_proportion. saturating_mul ( I64F64 :: from_num ( emission) ) ) . to_num :: < u64 > ( ) ;
307
+ let hotkey_take: u64 = ( take_proportion
308
+ . saturating_mul ( I64F64 :: from_num ( emission_to_distribute) ) )
309
+ . to_num :: < u64 > ( ) ;
287
310
288
- // --- 5 Compute the remaining emission after deducting the hotkey's take.
289
- let emission_minus_take: u64 = emission . saturating_sub ( hotkey_take) ;
311
+ // --- 5 Compute the remaining emission after deducting the hotkey's take and untouchable_emission .
312
+ let emission_minus_take: u64 = emission_to_distribute . saturating_sub ( hotkey_take) ;
290
313
291
314
// --- 6 Calculate the remaining emission after the hotkey's take.
292
315
let mut remainder: u64 = emission_minus_take;
@@ -327,8 +350,11 @@ impl<T: Config> Pallet<T> {
327
350
}
328
351
}
329
352
330
- // --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
331
- let hotkey_new_tao: u64 = hotkey_take. saturating_add ( remainder) ;
353
+ // --- 13 Finally, add the stake to the hotkey itself, including its take, the remaining emission, and
354
+ // the untouchable_emission (part of pending hotkey emission that consists of mining emission and childkey take)
355
+ let hotkey_new_tao: u64 = hotkey_take
356
+ . saturating_add ( remainder)
357
+ . saturating_add ( untouchable_emission) ;
332
358
Self :: increase_stake_on_hotkey_account ( hotkey, hotkey_new_tao) ;
333
359
334
360
// --- 14 Reset the stake delta for the hotkey.
0 commit comments