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
4 changes: 2 additions & 2 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ pub mod pallet {
}

/// The extrinsic sets the minimum burn for a subnet.
/// It is only callable by the root account or subnet owner.
/// It is only callable by the root account.
/// The extrinsic will call the Subtensor pallet to set the minimum burn.
#[pallet::call_index(22)]
#[pallet::weight(<T as Config>::WeightInfo::sudo_set_min_burn())]
Expand All @@ -563,7 +563,7 @@ pub mod pallet {
netuid: u16,
min_burn: u64,
) -> DispatchResult {
pallet_subtensor::Pallet::<T>::ensure_subnet_owner_or_root(origin, netuid)?;
ensure_root(origin)?;

ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Expand Down
34 changes: 20 additions & 14 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,26 @@ impl<T: Config> Pallet<T> {
netuid,
subnet_proportion
);
// 3.7: Calculate subnet's TAO emission: E_s = P_s * E_m
let tao_in: u64 = mech_emission
.checked_mul(subnet_proportion)
.unwrap_or(I96F32::saturating_from_num(0))
.saturating_to_num::<u64>();
log::debug!(
"Subnet TAO emission (E_s) for netuid {:?}: {:?}",
netuid,
tao_in
);
// 3.8: Store the subnet TAO emission.
*tao_in_map.entry(*netuid).or_insert(0) = tao_in;
// 3.9: Store the block emission for this subnet for chain storage.
EmissionValues::<T>::insert(*netuid, tao_in);

// Only emit TAO if the subnetwork allows registration.
if Self::get_network_registration_allowed(*netuid)
|| Self::get_network_pow_registration_allowed(*netuid)
{
// 3.7: Calculate subnet's TAO emission: E_s = P_s * E_m
let tao_in: u64 = mech_emission
.checked_mul(subnet_proportion)
.unwrap_or(I96F32::saturating_from_num(0))
.saturating_to_num::<u64>();
log::debug!(
"Subnet TAO emission (E_s) for netuid {:?}: {:?}",
netuid,
tao_in
);
// 3.8: Store the subnet TAO emission.
*tao_in_map.entry(*netuid).or_insert(0) = tao_in;
// 3.9: Store the block emission for this subnet for chain storage.
EmissionValues::<T>::insert(*netuid, tao_in);
}
}

// == We'll save the owner cuts for each subnet.
Expand Down
186 changes: 186 additions & 0 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,189 @@ fn test_total_issuance_after_coinbase() {
);
});
}

// Verifies that the total issuance after the coinbase is not changed when registration is disabled.
// Includes TAO weight.
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_registration_disabled_total_issuance_same --exact --show-output --nocapture
#[test]
fn test_registration_disabled_total_issuance_same() {
new_test_ext(1).execute_with(|| {
let netuid: u16 = 1;
add_network(netuid, 1, 0);
// Set TAO weight to 18%
SubtensorModule::set_tao_weight(I96F32::from_num(0.18).saturating_to_num::<u64>());
// Set owner cut to ~11.11%
SubtensorModule::set_subnet_owner_cut(u16::MAX / 9);
let total_coinbase_emission: I96F32 = I96F32::from_num(1_123_456_789);
let epsilon: u64 = 100;

// Define hotkeys and coldkeys
let hotkey_a: U256 = U256::from(1);
let hotkey_b: U256 = U256::from(2);
let hotkey_c: U256 = U256::from(3);
let coldkey_a: U256 = U256::from(100);
let coldkey_b: U256 = U256::from(101);
let coldkey_c: U256 = U256::from(102);

// Register neurons with decreasing stakes
register_ok_neuron(netuid, hotkey_a, coldkey_a, 0);
register_ok_neuron(netuid, hotkey_b, coldkey_b, 0);
register_ok_neuron(netuid, hotkey_c, coldkey_c, 0);

// Add initial stakes
SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000);
SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000);
SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000);

// Swap to alpha
let total_tao: I96F32 = I96F32::from_num(300_000 + 100_000 + 50_000);
let total_alpha: I96F32 = I96F32::from_num(SubtensorModule::swap_tao_for_alpha(
netuid,
total_tao.saturating_to_num::<u64>(),
));

// Set the stakes directly
// This avoids needing to swap tao to alpha, impacting the initial stake distribution.
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_a,
&coldkey_a,
netuid,
(total_alpha * I96F32::from_num(300_000) / total_tao).saturating_to_num::<u64>(),
);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_b,
&coldkey_b,
netuid,
(total_alpha * I96F32::from_num(100_000) / total_tao).saturating_to_num::<u64>(),
);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_c,
&coldkey_c,
netuid,
(total_alpha * I96F32::from_num(50_000) / total_tao).saturating_to_num::<u64>(),
);

// Stake some to root
let stake_to_root: u64 = 10_000_000;
SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, stake_to_root);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_a,
&coldkey_a,
netuid,
stake_to_root,
);

let alpha_price = SubtensorModule::get_alpha_price(netuid);
log::info!("alpha_price: {:?}", alpha_price);

// Get the total issuance
let mut total_issuance_before = TotalIssuance::<Test>::get();
log::info!("total_issuance_before: {:?}", total_issuance_before);

// Disable registration on the network
SubtensorModule::set_network_registration_allowed(netuid, false);
SubtensorModule::set_network_pow_registration_allowed(netuid, false);

// Run the coinbase
SubtensorModule::run_coinbase(total_coinbase_emission);

// Should be the same
let total_issuance_after = TotalIssuance::<Test>::get();
assert_abs_diff_eq!(
total_issuance_after,
total_issuance_before,
epsilon = epsilon
);
});
}

// Verifies that the TAO-in after the coinbase is not changed when registration is disabled.
// Includes TAO weight.
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_registration_disabled_tao_in_same --exact --show-output --nocapture
#[test]
fn test_registration_disabled_tao_in_same() {
new_test_ext(1).execute_with(|| {
let netuid: u16 = 1;
add_network(netuid, 1, 0);
// Set TAO weight to 18%
SubtensorModule::set_tao_weight(I96F32::from_num(0.18).saturating_to_num::<u64>());
// Set owner cut to ~11.11%
SubtensorModule::set_subnet_owner_cut(u16::MAX / 9);
let total_coinbase_emission: I96F32 = I96F32::from_num(1_123_456_789);
let epsilon: u64 = 100;

// Define hotkeys and coldkeys
let hotkey_a: U256 = U256::from(1);
let hotkey_b: U256 = U256::from(2);
let hotkey_c: U256 = U256::from(3);
let coldkey_a: U256 = U256::from(100);
let coldkey_b: U256 = U256::from(101);
let coldkey_c: U256 = U256::from(102);

// Register neurons with decreasing stakes
register_ok_neuron(netuid, hotkey_a, coldkey_a, 0);
register_ok_neuron(netuid, hotkey_b, coldkey_b, 0);
register_ok_neuron(netuid, hotkey_c, coldkey_c, 0);

// Add initial stakes
SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000);
SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000);
SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000);

// Swap to alpha
let total_tao: I96F32 = I96F32::from_num(300_000 + 100_000 + 50_000);
let total_alpha: I96F32 = I96F32::from_num(SubtensorModule::swap_tao_for_alpha(
netuid,
total_tao.saturating_to_num::<u64>(),
));

// Set the stakes directly
// This avoids needing to swap tao to alpha, impacting the initial stake distribution.
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_a,
&coldkey_a,
netuid,
(total_alpha * I96F32::from_num(300_000) / total_tao).saturating_to_num::<u64>(),
);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_b,
&coldkey_b,
netuid,
(total_alpha * I96F32::from_num(100_000) / total_tao).saturating_to_num::<u64>(),
);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_c,
&coldkey_c,
netuid,
(total_alpha * I96F32::from_num(50_000) / total_tao).saturating_to_num::<u64>(),
);

// Stake some to root
let stake_to_root: u64 = 10_000_000;
SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, stake_to_root);
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_a,
&coldkey_a,
netuid,
stake_to_root,
);

let alpha_price = SubtensorModule::get_alpha_price(netuid);
log::info!("alpha_price: {:?}", alpha_price);

// Get the total issuance
let mut tao_in_before = SubnetTAO::<Test>::get(netuid);
log::info!("tao_in_before: {:?}", tao_in_before);

// Disable registration on the network
SubtensorModule::set_network_registration_allowed(netuid, false);
SubtensorModule::set_network_pow_registration_allowed(netuid, false);

// Run the coinbase
SubtensorModule::run_coinbase(total_coinbase_emission);

// Should be the same
let tao_in_after = SubnetTAO::<Test>::get(netuid);
assert_abs_diff_eq!(tao_in_after, tao_in_before, epsilon = epsilon);
});
}
Loading