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
1 change: 1 addition & 0 deletions pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,7 @@ mod pallet_benchmarks {
netuid,
AlphaCurrency::ZERO,
pending_root_alpha.into(),
pending_root_alpha.into(),
AlphaCurrency::ZERO,
);

Expand Down
3 changes: 2 additions & 1 deletion pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,8 @@ impl<T: Config> Pallet<T> {

// --- 15. Mechanism step / emissions bookkeeping.
FirstEmissionBlockNumber::<T>::remove(netuid);
PendingEmission::<T>::remove(netuid);
PendingValidatorEmission::<T>::remove(netuid);
PendingServerEmission::<T>::remove(netuid);
PendingRootAlphaDivs::<T>::remove(netuid);
PendingOwnerCut::<T>::remove(netuid);
BlocksSinceLastStep::<T>::remove(netuid);
Expand Down
105 changes: 64 additions & 41 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,37 +195,48 @@ impl<T: Config> Pallet<T> {
let alpha_out_i: U96F32 = *alpha_out.get(netuid_i).unwrap_or(&asfloat!(0.0));
log::debug!("alpha_out_i: {alpha_out_i:?}");

// Get root proportion of alpha_out dividends.
let mut root_alpha: U96F32 = asfloat!(0.0);
// Get ALPHA issuance.
let alpha_issuance: U96F32 = asfloat!(Self::get_alpha_issuance(*netuid_i));
log::debug!("alpha_issuance: {alpha_issuance:?}");

// Get root proportional dividends.
let root_proportion: U96F32 = tao_weight
.checked_div(tao_weight.saturating_add(alpha_issuance))
.unwrap_or(asfloat!(0.0));
log::debug!("root_proportion: {root_proportion:?}");

// Get root alpha from root prop.
let root_alpha: U96F32 = root_proportion
.saturating_mul(alpha_out_i) // Total alpha emission per block remaining.
.saturating_mul(asfloat!(0.5)); // 50% to validators.
log::debug!("root_alpha: {root_alpha:?}");

if root_sell_flag {
// Get ALPHA issuance.
let alpha_issuance: U96F32 = asfloat!(Self::get_alpha_issuance(*netuid_i));
log::debug!("alpha_issuance: {alpha_issuance:?}");

// Get root proportional dividends.
let root_proportion: U96F32 = tao_weight
.checked_div(tao_weight.saturating_add(alpha_issuance))
.unwrap_or(asfloat!(0.0));
log::debug!("root_proportion: {root_proportion:?}");

// Get root alpha from root prop.
root_alpha = root_proportion
.saturating_mul(alpha_out_i) // Total alpha emission per block remaining.
.saturating_mul(asfloat!(0.5)); // 50% to validators.
// Only accumulate root alpha divs if root sell is allowed.
PendingRootAlphaDivs::<T>::mutate(*netuid_i, |total| {
*total = total.saturating_add(tou64!(root_alpha).into());
});
} else {
// If we are not selling the root alpha, we should recycle it.
Self::recycle_subnet_alpha(*netuid_i, AlphaCurrency::from(tou64!(root_alpha)));
}
// Remove root alpha from alpha_out.
log::debug!("root_alpha: {root_alpha:?}");

// Get pending alpha as original alpha_out - root_alpha.
let pending_alpha: U96F32 = alpha_out_i.saturating_sub(root_alpha);
log::debug!("pending_alpha: {pending_alpha:?}");
// Get pending server alpha, which is the miner cut of the alpha out.
// Currently miner cut is 50% of the alpha out.
let pending_server_alpha = alpha_out_i.saturating_mul(asfloat!(0.5));
// The total validator alpha is the remaining alpha out minus the server alpha.
let total_validator_alpha = alpha_out_i.saturating_sub(pending_server_alpha);

// Accumulate alpha emission in pending.
PendingEmission::<T>::mutate(*netuid_i, |total| {
*total = total.saturating_add(tou64!(pending_alpha).into());
// The alpha validators don't get the root alpha.
let pending_validator_alpha = total_validator_alpha.saturating_sub(root_alpha);

// Accumulate the server alpha emission.
PendingServerEmission::<T>::mutate(*netuid_i, |total| {
*total = total.saturating_add(tou64!(pending_server_alpha).into());
});
// Accumulate the validator alpha emission.
PendingValidatorEmission::<T>::mutate(*netuid_i, |total| {
*total = total.saturating_add(tou64!(pending_validator_alpha).into());
});
}

Expand All @@ -252,8 +263,11 @@ impl<T: Config> Pallet<T> {
LastMechansimStepBlock::<T>::insert(netuid, current_block);

// Get and drain the subnet pending emission.
let pending_alpha = PendingEmission::<T>::get(netuid);
PendingEmission::<T>::insert(netuid, AlphaCurrency::ZERO);
let pending_server_alpha = PendingServerEmission::<T>::get(netuid);
PendingServerEmission::<T>::insert(netuid, AlphaCurrency::ZERO);

let pending_validator_alpha = PendingValidatorEmission::<T>::get(netuid);
PendingValidatorEmission::<T>::insert(netuid, AlphaCurrency::ZERO);

// Get and drain the subnet pending root alpha divs.
let pending_root_alpha = PendingRootAlphaDivs::<T>::get(netuid);
Expand All @@ -264,7 +278,13 @@ impl<T: Config> Pallet<T> {
PendingOwnerCut::<T>::insert(netuid, AlphaCurrency::ZERO);

// Distribute the emission.
Self::distribute_emission(netuid, pending_alpha, pending_root_alpha, owner_cut);
Self::distribute_emission(
netuid,
pending_server_alpha,
pending_validator_alpha,
pending_root_alpha,
owner_cut,
);
} else {
// Increment
BlocksSinceLastStep::<T>::mutate(netuid, |total| *total = total.saturating_add(1));
Expand Down Expand Up @@ -633,20 +653,23 @@ impl<T: Config> Pallet<T> {

pub fn distribute_emission(
netuid: NetUid,
pending_alpha: AlphaCurrency,
pending_server_alpha: AlphaCurrency,
pending_validator_alpha: AlphaCurrency,
pending_root_alpha: AlphaCurrency,
owner_cut: AlphaCurrency,
pending_owner_cut: AlphaCurrency,
) {
log::debug!(
"Draining pending alpha emission for netuid {netuid:?}, pending_alpha: {pending_alpha:?}, pending_root_alpha: {pending_root_alpha:?}, owner_cut: {owner_cut:?}"
"Draining pending alpha emission for netuid {netuid:?}, pending_server_alpha: {pending_server_alpha:?}, pending_validator_alpha: {pending_validator_alpha:?}, pending_root_alpha: {pending_root_alpha:?}, pending_owner_cut: {pending_owner_cut:?}"
);

let tao_weight = Self::get_tao_weight();
let total_alpha = pending_alpha.saturating_add(pending_root_alpha);
let total_alpha_minus_owner_cut = pending_server_alpha
.saturating_add(pending_validator_alpha)
.saturating_add(pending_root_alpha);

// Run the epoch.
// Run the epoch, using the alpha going to both the servers and the validators.
let hotkey_emission: Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> =
Self::epoch_with_mechanisms(netuid, total_alpha);
Self::epoch_with_mechanisms(netuid, total_alpha_minus_owner_cut);
log::debug!("hotkey_emission: {hotkey_emission:?}");

// Compute the pending validator alpha.
Expand All @@ -661,20 +684,20 @@ impl<T: Config> Pallet<T> {
});
log::debug!("incentive_sum: {incentive_sum:?}");

let pending_validator_alpha = if !incentive_sum.is_zero() {
total_alpha
.saturating_div(2.into())
.saturating_sub(pending_root_alpha)
let validator_alpha = if !incentive_sum.is_zero() {
pending_validator_alpha
} else {
// If the incentive is 0, then Validators get 100% of the alpha.
pending_alpha
// If the incentive is 0, then Alpha Validators get both the server and validator alpha.
pending_validator_alpha.saturating_add(pending_server_alpha)
};
let root_alpha = pending_root_alpha;
let owner_cut = pending_owner_cut;

let (incentives, (alpha_dividends, root_alpha_dividends)) =
Self::calculate_dividend_and_incentive_distribution(
netuid,
pending_root_alpha,
pending_validator_alpha,
root_alpha,
validator_alpha,
hotkey_emission,
tao_weight,
);
Expand Down
10 changes: 7 additions & 3 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1430,9 +1430,13 @@ pub mod pallet {
pub type NetworkRegisteredAt<T: Config> =
StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultNetworkRegisteredAt<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> pending_emission
pub type PendingEmission<T> =
StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultPendingEmission<T>>;
/// --- MAP ( netuid ) --> pending_server_emission
pub type PendingServerEmission<T> =
StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha<T>>;
/// --- MAP ( netuid ) --> pending_validator_emission
#[pallet::storage]
pub type PendingValidatorEmission<T> =
StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha<T>>;
/// --- MAP ( netuid ) --> pending_root_alpha_emission
#[pallet::storage]
pub type PendingRootAlphaDivs<T> =
Expand Down
4 changes: 3 additions & 1 deletion pallets/subtensor/src/macros/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ mod hooks {
// Remove obsolete map entries
.saturating_add(migrations::migrate_remove_tao_dividends::migrate_remove_tao_dividends::<T>())
// Re-init tao flows
.saturating_add(migrations::migrate_init_tao_flow::migrate_init_tao_flow::<T>());
.saturating_add(migrations::migrate_init_tao_flow::migrate_init_tao_flow::<T>())
// Migrate pending emissions
.saturating_add(migrations::migrate_pending_emissions::migrate_pending_emissions::<T>());
weight
}

Expand Down
73 changes: 73 additions & 0 deletions pallets/subtensor/src/migrations/migrate_pending_emissions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use super::*;
use frame_support::{storage_alias, traits::Get, weights::Weight};
use substrate_fixed::types::U96F32;

pub mod deprecated_pending_emission_format {
use super::*;

#[storage_alias]
pub(super) type PendingEmission<T: Config> =
StorageMap<Pallet<T>, Identity, NetUid, AlphaCurrency, ValueQuery>;
}

pub fn migrate_pending_emissions<T: Config>() -> Weight {
let migration_name = b"migrate_pending_emissions".to_vec();
let mut weight: Weight = T::DbWeight::get().reads(1);

// Skip if already executed
if HasMigrationRun::<T>::get(&migration_name) {
log::info!(
target: "runtime",
"Migration '{}' already run - skipping.",
String::from_utf8_lossy(&migration_name)
);
return weight;
}
log::info!(
"Running migration '{}'",
String::from_utf8_lossy(&migration_name)
);

// Pull from PendingEmission and distribute to PendingValidatorEmission and PendingServerEmission
for (netuid, pending_emission) in
deprecated_pending_emission_format::PendingEmission::<T>::iter()
{
// Split up the pending emission into server and validator emission
// Server emission is pending+root_alpha times the 50% miner cut.
let root_alpha: U96F32 =
U96F32::saturating_from_num(PendingRootAlphaDivs::<T>::get(netuid).to_u64());
let server_emission_float: U96F32 = U96F32::saturating_from_num(pending_emission.to_u64())
.saturating_add(root_alpha)
.saturating_div(U96F32::saturating_from_num(2));
let server_emission: AlphaCurrency =
server_emission_float.saturating_to_num::<u64>().into();
let validator_emission = pending_emission.saturating_sub(server_emission);

PendingValidatorEmission::<T>::mutate(netuid, |total| {
*total = total.saturating_add(validator_emission)
});
PendingServerEmission::<T>::mutate(netuid, |total| {
*total = total.saturating_add(server_emission)
});

weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2));
}

// Kill the map
let removal_result =
deprecated_pending_emission_format::PendingEmission::<T>::clear(u32::MAX, None);
weight = weight.saturating_add(
T::DbWeight::get().reads_writes(removal_result.loops as u64, removal_result.backend as u64),
);

// Mark Migration as Completed
HasMigrationRun::<T>::insert(&migration_name, true);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

log::info!(
"Migration '{:?}' completed successfully.",
String::from_utf8_lossy(&migration_name)
);

weight
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod migrate_network_immunity_period;
pub mod migrate_network_lock_cost_2500;
pub mod migrate_network_lock_reduction_interval;
pub mod migrate_orphaned_storage_items;
pub mod migrate_pending_emissions;
pub mod migrate_populate_owned_hotkeys;
pub mod migrate_rao;
pub mod migrate_rate_limit_keys;
Expand Down
4 changes: 3 additions & 1 deletion pallets/subtensor/src/rpc_info/dynamic_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ impl<T: Config> Pallet<T> {
alpha_out_emission: SubnetAlphaOutEmission::<T>::get(netuid).into(),
alpha_in_emission: SubnetAlphaInEmission::<T>::get(netuid).into(),
tao_in_emission: SubnetTaoInEmission::<T>::get(netuid).into(),
pending_alpha_emission: PendingEmission::<T>::get(netuid).into(),
pending_alpha_emission: PendingValidatorEmission::<T>::get(netuid)
.saturating_add(PendingServerEmission::<T>::get(netuid))
.into(),
pending_root_emission: TaoCurrency::from(0u64).into(),
subnet_volume: SubnetVolume::<T>::get(netuid).into(),
network_registered_at: NetworkRegisteredAt::<T>::get(netuid).into(),
Expand Down
10 changes: 8 additions & 2 deletions pallets/subtensor/src/rpc_info/metagraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,9 @@ impl<T: Config> Pallet<T> {
alpha_out_emission: SubnetAlphaOutEmission::<T>::get(netuid).into(), // amount injected in alpha reserves per block
alpha_in_emission: SubnetAlphaInEmission::<T>::get(netuid).into(), // amount injected outstanding per block
tao_in_emission: SubnetTaoInEmission::<T>::get(netuid).into(), // amount of tao injected per block
pending_alpha_emission: PendingEmission::<T>::get(netuid).into(), // pending alpha to be distributed
pending_alpha_emission: PendingValidatorEmission::<T>::get(netuid)
.saturating_add(PendingServerEmission::<T>::get(netuid))
.into(), // pending alpha to be distributed
pending_root_emission: TaoCurrency::from(0u64).into(), // panding tao for root divs to be distributed
subnet_volume: subnet_volume.into(),
moving_price: SubnetMovingPrice::<T>::get(netuid),
Expand Down Expand Up @@ -1000,7 +1002,11 @@ impl<T: Config> Pallet<T> {
},
Some(SelectiveMetagraphIndex::PendingAlphaEmission) => SelectiveMetagraph {
netuid: netuid.into(),
pending_alpha_emission: Some(PendingEmission::<T>::get(netuid).into()),
pending_alpha_emission: Some(
PendingValidatorEmission::<T>::get(netuid)
.saturating_add(PendingServerEmission::<T>::get(netuid))
.into(),
),
..Default::default()
},
Some(SelectiveMetagraphIndex::PendingRootEmission) => SelectiveMetagraph {
Expand Down
3 changes: 2 additions & 1 deletion pallets/subtensor/src/tests/children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3095,7 +3095,8 @@ fn test_parent_child_chain_emission() {
);

// Set pending emission to 0
PendingEmission::<Test>::insert(netuid, AlphaCurrency::ZERO);
PendingValidatorEmission::<Test>::insert(netuid, AlphaCurrency::ZERO);
PendingServerEmission::<Test>::insert(netuid, AlphaCurrency::ZERO);

// Run epoch with emission value
SubtensorModule::run_coinbase(emission);
Expand Down
Loading
Loading