Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 23 additions & 4 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,17 @@ impl<T: Config> Pallet<T> {
}
log::debug!("alpha_dividends: {:?}", alpha_dividends);
log::debug!("root_dividends: {:?}", root_dividends);
log::debug!("total_root_divs: {:?}", total_root_divs);

// Compute root divs as TAO. Here we take
let mut tao_dividends: BTreeMap<T::AccountId, I96F32> = BTreeMap::new();
for (hotkey, root_divs) in root_dividends {
// Root proportion.
let root_share: I96F32 = root_divs.checked_div(total_root_divs).unwrap_or(zero);
log::debug!("hotkey: {:?}, root_share: {:?}", hotkey, root_share);
// Root proportion in TAO
let root_tao: I96F32 = asfloat!(pending_tao).saturating_mul(root_share);
log::debug!("hotkey: {:?}, root_tao: {:?}", hotkey, root_tao);
// Record root dividends as TAO.
tao_dividends
.entry(hotkey)
Expand All @@ -358,6 +361,12 @@ impl<T: Config> Pallet<T> {
if let Ok(owner_coldkey) = SubnetOwner::<T>::try_get(netuid) {
if let Ok(owner_hotkey) = SubnetOwnerHotkey::<T>::try_get(netuid) {
// Increase stake for owner hotkey and coldkey.
log::debug!(
"owner_hotkey: {:?} owner_coldkey: {:?}, owner_cut: {:?}",
owner_hotkey,
owner_coldkey,
owner_cut
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&owner_hotkey,
&owner_coldkey,
Expand All @@ -370,6 +379,7 @@ impl<T: Config> Pallet<T> {
// Distribute mining incentives.
for (hotkey, incentive) in incentives {
// Increase stake for miner.
log::debug!("incentives: hotkey: {:?}", incentive);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey.clone(),
&Owner::<T>::get(hotkey.clone()),
Expand All @@ -381,21 +391,21 @@ impl<T: Config> Pallet<T> {
// Distribute alpha divs.
let _ = AlphaDividendsPerSubnet::<T>::clear_prefix(netuid, u32::MAX, None);
for (hotkey, mut alpha_divs) in alpha_dividends {
log::debug!("hotkey: {:?} alpha_divs: {:?}", hotkey, alpha_divs);

// Get take prop
let alpha_take: I96F32 =
Self::get_hotkey_take_float(&hotkey).saturating_mul(alpha_divs);
// Remove take prop from alpha_divs
alpha_divs = alpha_divs.saturating_sub(alpha_take);
// Give the validator their take.
log::debug!("hotkey: {:?} alpha_take: {:?}", hotkey, alpha_take);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&Owner::<T>::get(hotkey.clone()),
netuid,
tou64!(alpha_take),
);
// Give all other nominators.
log::debug!("hotkey: {:?} alpha_divs: {:?}", hotkey, alpha_divs);
Self::increase_stake_for_hotkey_on_subnet(&hotkey.clone(), netuid, tou64!(alpha_divs));
// Record dividends for this hotkey.
AlphaDividendsPerSubnet::<T>::mutate(netuid, hotkey.clone(), |divs| {
Expand All @@ -406,19 +416,20 @@ impl<T: Config> Pallet<T> {
// Distribute root tao divs.
let _ = TaoDividendsPerSubnet::<T>::clear_prefix(netuid, u32::MAX, None);
for (hotkey, mut root_tao) in tao_dividends {
log::debug!("hotkey: {:?} root_tao: {:?}", hotkey, root_tao);
// Get take prop
let tao_take: I96F32 = Self::get_hotkey_take_float(&hotkey).saturating_mul(root_tao);
// Remove take prop from root_tao
root_tao = root_tao.saturating_sub(tao_take);
// Give the validator their take.
log::debug!("hotkey: {:?} tao_take: {:?}", hotkey, tao_take);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&Owner::<T>::get(hotkey.clone()),
Self::get_root_netuid(),
tou64!(tao_take),
);
// Give rest to nominators.
log::debug!("hotkey: {:?} root_tao: {:?}", hotkey, root_tao);
Self::increase_stake_for_hotkey_on_subnet(
&hotkey,
Self::get_root_netuid(),
Expand Down Expand Up @@ -580,10 +591,18 @@ impl<T: Config> Pallet<T> {
(remaining_emission.saturating_mul(emission_factor)).saturating_to_num::<u64>();

// Add the parent's emission to the distribution list
dividend_tuples.push((parent, parent_emission));
dividend_tuples.push((parent.clone(), parent_emission));

// Keep track of total emission distributed to parents
to_parents = to_parents.saturating_add(parent_emission);
log::debug!(
"Parent contribution for parent {:?} with contribution: {:?}, of total: {:?} of emission: {:?} gets: {:?}",
parent,
contribution,
total_contribution,
remaining_emission,
parent_emission
);
}
// Calculate the final emission for the hotkey itself.
// This includes the take left from the parents and the self contribution.
Expand Down
109 changes: 102 additions & 7 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,17 @@ impl<T: Config> Pallet<T> {
// Step 1: Get stake of hotkey (neuron)
let alpha_stake =
I64F64::saturating_from_num(Self::get_inherited_for_hotkey_on_subnet(hotkey, netuid));
log::trace!("alpha_stake: {:?}", alpha_stake);
log::debug!("alpha_stake: {:?}", alpha_stake);

// Step 2: Get the global tao stake for the hotkey
let tao_stake =
I64F64::saturating_from_num(Self::get_inherited_for_hotkey_on_subnet(hotkey, 0));
log::trace!("tao_stake: {:?}", tao_stake);
let tao_stake = I64F64::saturating_from_num(Self::get_tao_inherited_for_hotkey_on_subnet(
hotkey, netuid,
));
log::debug!("tao_stake: {:?}", tao_stake);

// Step 3: Combine alpha and tao stakes
let total_stake = alpha_stake.saturating_add(tao_stake.saturating_mul(tao_weight));
log::trace!("total_stake: {:?}", total_stake);
log::debug!("total_stake: {:?}", total_stake);

(total_stake, alpha_stake, tao_stake)
}
Expand Down Expand Up @@ -173,8 +174,8 @@ impl<T: Config> Pallet<T> {
.map(|uid| {
if Keys::<T>::contains_key(netuid, uid) {
let hotkey: T::AccountId = Keys::<T>::get(netuid, uid);
I64F64::saturating_from_num(Self::get_inherited_for_hotkey_on_subnet(
&hotkey, 0,
I64F64::saturating_from_num(Self::get_tao_inherited_for_hotkey_on_subnet(
&hotkey, netuid,
))
} else {
I64F64::saturating_from_num(0)
Expand Down Expand Up @@ -222,6 +223,100 @@ impl<T: Config> Pallet<T> {
///
/// # Note
/// This function uses saturating arithmetic to prevent overflows.
pub fn get_tao_inherited_for_hotkey_on_subnet(hotkey: &T::AccountId, netuid: u16) -> u64 {
let initial_tao: I96F32 = I96F32::saturating_from_num(
Self::get_stake_for_hotkey_on_subnet(hotkey, Self::get_root_netuid()),
);

// Initialize variables to track alpha allocated to children and inherited from parents.
let mut tao_to_children: I96F32 = I96F32::saturating_from_num(0);
let mut tao_from_parents: I96F32 = I96F32::saturating_from_num(0);

// Step 2: Retrieve the lists of parents and children for the hotkey on the subnet.
let parents: Vec<(u64, T::AccountId)> = Self::get_parents(hotkey, netuid);
let children: Vec<(u64, T::AccountId)> = Self::get_children(hotkey, netuid);
log::trace!(
"Parents for hotkey {:?} on subnet {}: {:?}",
hotkey,
netuid,
parents
);
log::trace!(
"Children for hotkey {:?} on subnet {}: {:?}",
hotkey,
netuid,
children
);

// Step 3: Calculate the total tao allocated to children.
for (proportion, _) in children {
// Convert the proportion to a normalized value between 0 and 1.
let normalized_proportion: I96F32 = I96F32::saturating_from_num(proportion)
.safe_div(I96F32::saturating_from_num(u64::MAX));
log::trace!(
"Normalized proportion for child: {:?}",
normalized_proportion
);

// Calculate the amount of tao to be allocated to this child.
let tao_proportion_to_child: I96F32 =
I96F32::saturating_from_num(initial_tao).saturating_mul(normalized_proportion);
log::trace!("Tao proportion to child: {:?}", tao_proportion_to_child);

// Add this child's allocation to the total tao allocated to children.
tao_to_children = tao_to_children.saturating_add(tao_proportion_to_child);
}
log::trace!("Total tao allocated to children: {:?}", tao_to_children);

// Step 4: Calculate the total tao inherited from parents.
for (proportion, parent) in parents {
// Retrieve the parent's total stake on this subnet.
let parent_tao: I96F32 = I96F32::saturating_from_num(
Self::get_stake_for_hotkey_on_subnet(&parent, Self::get_root_netuid()),
);
log::trace!(
"Parent tao for parent {:?} on subnet {}: {:?}",
parent,
netuid,
parent_tao
);

// Convert the proportion to a normalized value between 0 and 1.
let normalized_proportion: I96F32 = I96F32::saturating_from_num(proportion)
.safe_div(I96F32::saturating_from_num(u64::MAX));
log::trace!(
"Normalized proportion from parent: {:?}",
normalized_proportion
);

// Calculate the amount of tao to be inherited from this parent.
let tao_proportion_from_parent: I96F32 =
I96F32::saturating_from_num(parent_tao).saturating_mul(normalized_proportion);
log::trace!(
"Tao proportion from parent: {:?}",
tao_proportion_from_parent
);

// Add this parent's contribution to the total tao inherited from parents.
tao_from_parents = tao_from_parents.saturating_add(tao_proportion_from_parent);
}
log::trace!("Total tao inherited from parents: {:?}", tao_from_parents);

// Step 5: Calculate the final inherited tao for the hotkey.
let finalized_tao: I96F32 = initial_tao
.saturating_sub(tao_to_children) // Subtract tao allocated to children
.saturating_add(tao_from_parents); // Add tao inherited from parents
log::trace!(
"Finalized tao for hotkey {:?} on subnet {}: {:?}",
hotkey,
netuid,
finalized_tao
);

// Step 6: Return the final inherited tao value.
finalized_tao.saturating_to_num::<u64>()
}

pub fn get_inherited_for_hotkey_on_subnet(hotkey: &T::AccountId, netuid: u16) -> u64 {
// Step 1: Retrieve the initial total stake (alpha) for the hotkey on the specified subnet.
let initial_alpha: I96F32 =
Expand Down
Loading
Loading