@@ -247,32 +247,20 @@ impl<T: Config> Pallet<T> {
247
247
alpha_out
248
248
) ;
249
249
250
- // 6.1 Distribute the 18% owner cut.
250
+ // Calculate the 18% owner cut.
251
251
let owner_cut: u64 = I96F32 :: from_num ( alpha_out)
252
252
. saturating_mul ( Self :: get_float_subnet_owner_cut ( ) )
253
253
. to_num :: < u64 > ( ) ;
254
254
log:: debug!( "Owner cut for netuid {:?}: {:?}" , netuid, owner_cut) ;
255
- // 6.1.1: Check for existence of owner cold/hot pair and distribute emission directly to them.
256
- if let Ok ( owner_coldkey) = SubnetOwner :: < T > :: try_get ( netuid) {
257
- if let Ok ( owner_hotkey) = SubnetOwnerHotkey :: < T > :: try_get ( netuid) {
258
- // Increase stake for both coldkey and hotkey on the subnet
259
- Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
260
- & owner_hotkey,
261
- & owner_coldkey,
262
- netuid,
263
- owner_cut,
264
- ) ;
265
- log:: debug!( "Distributed owner cut for netuid {:?} to owner_hotkey {:?} and owner_coldkey {:?}" , netuid, owner_hotkey, owner_coldkey) ;
266
- }
267
- }
255
+
268
256
let remaining_emission: u64 = alpha_out. saturating_sub ( owner_cut) ;
269
257
log:: debug!(
270
258
"Remaining emission for netuid {:?}: {:?}" ,
271
259
netuid,
272
260
remaining_emission
273
261
) ;
274
262
275
- // 6.2 Run the epoch() --> hotkey emission.
263
+ // Run the epoch() --> hotkey emission.
276
264
let hotkey_emission: Vec < ( T :: AccountId , u64 , u64 ) > =
277
265
Self :: epoch ( netuid, remaining_emission) ;
278
266
log:: debug!(
@@ -281,11 +269,15 @@ impl<T: Config> Pallet<T> {
281
269
hotkey_emission
282
270
) ;
283
271
284
- // 6.3 Pay out the hotkey alpha dividends.
272
+ // Pay out the hotkey alpha dividends.
285
273
// First clear the netuid from HotkeyDividends
286
274
let mut total_root_alpha_divs: u64 = 0 ;
287
275
let mut root_alpha_divs: BTreeMap < T :: AccountId , u64 > = BTreeMap :: new ( ) ;
288
276
let _ = AlphaDividendsPerSubnet :: < T > :: clear_prefix ( netuid, u32:: MAX , None ) ;
277
+
278
+ let mut dividends_to_distribute: Vec < ( T :: AccountId , Vec < ( T :: AccountId , u64 ) > ) > = Vec :: new ( ) ;
279
+ let mut mining_incentive_to_distribute: Vec < ( T :: AccountId , u64 ) > = Vec :: new ( ) ;
280
+
289
281
for ( hotkey, incentive, dividends) in hotkey_emission {
290
282
log:: debug!(
291
283
"Processing hotkey {:?} with incentive {:?} and dividends {:?}" ,
@@ -294,21 +286,10 @@ impl<T: Config> Pallet<T> {
294
286
dividends
295
287
) ;
296
288
297
- // 6.3.1: Distribute mining incentive immediately.
298
- Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
299
- & hotkey. clone ( ) ,
300
- & Owner :: < T > :: get ( hotkey. clone ( ) ) ,
301
- netuid,
302
- incentive,
303
- ) ;
304
- log:: debug!(
305
- "Distributed mining incentive for hotkey {:?} on netuid {:?}: {:?}" ,
306
- hotkey,
307
- netuid,
308
- incentive
309
- ) ;
289
+ // Record mining incentive
290
+ mining_incentive_to_distribute. push ( ( hotkey. clone ( ) , incentive) ) ;
310
291
311
- // 6.3.2: Get dividend tuples for parents and self based on childkey relationships and child-take.
292
+ // Get dividend tuples for parents and self based on childkey relationships and child-take.
312
293
let dividend_tuples: Vec < ( T :: AccountId , u64 ) > =
313
294
Self :: get_dividends_distribution ( & hotkey, netuid, dividends) ;
314
295
log:: debug!(
@@ -318,74 +299,66 @@ impl<T: Config> Pallet<T> {
318
299
dividend_tuples
319
300
) ;
320
301
321
- // 6.3.3 Pay out dividends to hotkeys based on the local vs root proportion.
322
- for ( hotkey_j, divs_j) in dividend_tuples {
302
+ // Record dividends to distribute
303
+ dividends_to_distribute. push ( ( hotkey. clone ( ) , dividend_tuples) ) ;
304
+ }
305
+
306
+ // Calculate the validator take and root alpha divs using the alpha divs.
307
+ for ( hotkey, dividend_tuples) in dividends_to_distribute. iter ( ) {
308
+ // Get the local alpha and root alpha.
309
+ let hotkey_tao: I96F32 = I96F32 :: from_num ( Self :: get_stake_for_hotkey_on_subnet (
310
+ hotkey,
311
+ Self :: get_root_netuid ( ) ,
312
+ ) ) ;
313
+ let hotkey_tao_as_alpha: I96F32 = hotkey_tao. saturating_mul ( Self :: get_tao_weight ( ) ) ;
314
+ let hotkey_alpha =
315
+ I96F32 :: from_num ( Self :: get_stake_for_hotkey_on_subnet ( hotkey, netuid) ) ;
316
+ log:: debug!( "Hotkey tao for hotkey {:?} on root netuid: {:?}, hotkey tao as alpha: {:?}, hotkey alpha: {:?}" , hotkey, hotkey_tao, hotkey_tao_as_alpha, hotkey_alpha) ;
317
+
318
+ // Compute alpha and root proportions.
319
+ let alpha_prop: I96F32 = hotkey_alpha
320
+ . checked_div ( hotkey_alpha. saturating_add ( hotkey_tao_as_alpha) )
321
+ . unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
322
+ let root_prop: I96F32 = hotkey_tao_as_alpha
323
+ . checked_div ( hotkey_alpha. saturating_add ( hotkey_tao_as_alpha) )
324
+ . unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
325
+ log:: debug!(
326
+ "Alpha proportion: {:?}, root proportion: {:?}" ,
327
+ alpha_prop,
328
+ root_prop
329
+ ) ;
330
+
331
+ // Calculate the dividends to hotkeys based on the local vs root proportion.
332
+ for ( hotkey_j, divs_j) in dividend_tuples. iter ( ) {
323
333
log:: debug!(
324
334
"Processing dividend for hotkey {:?} to hotkey {:?}: {:?}" ,
325
335
hotkey,
326
336
hotkey_j,
327
- divs_j
337
+ * divs_j
328
338
) ;
329
339
330
- // 6.3.3.1: Remove the hotkey take straight off the top.
331
- let take_prop: I96F32 = I96F32 :: from_num ( Self :: get_hotkey_take ( & hotkey_j) )
340
+ // Remove the hotkey take straight off the top.
341
+ let take_prop: I96F32 = I96F32 :: from_num ( Self :: get_hotkey_take ( hotkey_j) )
332
342
. checked_div ( I96F32 :: from_num ( u16:: MAX ) )
333
343
. unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
334
- let validator_take: I96F32 = take_prop. saturating_mul ( I96F32 :: from_num ( divs_j) ) ;
335
- let rem_divs_j: I96F32 = I96F32 :: from_num ( divs_j) . saturating_sub ( validator_take) ;
344
+ let validator_take: I96F32 = take_prop. saturating_mul ( I96F32 :: from_num ( * divs_j) ) ;
345
+ let rem_divs_j: I96F32 = I96F32 :: from_num ( * divs_j) . saturating_sub ( validator_take) ;
336
346
log:: debug!(
337
347
"Validator take for hotkey {:?}: {:?}, remaining dividends: {:?}" ,
338
348
hotkey_j,
339
349
validator_take,
340
350
rem_divs_j
341
351
) ;
342
352
343
- // 6.3.3.2: Distribute validator take automatically.
344
- Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
345
- & hotkey_j,
346
- & Owner :: < T > :: get ( hotkey_j. clone ( ) ) ,
347
- netuid,
348
- validator_take. to_num :: < u64 > ( ) ,
349
- ) ;
350
- log:: debug!(
351
- "Distributed validator take for hotkey {:?} on netuid {:?}: {:?}" ,
352
- hotkey_j,
353
- netuid,
354
- validator_take. to_num:: <u64 >( )
355
- ) ;
356
-
357
- // 6.3.3.3: Get the local alpha and root alpha.
358
- let hotkey_tao: I96F32 = I96F32 :: from_num ( Self :: get_stake_for_hotkey_on_subnet (
359
- & hotkey,
360
- Self :: get_root_netuid ( ) ,
361
- ) ) ;
362
- let hotkey_tao_as_alpha: I96F32 = hotkey_tao. saturating_mul ( Self :: get_tao_weight ( ) ) ;
363
- let hotkey_alpha =
364
- I96F32 :: from_num ( Self :: get_stake_for_hotkey_on_subnet ( & hotkey, netuid) ) ;
365
- log:: debug!( "Hotkey tao for hotkey {:?} on root netuid: {:?}, hotkey tao as alpha: {:?}, hotkey alpha: {:?}" , hotkey, hotkey_tao, hotkey_tao_as_alpha, hotkey_alpha) ;
366
-
367
- // 6.3.3.4 Compute alpha and root proportions.
368
- let alpha_prop: I96F32 = hotkey_alpha
369
- . checked_div ( hotkey_alpha. saturating_add ( hotkey_tao_as_alpha) )
370
- . unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
371
- let root_prop: I96F32 = hotkey_tao_as_alpha
372
- . checked_div ( hotkey_alpha. saturating_add ( hotkey_tao_as_alpha) )
373
- . unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
374
- log:: debug!(
375
- "Alpha proportion: {:?}, root proportion: {:?}" ,
376
- alpha_prop,
377
- root_prop
378
- ) ;
379
-
380
- // 6.3.3.5: Compute alpha and root dividends
353
+ // Compute root dividends
381
354
let root_divs: I96F32 = rem_divs_j. saturating_mul ( root_prop) ;
382
355
log:: debug!(
383
356
"Alpha dividends: {:?}, root dividends: {:?}" ,
384
357
rem_divs_j,
385
358
root_divs
386
359
) ;
387
360
388
- // 6.3.3.6. Store the root alpha divs under hotkey_j
361
+ // Store the root- alpha divs under hotkey_j
389
362
root_alpha_divs
390
363
. entry ( hotkey_j. clone ( ) )
391
364
. and_modify ( |e| * e = e. saturating_add ( root_divs. to_num :: < u64 > ( ) ) )
@@ -397,10 +370,74 @@ impl<T: Config> Pallet<T> {
397
370
hotkey_j,
398
371
root_divs. to_num:: <u64 >( )
399
372
) ;
373
+ }
374
+ }
375
+
376
+ // Check for existence of owner cold/hot pair and distribute emission directly to them.
377
+ if let Ok ( owner_coldkey) = SubnetOwner :: < T > :: try_get ( netuid) {
378
+ if let Ok ( owner_hotkey) = SubnetOwnerHotkey :: < T > :: try_get ( netuid) {
379
+ // Increase stake for both coldkey and hotkey on the subnet
380
+ Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
381
+ & owner_hotkey,
382
+ & owner_coldkey,
383
+ netuid,
384
+ owner_cut,
385
+ ) ;
386
+ log:: debug!( "Distributed owner cut for netuid {:?} to owner_hotkey {:?} and owner_coldkey {:?}" , netuid, owner_hotkey, owner_coldkey) ;
387
+ }
388
+ }
400
389
401
- // 6.3.3.7: Distribute the alpha divs to the hotkey.
390
+ // Distribute mining incentive.
391
+ for ( hotkey, incentive) in mining_incentive_to_distribute {
392
+ // Distribute mining incentive immediately.
393
+ Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
394
+ & hotkey. clone ( ) ,
395
+ & Owner :: < T > :: get ( hotkey. clone ( ) ) ,
396
+ netuid,
397
+ incentive,
398
+ ) ;
399
+ log:: debug!(
400
+ "Distributed mining incentive for hotkey {:?} on netuid {:?}: {:?}" ,
401
+ hotkey,
402
+ netuid,
403
+ incentive
404
+ ) ;
405
+ }
406
+
407
+ // Distribute validator take and alpha-dividends.
408
+ for ( _hotkey, dividend_tuples) in dividends_to_distribute. iter ( ) {
409
+ // Pay out dividends to hotkeys based on the local vs root proportion.
410
+ for ( hotkey_j, divs_j) in dividend_tuples. iter ( ) {
411
+ // Remove the hotkey take straight off the top.
412
+ let take_prop: I96F32 = I96F32 :: from_num ( Self :: get_hotkey_take ( hotkey_j) )
413
+ . checked_div ( I96F32 :: from_num ( u16:: MAX ) )
414
+ . unwrap_or ( I96F32 :: from_num ( 0.0 ) ) ;
415
+ let validator_take: I96F32 = take_prop. saturating_mul ( I96F32 :: from_num ( * divs_j) ) ;
416
+ let rem_divs_j: I96F32 = I96F32 :: from_num ( * divs_j) . saturating_sub ( validator_take) ;
417
+ log:: debug!(
418
+ "Validator take for hotkey {:?}: {:?}, remaining dividends: {:?}" ,
419
+ hotkey_j,
420
+ validator_take,
421
+ rem_divs_j
422
+ ) ;
423
+
424
+ // Distribute validator take.
425
+ Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
426
+ hotkey_j,
427
+ & Owner :: < T > :: get ( hotkey_j. clone ( ) ) ,
428
+ netuid,
429
+ validator_take. to_num :: < u64 > ( ) ,
430
+ ) ;
431
+ log:: debug!(
432
+ "Distributed validator take for hotkey {:?} on netuid {:?}: {:?}" ,
433
+ hotkey_j,
434
+ netuid,
435
+ validator_take. to_num:: <u64 >( )
436
+ ) ;
437
+
438
+ // Distribute the alpha divs to the hotkey.
402
439
Self :: increase_stake_for_hotkey_on_subnet (
403
- & hotkey_j,
440
+ hotkey_j,
404
441
netuid,
405
442
rem_divs_j. to_num :: < u64 > ( ) ,
406
443
) ;
@@ -411,19 +448,20 @@ impl<T: Config> Pallet<T> {
411
448
rem_divs_j. to_num:: <u64 >( )
412
449
) ;
413
450
414
- // 7.6.3.9: Record dividends for this hotkey on this subnet.
451
+ // Record dividends for this hotkey on this subnet.
415
452
AlphaDividendsPerSubnet :: < T > :: mutate ( netuid, hotkey_j. clone ( ) , |divs| {
416
- * divs = divs. saturating_add ( divs_j) ;
453
+ * divs = divs. saturating_add ( * divs_j) ;
417
454
} ) ;
418
455
log:: debug!(
419
456
"Recorded dividends for hotkey {:?} on netuid {:?}: {:?}" ,
420
457
hotkey_j,
421
458
netuid,
422
- divs_j
459
+ * divs_j
423
460
) ;
424
461
}
425
462
}
426
- // For all the root alpha divs give this proportion of the swapped tao to the root participants.
463
+
464
+ // For all the root-alpha divs give this proportion of the swapped tao to the root participants.
427
465
let _ = TaoDividendsPerSubnet :: < T > :: clear_prefix ( netuid, u32:: MAX , None ) ;
428
466
let total_root_divs_to_distribute = PendingRootDivs :: < T > :: get ( netuid) ;
429
467
PendingRootDivs :: < T > :: insert ( netuid, 0 ) ;
@@ -453,13 +491,15 @@ impl<T: Config> Pallet<T> {
453
491
root_divs_to_pay
454
492
) ;
455
493
456
- // 7.6.3.9: Record dividends for this hotkey on this subnet.
494
+ // Record dividends for this hotkey on this subnet.
457
495
TaoDividendsPerSubnet :: < T > :: mutate ( netuid, hotkey_j. clone ( ) , |divs| {
458
496
* divs = divs. saturating_add ( root_divs_to_pay) ;
459
497
} ) ;
460
498
}
461
499
}
462
500
501
+ /// Returns the self contribution of a hotkey on a subnet.
502
+ /// This is the portion of the hotkey's stake that is provided by itself, and not delegated to other hotkeys.
463
503
pub fn get_self_contribution ( hotkey : & T :: AccountId , netuid : u16 ) -> u64 {
464
504
// Get all childkeys for this hotkey.
465
505
let childkeys = Self :: get_children ( hotkey, netuid) ;
@@ -519,12 +559,27 @@ impl<T: Config> Pallet<T> {
519
559
let childkey_take_proportion: I96F32 =
520
560
I96F32 :: from_num ( Self :: get_childkey_take ( hotkey, netuid) )
521
561
. saturating_div ( I96F32 :: from_num ( u16:: MAX ) ) ;
562
+ log:: debug!(
563
+ "Childkey take proportion: {:?} for hotkey {:?}" ,
564
+ childkey_take_proportion,
565
+ hotkey
566
+ ) ;
522
567
// NOTE: Only the validation emission should be split amongst parents.
523
568
524
569
// Reserve childkey take
525
570
let child_emission_take: I96F32 =
526
571
childkey_take_proportion. saturating_mul ( I96F32 :: from_num ( validating_emission) ) ;
527
572
let remaining_emission: I96F32 = validating_emission. saturating_sub ( child_emission_take) ;
573
+ log:: debug!(
574
+ "Child emission take: {:?} for hotkey {:?}" ,
575
+ child_emission_take,
576
+ hotkey
577
+ ) ;
578
+ log:: debug!(
579
+ "Remaining emission: {:?} for hotkey {:?}" ,
580
+ remaining_emission,
581
+ hotkey
582
+ ) ;
528
583
529
584
// Initialize variables to track emission distribution
530
585
let mut to_parents: u64 = 0 ;
@@ -573,6 +628,12 @@ impl<T: Config> Pallet<T> {
573
628
total_contribution = total_contribution. saturating_add ( combined_contribution) ;
574
629
// Store the parent's contributions for later use
575
630
parent_contributions. push ( ( parent. clone ( ) , combined_contribution) ) ;
631
+ log:: debug!(
632
+ "Parent contribution for hotkey {:?} from parent {:?}: {:?}" ,
633
+ hotkey,
634
+ parent,
635
+ combined_contribution
636
+ ) ;
576
637
}
577
638
578
639
// Distribute emission to parents based on their contributions.
0 commit comments