Skip to content
Merged
32 changes: 32 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,38 @@ pub mod pallet {
res
}

/// Set the behaviour of the "burn" UID(s) for a given subnet.
/// If set to `Burn`, the miner emission sent to the burn UID(s) will be burned.
/// If set to `Recycle`, the miner emission sent to the burn UID(s) will be recycled.
///
/// # Parameters
/// - `origin`: The origin of the call, which must be the root account or subnet owner.
/// - `netuid`: The unique identifier for the subnet.
/// - `recycle_or_burn`: The desired behaviour of the "burn" UID(s) for the subnet.
///
#[pallet::call_index(80)]
#[pallet::weight((1_000_000, DispatchClass::Normal, Pays::Yes))] // TODO: add proper weights
pub fn sudo_set_recycle_or_burn(
origin: OriginFor<T>,
netuid: NetUid,
recycle_or_burn: pallet_subtensor::RecycleOrBurnEnum,
) -> DispatchResult {
let maybe_owner = pallet_subtensor::Pallet::<T>::ensure_sn_owner_or_root_with_limits(
origin,
netuid,
&[Hyperparameter::RecycleOrBurn.into()],
)?;

pallet_subtensor::Pallet::<T>::set_recycle_or_burn(netuid, recycle_or_burn);
pallet_subtensor::Pallet::<T>::record_owner_rl(
maybe_owner,
netuid,
&[Hyperparameter::RecycleOrBurn.into()],
);

Ok(())
}

/// Toggles the enablement of an EVM precompile.
///
/// # Arguments
Expand Down
11 changes: 11 additions & 0 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,17 @@ impl<T: Config> Pallet<T> {
log::debug!(
"incentives: hotkey: {hotkey:?} is SN owner hotkey or associated hotkey, skipping {incentive:?}"
);
// Check if we should recycle or burn the incentive
match RecycleOrBurn::<T>::try_get(netuid) {
Ok(RecycleOrBurnEnum::Recycle) => {
log::debug!("recycling {incentive:?}");
Self::recycle_subnet_alpha(netuid, incentive);
}
Ok(RecycleOrBurnEnum::Burn) | Err(_) => {
log::debug!("burning {incentive:?}");
Self::burn_subnet_alpha(netuid, incentive);
}
}
continue;
}

Expand Down
18 changes: 18 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ pub mod pallet {
pub additional: Vec<u8>,
}

/// Enum for recycle or burn for the owner_uid(s)
#[derive(TypeInfo, Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug)]
pub enum RecycleOrBurnEnum {
/// Burn the miner emission sent to the burn UID
Burn,
/// Recycle the miner emission sent to the recycle UID
Recycle,
}

/// ============================
/// ==== Staking + Accounts ====
/// ============================
Expand Down Expand Up @@ -538,6 +547,11 @@ pub mod pallet {
T::InitialSubnetOwnerCut::get()
}
#[pallet::type_value]
/// Default value for recycle or burn.
pub fn DefaultRecycleOrBurn<T: Config>() -> RecycleOrBurnEnum {
RecycleOrBurnEnum::Burn // default to burn
}
#[pallet::type_value]
/// Default value for network rate limit.
pub fn DefaultNetworkRateLimit<T: Config>() -> u64 {
if cfg!(feature = "pow-faucet") {
Expand Down Expand Up @@ -1335,6 +1349,10 @@ pub mod pallet {
pub type SubnetOwnerHotkey<T: Config> =
StorageMap<_, Identity, NetUid, T::AccountId, ValueQuery, DefaultSubnetOwner<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> recycle_or_burn
pub type RecycleOrBurn<T: Config> =
StorageMap<_, Identity, NetUid, RecycleOrBurnEnum, ValueQuery, DefaultRecycleOrBurn<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> serving_rate_limit
pub type ServingRateLimit<T> =
StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultServingRateLimit<T>>;
Expand Down
5 changes: 5 additions & 0 deletions pallets/subtensor/src/staking/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,13 @@ impl<T: Config> Pallet<T> {
}

pub fn recycle_subnet_alpha(netuid: NetUid, amount: AlphaCurrency) {
// TODO: record recycled alpha in a tracker
SubnetAlphaOut::<T>::mutate(netuid, |total| {
*total = total.saturating_sub(amount);
});
}

pub fn burn_subnet_alpha(_netuid: NetUid, _amount: AlphaCurrency) {
// Do nothing; TODO: record burned alpha in a tracker
}
}
2 changes: 1 addition & 1 deletion pallets/subtensor/src/staking/recycle_alpha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<T: Config> Pallet<T> {
&hotkey, &coldkey, netuid, amount,
);

// This is a burn, so we don't need to update AlphaOut.
Self::burn_subnet_alpha(netuid, amount);

// Deposit event
Self::deposit_event(Event::AlphaBurned(
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/subnets/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl<T: Config> Pallet<T> {
);

if actual_tao_lock_amount_less_pool_tao > TaoCurrency::ZERO {
Self::burn_tokens(actual_tao_lock_amount_less_pool_tao);
Self::recycle_tao(actual_tao_lock_amount_less_pool_tao);
}

if actual_tao_lock_amount > TaoCurrency::ZERO && pool_initial_tao > TaoCurrency::ZERO {
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/swap/swap_coldkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ impl<T: Config> Pallet<T> {
Error::<T>::NotEnoughBalanceToPaySwapColdKey
);

// 7. Remove and burn the swap cost from the old coldkey's account
// 7. Remove and recycle the swap cost from the old coldkey's account
let actual_burn_amount =
Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost.into())?;
Self::burn_tokens(actual_burn_amount);
Self::recycle_tao(actual_burn_amount);

// 8. Update the weight for the balance operations
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));
Expand Down
12 changes: 6 additions & 6 deletions pallets/subtensor/src/swap/swap_hotkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ impl<T: Config> Pallet<T> {
weight.saturating_accrue(T::DbWeight::get().reads_writes(3, 0));

// 14. Remove the swap cost from the coldkey's account
let actual_burn_amount =
let actual_recycle_amount =
Self::remove_balance_from_coldkey_account(&coldkey, swap_cost.into())?;

// 18. Burn the tokens
Self::burn_tokens(actual_burn_amount);
// 18. Recycle the tokens
Self::recycle_tao(actual_recycle_amount);
weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2));

// 19. Perform the hotkey swap
Expand Down Expand Up @@ -296,11 +296,11 @@ impl<T: Config> Pallet<T> {
);

// 5. Remove the swap cost from the coldkey's account
let actual_burn_amount = Self::remove_balance_from_coldkey_account(coldkey, swap_cost)?;
let actual_recycle_amount = Self::remove_balance_from_coldkey_account(coldkey, swap_cost)?;
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0));

// 6. Burn the tokens
Self::burn_tokens(actual_burn_amount);
// 6. Recycle the tokens
Self::recycle_tao(actual_recycle_amount);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));

// 7. Swap owner.
Expand Down
6 changes: 5 additions & 1 deletion pallets/subtensor/src/utils/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ impl<T: Config> Pallet<T> {
// ========================
// === Token Management ===
// ========================
pub fn burn_tokens(amount: TaoCurrency) {
pub fn recycle_tao(amount: TaoCurrency) {
TotalIssuance::<T>::put(TotalIssuance::<T>::get().saturating_sub(amount));
}
pub fn increase_issuance(amount: TaoCurrency) {
Expand All @@ -393,6 +393,10 @@ impl<T: Config> Pallet<T> {
total_subnet_locked.into()
}

pub fn set_recycle_or_burn(netuid: NetUid, recycle_or_burn: RecycleOrBurnEnum) {
RecycleOrBurn::<T>::insert(netuid, recycle_or_burn);
}

// ========================
// ========= Sudo =========
// ========================
Expand Down
1 change: 1 addition & 0 deletions pallets/subtensor/src/utils/rate_limiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ pub enum Hyperparameter {
Yuma3Enabled = 21,
BondsResetEnabled = 22,
ImmuneNeuronLimit = 23,
RecycleOrBurn = 24,
}

impl<T: Config> Pallet<T> {
Expand Down
Loading