diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 5569e286b9..b46c397fbe 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -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, + netuid: NetUid, + recycle_or_burn: pallet_subtensor::RecycleOrBurnEnum, + ) -> DispatchResult { + let maybe_owner = pallet_subtensor::Pallet::::ensure_sn_owner_or_root_with_limits( + origin, + netuid, + &[Hyperparameter::RecycleOrBurn.into()], + )?; + + pallet_subtensor::Pallet::::set_recycle_or_burn(netuid, recycle_or_burn); + pallet_subtensor::Pallet::::record_owner_rl( + maybe_owner, + netuid, + &[Hyperparameter::RecycleOrBurn.into()], + ); + + Ok(()) + } + /// Toggles the enablement of an EVM precompile. /// /// # Arguments diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index d284f33eda..c4a499c933 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -499,6 +499,17 @@ impl Pallet { 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::::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; } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f4a65de0e1..7bf88594eb 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -305,6 +305,15 @@ pub mod pallet { pub additional: Vec, } + /// 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 ==== /// ============================ @@ -538,6 +547,11 @@ pub mod pallet { T::InitialSubnetOwnerCut::get() } #[pallet::type_value] + /// Default value for recycle or burn. + pub fn DefaultRecycleOrBurn() -> RecycleOrBurnEnum { + RecycleOrBurnEnum::Burn // default to burn + } + #[pallet::type_value] /// Default value for network rate limit. pub fn DefaultNetworkRateLimit() -> u64 { if cfg!(feature = "pow-faucet") { @@ -1335,6 +1349,10 @@ pub mod pallet { pub type SubnetOwnerHotkey = StorageMap<_, Identity, NetUid, T::AccountId, ValueQuery, DefaultSubnetOwner>; #[pallet::storage] + /// --- MAP ( netuid ) --> recycle_or_burn + pub type RecycleOrBurn = + StorageMap<_, Identity, NetUid, RecycleOrBurnEnum, ValueQuery, DefaultRecycleOrBurn>; + #[pallet::storage] /// --- MAP ( netuid ) --> serving_rate_limit pub type ServingRateLimit = StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultServingRateLimit>; diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 7b1b644e85..1625afa811 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -323,8 +323,13 @@ impl Pallet { } pub fn recycle_subnet_alpha(netuid: NetUid, amount: AlphaCurrency) { + // TODO: record recycled alpha in a tracker SubnetAlphaOut::::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 + } } diff --git a/pallets/subtensor/src/staking/recycle_alpha.rs b/pallets/subtensor/src/staking/recycle_alpha.rs index 4c1bbd0b9f..f4c35e53c4 100644 --- a/pallets/subtensor/src/staking/recycle_alpha.rs +++ b/pallets/subtensor/src/staking/recycle_alpha.rs @@ -126,7 +126,7 @@ impl Pallet { &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( diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index bbb9ff9b11..a3c0744863 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -229,7 +229,7 @@ impl Pallet { ); 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 { diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index f7f9997183..8180650bf8 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -62,10 +62,10 @@ impl Pallet { Error::::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)); diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 19737f765c..16b8229136 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -97,11 +97,11 @@ impl Pallet { 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 @@ -296,11 +296,11 @@ impl Pallet { ); // 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. diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 02752eda72..9ca7e361cc 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -372,7 +372,7 @@ impl Pallet { // ======================== // === Token Management === // ======================== - pub fn burn_tokens(amount: TaoCurrency) { + pub fn recycle_tao(amount: TaoCurrency) { TotalIssuance::::put(TotalIssuance::::get().saturating_sub(amount)); } pub fn increase_issuance(amount: TaoCurrency) { @@ -393,6 +393,10 @@ impl Pallet { total_subnet_locked.into() } + pub fn set_recycle_or_burn(netuid: NetUid, recycle_or_burn: RecycleOrBurnEnum) { + RecycleOrBurn::::insert(netuid, recycle_or_burn); + } + // ======================== // ========= Sudo ========= // ======================== diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index 190634212a..b877e39bc0 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -196,6 +196,7 @@ pub enum Hyperparameter { Yuma3Enabled = 21, BondsResetEnabled = 22, ImmuneNeuronLimit = 23, + RecycleOrBurn = 24, } impl Pallet {