Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do not merge #858

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a19b7c7
Childkey fixes, tests are incomplete
gztensor Oct 11, 2024
db01f55
Test draining childkey emission: childkey take
gztensor Oct 14, 2024
adaca62
Test draining emission: miner emission. Improve readability of childk…
gztensor Oct 14, 2024
68c16b3
Format
gztensor Oct 14, 2024
0a34147
Add swapping child's parents to hotkey swap
gztensor Oct 16, 2024
34e0e61
Add more tests for miner and childkey emission drain
gztensor Oct 17, 2024
37f8052
Update test for two validator-miner neurons
gztensor Oct 17, 2024
6ceaa72
Add test case for draining emissions with three neurons: validator, v…
gztensor Oct 17, 2024
aa521f4
Merge pull request #863 from opentensor/fix/hotkey-swap-parentkeys
sam0x17 Oct 18, 2024
212316c
Merge branch 'main' into hotfix/childkey-emission-distibution
gztensor Oct 18, 2024
e9d8bf4
bump spec above mainnet (#829)
camfairchild Sep 23, 2024
8c2e5e3
Childkey fixes, tests are incomplete
gztensor Oct 11, 2024
20f288b
Test draining childkey emission: childkey take
gztensor Oct 14, 2024
8405d2e
Test draining emission: miner emission. Improve readability of childk…
gztensor Oct 14, 2024
05948f5
Format
gztensor Oct 14, 2024
a28c55c
Add more tests for miner and childkey emission drain
gztensor Oct 17, 2024
de289c3
Update test for two validator-miner neurons
gztensor Oct 17, 2024
07eb207
Add test case for draining emissions with three neurons: validator, v…
gztensor Oct 17, 2024
f040a1c
Add swapping child's parents to hotkey swap
gztensor Oct 16, 2024
4e6ea9f
Merge branch 'hotfix/childkey-emission-distibution' of github.com:ope…
gztensor Nov 4, 2024
9caebe0
Merge branch 'devnet-ready' into hotfix/childkey-emission-distibution
gztensor Nov 4, 2024
a472762
Format
gztensor Nov 4, 2024
0d1f992
Make tests build
gztensor Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 46 additions & 20 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,13 @@ impl<T: Config> Pallet<T> {
mining_emission: u64,
) {
// --- 1. First, calculate the hotkey's share of the emission.
let take_proportion: I64F64 = I64F64::from_num(Self::get_childkey_take(hotkey, netuid))
.saturating_div(I64F64::from_num(u16::MAX));
let hotkey_take: u64 = take_proportion
.saturating_mul(I64F64::from_num(validating_emission))
.to_num::<u64>();
// NOTE: Only the validation emission should be split amongst parents.

// --- 2. Compute the remaining emission after the hotkey's share is deducted.
let emission_minus_take: u64 = validating_emission.saturating_sub(hotkey_take);
let childkey_take_proportion: I64F64 =
I64F64::from_num(Self::get_childkey_take(hotkey, netuid))
.saturating_div(I64F64::from_num(u16::MAX));
let mut total_childkey_take: u64 = 0;

// --- 3. Track the remaining emission for accounting purposes.
let mut remaining_emission: u64 = emission_minus_take;
let mut remaining_emission: u64 = validating_emission;

// --- 4. Calculate the total stake of the hotkey, adjusted by the stakes of parents and children.
// Parents contribute to the stake, while children reduce it.
Expand All @@ -225,28 +220,47 @@ impl<T: Config> Pallet<T> {
);
let proportion_from_parent: I96F32 =
stake_from_parent.saturating_div(I96F32::from_num(total_hotkey_stake));
let parent_emission_take: u64 = proportion_from_parent
.saturating_mul(I96F32::from_num(emission_minus_take))
let parent_emission: u64 = proportion_from_parent
.saturating_mul(I96F32::from_num(validating_emission))
.to_num::<u64>();

// --- 5.3 Childkey take as part of parent emission
let child_emission_take: u64 = childkey_take_proportion
.saturating_mul(I64F64::from_num(parent_emission))
.to_num::<u64>();
total_childkey_take = total_childkey_take.saturating_add(child_emission_take);
// NOTE: Only the validation emission should be split amongst parents.

// --- 5.4 Compute the remaining parent emission after the childkey's share is deducted.
let parent_emission_take: u64 = parent_emission.saturating_sub(child_emission_take);

// --- 5.5. Accumulate emissions for the parent hotkey.
PendingdHotkeyEmission::<T>::mutate(parent, |parent_accumulated| {
*parent_accumulated = parent_accumulated.saturating_add(parent_emission_take)
});

// --- 5.6. Subtract the parent's share from the remaining emission for this hotkey.
remaining_emission = remaining_emission.saturating_sub(parent_emission_take);
remaining_emission = remaining_emission
.saturating_sub(parent_emission_take)
.saturating_sub(child_emission_take);
}
}

// --- 6. Add the remaining emission plus the hotkey's initial take to the pending emission for this hotkey.
PendingdHotkeyEmission::<T>::mutate(hotkey, |hotkey_pending| {
*hotkey_pending = hotkey_pending.saturating_add(
remaining_emission
.saturating_add(hotkey_take)
.saturating_add(total_childkey_take)
.saturating_add(mining_emission),
)
});

// --- 7. Update untouchable part of hotkey emission (that will not be distributed to nominators)
// This doesn't include remaining_emission, which should be distributed in drain_hotkey_emission
PendingdHotkeyEmissionUntouchable::<T>::mutate(hotkey, |hotkey_pending| {
*hotkey_pending =
hotkey_pending.saturating_add(total_childkey_take.saturating_add(mining_emission))
});
}

/// Calculates the nonviable stake for a nominator.
Expand Down Expand Up @@ -279,8 +293,14 @@ impl<T: Config> Pallet<T> {
// --- 0. For accounting purposes record the total new added stake.
let mut total_new_tao: u64 = 0;

// Get the untouchable part of pending hotkey emission, so that we don't distribute this part of
// PendingdHotkeyEmission to nominators
let untouchable_emission = PendingdHotkeyEmissionUntouchable::<T>::get(hotkey);
let emission_to_distribute = emission.saturating_sub(untouchable_emission);

// --- 1.0 Drain the hotkey emission.
PendingdHotkeyEmission::<T>::insert(hotkey, 0);
PendingdHotkeyEmissionUntouchable::<T>::insert(hotkey, 0);

// --- 2 Update the block value to the current block number.
LastHotkeyEmissionDrain::<T>::insert(hotkey, block_number);
Expand All @@ -289,13 +309,16 @@ impl<T: Config> Pallet<T> {
let total_hotkey_stake: u64 = Self::get_total_stake_for_hotkey(hotkey);

// --- 4 Calculate the emission take for the hotkey.
// This is only the hotkey take. Childkey take was already deducted from validator emissions in
// accumulate_hotkey_emission and now it is included in untouchable_emission.
let take_proportion: I64F64 = I64F64::from_num(Delegates::<T>::get(hotkey))
.saturating_div(I64F64::from_num(u16::MAX));
let hotkey_take: u64 =
(take_proportion.saturating_mul(I64F64::from_num(emission))).to_num::<u64>();
let hotkey_take: u64 = (take_proportion
.saturating_mul(I64F64::from_num(emission_to_distribute)))
.to_num::<u64>();

// --- 5 Compute the remaining emission after deducting the hotkey's take.
let emission_minus_take: u64 = emission.saturating_sub(hotkey_take);
// --- 5 Compute the remaining emission after deducting the hotkey's take and untouchable_emission.
let emission_minus_take: u64 = emission_to_distribute.saturating_sub(hotkey_take);

// --- 6 Calculate the remaining emission after the hotkey's take.
let mut remainder: u64 = emission_minus_take;
Expand Down Expand Up @@ -336,8 +359,11 @@ impl<T: Config> Pallet<T> {
}
}

// --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
let hotkey_new_tao: u64 = hotkey_take.saturating_add(remainder);
// --- 13 Finally, add the stake to the hotkey itself, including its take, the remaining emission, and
// the untouchable_emission (part of pending hotkey emission that consists of mining emission and childkey take)
let hotkey_new_tao: u64 = hotkey_take
.saturating_add(remainder)
.saturating_add(untouchable_emission);
Self::increase_stake_on_hotkey_account(hotkey, hotkey_new_tao);

// --- 14 Reset the stake delta for the hotkey.
Expand Down
10 changes: 10 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,16 @@ pub mod pallet {
DefaultAccumulatedEmission<T>,
>;
#[pallet::storage]
/// Map ( hot ) --> emission | Part of accumulated hotkey emission that will not be distributed to nominators.
pub type PendingdHotkeyEmissionUntouchable<T: Config> = StorageMap<
_,
Blake2_128Concat,
T::AccountId,
u64,
ValueQuery,
DefaultAccumulatedEmission<T>,
>;
#[pallet::storage]
/// Map ( hot, cold ) --> block_number | Last add stake increase.
pub type LastAddStakeIncrease<T: Config> = StorageDoubleMap<
_,
Expand Down
15 changes: 14 additions & 1 deletion pallets/subtensor/src/swap/swap_hotkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,20 @@ impl<T: Config> Pallet<T> {
// Remove the old hotkey's child entries
ChildKeys::<T>::remove(old_hotkey, netuid);
// Insert the same child entries for the new hotkey
ChildKeys::<T>::insert(new_hotkey, netuid, my_children);
ChildKeys::<T>::insert(new_hotkey, netuid, my_children.clone());
for (_, child_key_i) in my_children {
// For each child, update their parent list
let mut child_parents: Vec<(u64, T::AccountId)> =
ParentKeys::<T>::get(child_key_i.clone(), netuid);
for parent in child_parents.iter_mut() {
// If the parent is the old hotkey, replace it with the new hotkey
if parent.1 == *old_hotkey {
parent.1 = new_hotkey.clone();
}
}
// Update the child's parent list
ParentKeys::<T>::insert(child_key_i, netuid, child_parents);
}
}

// 13. Swap ParentKeys.
Expand Down
Loading
Loading