diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d4a3559d16..d6bf65348b 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -871,6 +871,7 @@ pub mod pallet { NetworkMinLockCostSet(u64), // Event created when the network minimum locking cost is set. SubnetLimitSet(u16), // Event created when the maximum number of subnets is set NetworkLockCostReductionIntervalSet(u64), // Event created when the lock cost reduction is set + TakeDecreased( T::AccountId, T::AccountId, u16 ), // Event created when the take for a delegate is decreased. HotkeySwapped { coldkey: T::AccountId, old_hotkey: T::AccountId, @@ -937,6 +938,7 @@ pub mod pallet { StakeTooLowForRoot, // --- Thrown when a hotkey attempts to join the root subnet with too little stake AllNetworksInImmunity, // --- Thrown when all subnets are in the immunity period NotEnoughBalance, + InvalidTake, // -- Thrown when take being set is invalid. } // ================== @@ -1279,6 +1281,38 @@ pub mod pallet { Self::do_become_delegate(origin, hotkey, Self::get_default_take()) } + // --- Allows delegates to decrease its take value. + // + // # Args: + // * 'origin': (::Origin): + // - The signature of the caller's coldkey. + // + // * 'hotkey' (T::AccountId): + // - The hotkey we are delegating (must be owned by the coldkey.) + // + // * 'take' (u16): + // - The new stake proportion that this hotkey takes from delegations. + // + // # Event: + // * TakeDecreased; + // - On successfully setting a decreased take for this hotkey. + // + // # Raises: + // * 'NotRegistered': + // - The hotkey we are delegating is not registered on the network. + // + // * 'NonAssociatedColdKey': + // - The hotkey we are delegating is not owned by the calling coldkey. + // + // * 'InvalidTransaction': + // - The delegate is setting a take which is not lower than the previous. + // + #[pallet::call_index(63)] + #[pallet::weight((0, DispatchClass::Normal, Pays::No))] + pub fn decrease_take(origin: OriginFor, hotkey: T::AccountId, take: u16) -> DispatchResult { + Self::do_decrease_take(origin, hotkey, take) + } + // --- Adds stake to a hotkey. The call is made from the // coldkey account linked in the hotkey. // Only the associated coldkey is allowed to make staking and @@ -1325,6 +1359,7 @@ pub mod pallet { Self::do_add_stake(origin, hotkey, amount_staked) } + // ---- Remove stake from the staking account. The call must be made // from the coldkey account attached to the neuron metadata. Only this key // has permission to make staking and unstaking requests. diff --git a/pallets/subtensor/src/staking.rs b/pallets/subtensor/src/staking.rs index 7f723cb718..d8aa9573b5 100644 --- a/pallets/subtensor/src/staking.rs +++ b/pallets/subtensor/src/staking.rs @@ -86,6 +86,87 @@ impl Pallet { Ok(()) } + // ---- The implementation for the extrinsic decrease_take + // + // # Args: + // * 'origin': (::RuntimeOrigin): + // - The signature of the caller's coldkey. + // + // * 'hotkey' (T::AccountId): + // - The hotkey we are delegating (must be owned by the coldkey.) + // + // * 'take' (u16): + // - The stake proportion that this hotkey takes from delegations. + // + // # Event: + // * TakeDecreased; + // - On successfully setting a decreased take for this hotkey. + // + // # Raises: + // * 'NotRegistered': + // - The hotkey we are delegating is not registered on the network. + // + // * 'NonAssociatedColdKey': + // - The hotkey we are delegating is not owned by the calling coldket. + // + // * 'TxRateLimitExceeded': + // - Thrown if key has hit transaction rate limit + // + pub fn do_decrease_take( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + take: u16, + ) -> dispatch::DispatchResult { + // --- 1. We check the coldkey signature. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_decrease_take( origin:{:?} hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + + // --- 2. Ensure we are delegating a known key. + ensure!( + Self::hotkey_account_exists(&hotkey), + Error::::NotRegistered + ); + + // --- 3. Ensure that the coldkey is the owner. + ensure!( + Self::coldkey_owns_hotkey(&coldkey, &hotkey), + Error::::NonAssociatedColdKey + ); + + // --- 4. Ensure we are not already a delegate (dont allow changing delegate take.) + ensure!( + !Self::hotkey_is_delegate(&hotkey), + Error::::AlreadyDelegate + ); + + // --- 5. Ensure we are always decreasing take never increasing. + let current_take: u16 = Delegates::::get(hotkey.clone()); + ensure!( + take < current_take, + Error::::InvalidTake + ); + + // --- 6. Set the new take value. + Delegates::::insert(hotkey.clone(), take); + + // --- 7. Emit the take value. + log::info!( + "TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + Self::deposit_event(Event::TakeDecreased(coldkey, hotkey, take)); + + // --- 8. Ok and return. + Ok(()) + } + // ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. // // # Args: