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