@@ -249,6 +249,20 @@ impl<T: Config> Pallet<T> {
249
249
} ) ;
250
250
}
251
251
252
+ /// Calculates the nonviable stake for a nominator.
253
+ /// The nonviable stake is the stake that was added by the nominator since the last emission drain.
254
+ /// This stake will not receive emission until the next emission drain.
255
+ /// Note: if the stake delta is below zero, we return zero. We don't allow more stake than the nominator has.
256
+ pub fn get_nonviable_stake ( hotkey : & T :: AccountId , nominator : & T :: AccountId ) -> u64 {
257
+ let stake_delta = StakeDeltaSinceLastEmissionDrain :: < T > :: get ( hotkey, nominator) ;
258
+ if stake_delta. is_negative ( ) {
259
+ 0
260
+ } else {
261
+ // Should never fail the into, but we handle it anyway.
262
+ stake_delta. try_into ( ) . unwrap_or ( u64:: MAX )
263
+ }
264
+ }
265
+
252
266
//. --- 4. Drains the accumulated hotkey emission through to the nominators. The hotkey takes a proportion of the emission.
253
267
/// The remainder is drained through to the nominators keeping track of the last stake increase event to ensure that the hotkey does not
254
268
/// gain more emission than it's stake since the last drain.
@@ -268,71 +282,67 @@ impl<T: Config> Pallet<T> {
268
282
// --- 1.0 Drain the hotkey emission.
269
283
PendingdHotkeyEmission :: < T > :: insert ( hotkey, 0 ) ;
270
284
271
- // --- 2 Retrieve the last time this hotkey's emissions were drained.
272
- let last_emission_drain: u64 = LastHotkeyEmissionDrain :: < T > :: get ( hotkey) ;
273
-
274
- // --- 3 Update the block value to the current block number.
285
+ // --- 2 Update the block value to the current block number.
275
286
LastHotkeyEmissionDrain :: < T > :: insert ( hotkey, block_number) ;
276
287
277
- // --- 4 Retrieve the total stake for the hotkey from all nominations.
288
+ // --- 3 Retrieve the total stake for the hotkey from all nominations.
278
289
let total_hotkey_stake: u64 = Self :: get_total_stake_for_hotkey ( hotkey) ;
279
290
280
- // --- 5 Calculate the emission take for the hotkey.
291
+ // --- 4 Calculate the emission take for the hotkey.
281
292
let take_proportion: I64F64 = I64F64 :: from_num ( Delegates :: < T > :: get ( hotkey) )
282
293
. saturating_div ( I64F64 :: from_num ( u16:: MAX ) ) ;
283
294
let hotkey_take: u64 =
284
295
( take_proportion. saturating_mul ( I64F64 :: from_num ( emission) ) ) . to_num :: < u64 > ( ) ;
285
296
286
- // --- 6 Compute the remaining emission after deducting the hotkey's take.
297
+ // --- 5 Compute the remaining emission after deducting the hotkey's take.
287
298
let emission_minus_take: u64 = emission. saturating_sub ( hotkey_take) ;
288
299
289
- // --- 7 Calculate the remaining emission after the hotkey's take.
300
+ // --- 6 Calculate the remaining emission after the hotkey's take.
290
301
let mut remainder: u64 = emission_minus_take;
291
302
292
- // --- 8 Iterate over each nominator and get all viable stake.
303
+ // --- 7 Iterate over each nominator and get all viable stake.
293
304
let mut total_viable_nominator_stake: u64 = total_hotkey_stake;
294
- for ( nominator, nominator_stake ) in Stake :: < T > :: iter_prefix ( hotkey) {
295
- if false && LastAddStakeIncrease :: < T > :: get ( hotkey, nominator) > last_emission_drain {
296
- total_viable_nominator_stake =
297
- total_viable_nominator_stake. saturating_sub ( nominator_stake ) ;
298
- }
305
+ for ( nominator, _ ) in Stake :: < T > :: iter_prefix ( hotkey) {
306
+ let nonviable_nomintaor_stake = Self :: get_nonviable_stake ( hotkey, & nominator) ;
307
+
308
+ total_viable_nominator_stake =
309
+ total_viable_nominator_stake . saturating_sub ( nonviable_nomintaor_stake ) ;
299
310
}
300
311
301
- // --- 9 Iterate over each nominator.
312
+ // --- 8 Iterate over each nominator.
302
313
if total_viable_nominator_stake != 0 {
303
314
for ( nominator, nominator_stake) in Stake :: < T > :: iter_prefix ( hotkey) {
304
- // --- 10 Check if the stake was manually increased by the user since the last emission drain for this hotkey.
305
- // If it was, skip this nominator as they will not receive their proportion of the emission.
306
- if false
307
- && LastAddStakeIncrease :: < T > :: get ( hotkey, nominator. clone ( ) )
308
- > last_emission_drain
309
- {
310
- continue ;
311
- }
315
+ // --- 9 Skip emission for any stake the was added by the nominator since the last emission drain.
316
+ // This means the nominator will get emission on existing stake, but not on new stake, until the next emission drain.
317
+ let viable_nominator_stake =
318
+ nominator_stake. saturating_sub ( Self :: get_nonviable_stake ( hotkey, & nominator) ) ;
312
319
313
- // --- 11 Calculate this nominator's share of the emission.
314
- let nominator_emission: I64F64 = I64F64 :: from_num ( nominator_stake )
320
+ // --- 10 Calculate this nominator's share of the emission.
321
+ let nominator_emission: I64F64 = I64F64 :: from_num ( viable_nominator_stake )
315
322
. checked_div ( I64F64 :: from_num ( total_viable_nominator_stake) )
316
323
. unwrap_or ( I64F64 :: from_num ( 0 ) )
317
324
. saturating_mul ( I64F64 :: from_num ( emission_minus_take) ) ;
318
325
319
- // --- 12 Increase the stake for the nominator.
326
+ // --- 11 Increase the stake for the nominator.
320
327
Self :: increase_stake_on_coldkey_hotkey_account (
321
328
& nominator,
322
329
hotkey,
323
330
nominator_emission. to_num :: < u64 > ( ) ,
324
331
) ;
325
332
326
- // --- 13 * Record event and Subtract the nominator's emission from the remainder.
333
+ // --- 12 * Record event and Subtract the nominator's emission from the remainder.
327
334
total_new_tao = total_new_tao. saturating_add ( nominator_emission. to_num :: < u64 > ( ) ) ;
328
335
remainder = remainder. saturating_sub ( nominator_emission. to_num :: < u64 > ( ) ) ;
329
336
}
330
337
}
331
338
332
- // --- 14 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
339
+ // --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
333
340
let hotkey_new_tao: u64 = hotkey_take. saturating_add ( remainder) ;
334
341
Self :: increase_stake_on_hotkey_account ( hotkey, hotkey_new_tao) ;
335
342
343
+ // --- 14 Reset the stake delta for the hotkey.
344
+ let _ = StakeDeltaSinceLastEmissionDrain :: < T > :: clear_prefix ( hotkey, u32:: MAX , None ) ;
345
+
336
346
// --- 15 Record new tao creation event and return the amount created.
337
347
total_new_tao = total_new_tao. saturating_add ( hotkey_new_tao) ;
338
348
total_new_tao
0 commit comments