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
31 changes: 28 additions & 3 deletions pallets/subtensor/src/coinbase/block_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ impl<T: Config + pallet_drand::Config> Pallet<T> {
Self::run_coinbase(block_emission);
// --- 5. Update moving prices AFTER using them for emissions.
Self::update_moving_prices();
// --- 6. Set pending children on the epoch; but only after the coinbase has been run.
// --- 6. Update roop prop AFTER using them for emissions.
Self::update_root_prop();
// --- 7. Set pending children on the epoch; but only after the coinbase has been run.
Self::try_set_pending_children(block_number);
// --- 7. Run auto-claim root divs.
// --- 8. Run auto-claim root divs.
Self::run_auto_claim_root_divs(last_block_hash);
// --- 8. Populate root coldkey maps.
// --- 9. Populate root coldkey maps.
Self::populate_root_coldkey_staking_maps();

// Return ok.
Expand Down Expand Up @@ -277,6 +279,29 @@ impl<T: Config + pallet_drand::Config> Pallet<T> {
}
}

pub fn update_root_prop() {
let subnets_to_emit_to: Vec<NetUid> =
Self::get_subnets_to_emit_to(&Self::get_all_subnet_netuids());
// Only root_prop for subnets that we emit to.
for netuid_i in subnets_to_emit_to.iter() {
let root_prop = Self::root_proportion(*netuid_i);

RootProp::<T>::insert(netuid_i, root_prop);
}
}

pub fn root_proportion(netuid: NetUid) -> U96F32 {
let alpha_issuance = U96F32::from_num(Self::get_alpha_issuance(netuid));
let root_tao: U96F32 = U96F32::from_num(SubnetTAO::<T>::get(NetUid::ROOT));
let tao_weight: U96F32 = root_tao.saturating_mul(Self::get_tao_weight());

let root_proportion: U96F32 = tao_weight
.checked_div(tao_weight.saturating_add(alpha_issuance))
.unwrap_or(U96F32::from_num(0.0));

root_proportion
}

pub fn reveal_crv3_commits() {
let netuids: Vec<NetUid> = Self::get_all_subnet_netuids();
for netuid in netuids.into_iter().filter(|netuid| *netuid != NetUid::ROOT) {
Expand Down
15 changes: 1 addition & 14 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,6 @@ impl<T: Config> Pallet<T> {
// --- 3. Inject ALPHA for participants.
let cut_percent: U96F32 = Self::get_float_subnet_owner_cut();

// Get total TAO on root.
let root_tao: U96F32 = asfloat!(SubnetTAO::<T>::get(NetUid::ROOT));
log::debug!("root_tao: {root_tao:?}");
// Get tao_weight
let tao_weight: U96F32 = root_tao.saturating_mul(Self::get_tao_weight());
log::debug!("tao_weight: {tao_weight:?}");

for netuid_i in subnets_to_emit_to.iter() {
// Get alpha_out for this block.
let mut alpha_out_i: U96F32 = *alpha_out.get(netuid_i).unwrap_or(&asfloat!(0));
Expand All @@ -205,14 +198,8 @@ impl<T: Config> Pallet<T> {
*total = total.saturating_add(tou64!(owner_cut_i).into());
});

// 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));
let root_proportion = Self::root_proportion(*netuid_i);
log::debug!("root_proportion: {root_proportion:?}");

// Get root alpha from root prop.
Expand Down
13 changes: 12 additions & 1 deletion pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub mod pallet {
use sp_std::collections::vec_deque::VecDeque;
use sp_std::vec;
use sp_std::vec::Vec;
use substrate_fixed::types::{I64F64, I96F32, U64F64};
use substrate_fixed::types::{I64F64, I96F32, U64F64, U96F32};
use subtensor_macros::freeze_struct;
use subtensor_runtime_common::{
AlphaCurrency, Currency, MechId, NetUid, NetUidStorageIndex, TaoCurrency,
Expand Down Expand Up @@ -994,6 +994,12 @@ pub mod pallet {
I96F32::saturating_from_num(0.0)
}

/// Default subnet root proportion.
#[pallet::type_value]
pub fn DefaultRootProp<T: Config>() -> U96F32 {
U96F32::saturating_from_num(0.0)
}

/// Default subnet root claimable
#[pallet::type_value]
pub fn DefaultRootClaimable<T: Config>() -> BTreeMap<NetUid, I96F32> {
Expand Down Expand Up @@ -1279,6 +1285,11 @@ pub mod pallet {
pub type SubnetMovingPrice<T: Config> =
StorageMap<_, Identity, NetUid, I96F32, ValueQuery, DefaultMovingPrice<T>>;

/// --- MAP ( netuid ) --> root_prop | The subnet root proportion.
#[pallet::storage]
pub type RootProp<T: Config> =
StorageMap<_, Identity, NetUid, U96F32, ValueQuery, DefaultRootProp<T>>;

/// --- MAP ( netuid ) --> total_volume | The total amount of TAO bought and sold since the start of the network.
#[pallet::storage]
pub type SubnetVolume<T: Config> =
Expand Down
14 changes: 7 additions & 7 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ mod dispatches {
///
#[pallet::call_index(2)]
#[pallet::weight((Weight::from_parts(340_800_000, 0)
.saturating_add(T::DbWeight::get().reads(27_u64))
.saturating_add(T::DbWeight::get().reads(25_u64))
.saturating_add(T::DbWeight::get().writes(16_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn add_stake(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1587,7 +1587,7 @@ mod dispatches {
/// - Thrown if key has hit transaction rate limit
#[pallet::call_index(84)]
#[pallet::weight((Weight::from_parts(358_500_000, 0)
.saturating_add(T::DbWeight::get().reads(44_u64))
.saturating_add(T::DbWeight::get().reads(41_u64))
.saturating_add(T::DbWeight::get().writes(26_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn unstake_all_alpha(origin: OriginFor<T>, hotkey: T::AccountId) -> DispatchResult {
Self::do_unstake_all_alpha(origin, hotkey)
Expand Down Expand Up @@ -1701,7 +1701,7 @@ mod dispatches {
#[pallet::call_index(87)]
#[pallet::weight((
Weight::from_parts(351_300_000, 0)
.saturating_add(T::DbWeight::get().reads(40_u64))
.saturating_add(T::DbWeight::get().reads(37_u64))
.saturating_add(T::DbWeight::get().writes(24_u64)),
DispatchClass::Normal,
Pays::Yes
Expand Down Expand Up @@ -1766,7 +1766,7 @@ mod dispatches {
///
#[pallet::call_index(88)]
#[pallet::weight((Weight::from_parts(402_900_000, 0)
.saturating_add(T::DbWeight::get().reads(27_u64))
.saturating_add(T::DbWeight::get().reads(25_u64))
.saturating_add(T::DbWeight::get().writes(16_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn add_stake_limit(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1830,7 +1830,7 @@ mod dispatches {
///
#[pallet::call_index(89)]
#[pallet::weight((Weight::from_parts(377_400_000, 0)
.saturating_add(T::DbWeight::get().reads(31_u64))
.saturating_add(T::DbWeight::get().reads(29_u64))
.saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn remove_stake_limit(
origin: OriginFor<T>,
Expand Down Expand Up @@ -1874,7 +1874,7 @@ mod dispatches {
#[pallet::call_index(90)]
#[pallet::weight((
Weight::from_parts(411_500_000, 0)
.saturating_add(T::DbWeight::get().reads(40_u64))
.saturating_add(T::DbWeight::get().reads(37_u64))
.saturating_add(T::DbWeight::get().writes(24_u64)),
DispatchClass::Normal,
Pays::Yes
Expand Down Expand Up @@ -2052,7 +2052,7 @@ mod dispatches {
/// Without limit_price it remove all the stake similar to `remove_stake` extrinsic
#[pallet::call_index(103)]
#[pallet::weight((Weight::from_parts(395_300_000, 10142)
.saturating_add(T::DbWeight::get().reads(31_u64))
.saturating_add(T::DbWeight::get().reads(29_u64))
.saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn remove_stake_full_limit(
origin: T::RuntimeOrigin,
Expand Down
61 changes: 61 additions & 0 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3919,3 +3919,64 @@ fn test_pending_emission_start_call_not_done() {
);
});
}

#[test]
fn test_root_prop_filled_on_block_step() {
new_test_ext(1).execute_with(|| {
let hotkey = U256::from(10);
let coldkey = U256::from(11);
let netuid1 = add_dynamic_network(&hotkey, &coldkey);
let netuid2 = add_dynamic_network(&hotkey, &coldkey);

SubnetTAO::<Test>::insert(NetUid::ROOT, TaoCurrency::from(1_000_000_000_000u64));
SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0

let tao_reserve = TaoCurrency::from(50_000_000_000);
let alpha_in = AlphaCurrency::from(100_000_000_000);
SubnetTAO::<Test>::insert(netuid1, tao_reserve);
SubnetAlphaIn::<Test>::insert(netuid1, alpha_in);
SubnetTAO::<Test>::insert(netuid2, tao_reserve);
SubnetAlphaIn::<Test>::insert(netuid2, alpha_in);

assert!(!RootProp::<Test>::contains_key(netuid1));
assert!(!RootProp::<Test>::contains_key(netuid2));

run_to_block(2);

assert!(RootProp::<Test>::get(netuid1) > U96F32::from_num(0));
assert!(RootProp::<Test>::get(netuid2) > U96F32::from_num(0));
});
}

#[test]
fn test_root_proportion() {
new_test_ext(1).execute_with(|| {
let hotkey = U256::from(10);
let coldkey = U256::from(11);
let netuid = add_dynamic_network(&hotkey, &coldkey);

let root_tao_reserve = 1_000_000_000_000u64;
SubnetTAO::<Test>::insert(NetUid::ROOT, TaoCurrency::from(root_tao_reserve));

let tao_weight = 3_320_413_933_267_719_290u64;
SubtensorModule::set_tao_weight(tao_weight);

let alpha_in = 100_000_000_000u64;
SubnetAlphaIn::<Test>::insert(netuid, AlphaCurrency::from(alpha_in));

let actual_root_proportion = SubtensorModule::root_proportion(netuid);
let expected_root_prop = {
let tao_weight = SubtensorModule::get_tao_weight();
let root_tao = U96F32::from_num(root_tao_reserve);
let alpha_in = {
let alpha: u64 = SubtensorModule::get_alpha_issuance(netuid).into();

U96F32::from_num(alpha)
};

tao_weight * root_tao / (tao_weight * root_tao + alpha_in)
};

assert_eq!(actual_root_proportion, expected_root_prop);
});
}