From 1f30cdde6668d28fa8834c15a0a5f5d4fef8bd41 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sat, 18 Jan 2025 18:49:56 +0100 Subject: [PATCH 1/6] transfer stake (untested) --- pallets/subtensor/src/macros/dispatches.rs | 29 ++++++ pallets/subtensor/src/macros/events.rs | 2 + pallets/subtensor/src/staking/mod.rs | 1 + .../subtensor/src/staking/transfer_stake.rs | 89 +++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 pallets/subtensor/src/staking/transfer_stake.rs diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 7073a1413..3e0ce6caf 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1596,5 +1596,34 @@ mod dispatches { alpha_amount, ) } + /// ---- The implementation for the extrinsic transfer_stake: Moves specified amount of stake from a coldkey to another. + /// + /// # Args: + /// * `origin` - (::Origin): + /// - The signature of the caller's coldkey. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey account to move stake from. + /// + /// * `destination_coldkey` (T::AccountId): + /// - The coldkey account to move stake to. + /// + /// * `netuid` (T::AccountId): + /// - The subnet ID to move stake from. + /// + /// * `alpha_amount` (T::AccountId): + /// - The alpha stake amount to move. + /// + #[pallet::call_index(86)] + #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + pub fn transfer_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + destination_coldkey: T::AccountId, + netuid: u16, + alpha_amount: u64, + ) -> DispatchResult { + Self::do_transfer_stake(origin, hotkey, destination_coldkey, netuid, alpha_amount) + } } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 30566ac47..85d69a698 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -17,6 +17,8 @@ mod events { StakeAdded(T::AccountId, T::AccountId, u64, u64, u16), /// stake has been removed from the hotkey staking account onto the coldkey account. StakeRemoved(T::AccountId, T::AccountId, u64, u64, u16), + /// stake has been transfered from one coldkey to another. + StakeTransferred(T::AccountId, T::AccountId, T::AccountId, u16, u64), /// stake has been moved from origin (hotkey, subnet ID) to destination (hotkey, subnet ID) of this amount (in TAO). StakeMoved(T::AccountId, T::AccountId, u16, T::AccountId, u16, u64), /// a caller successfully sets their weights on a subnetwork. diff --git a/pallets/subtensor/src/staking/mod.rs b/pallets/subtensor/src/staking/mod.rs index 2b222036c..d8b232c20 100644 --- a/pallets/subtensor/src/staking/mod.rs +++ b/pallets/subtensor/src/staking/mod.rs @@ -7,3 +7,4 @@ pub mod move_stake; pub mod remove_stake; pub mod set_children; pub mod stake_utils; +pub mod transfer_stake; diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs new file mode 100644 index 000000000..21710d14c --- /dev/null +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -0,0 +1,89 @@ +use super::*; + +impl Pallet { + /// Transfers stake from one coldkey to another. + /// + /// # Arguments + /// * `origin` - The origin of the transaction, which must be signed by the `origin_hotkey`. + /// * `hotkey` - The account ID of the hotkey from which the stake is being moved. + /// * `destination_coldkey` - The account ID of the coldkey to which the stake is being moved. + /// * `netuid` - The network ID of the subnet. + /// * `alpha_amount` - The amount of alpha to move. + /// + /// # Returns + /// * `DispatchResult` - Indicates the success or failure of the operation. + /// + /// # Errors + /// This function will return an error if: + /// * The origin is not signed by the `origin_coldkey`. + /// * The subnet does not exist. + /// * The `hotkey` does not exist. + /// + /// # Events + /// Emits a `StakeTransferred` event upon successful completion of the stake movement. + pub fn do_transfer_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + destination_coldkey: T::AccountId, + netuid: u16, + alpha_amount: u64, + ) -> dispatch::DispatchResult { + // --- 1. Check that the origin is signed by the origin_hotkey. + let coldkey = ensure_signed(origin)?; + + // --- 2. Check that the subnet exists. + ensure!(Self::if_subnet_exist(netuid), Error::::SubnetNotExists); + + // --- 3. Check that the hotkey exists. + ensure!( + Self::hotkey_account_exists(&hotkey), + Error::::HotKeyAccountNotExists + ); + + // --- 4. Get the current alpha stake for the origin hotkey-coldkey pair in the origin subnet + let origin_alpha = + Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); + ensure!( + alpha_amount <= origin_alpha, + Error::::NotEnoughStakeToWithdraw + ); + + let origin_tao: u64 = Self::swap_alpha_for_tao(netuid, alpha_amount); + + // --- 5. Unstake the amount of alpha from the origin coldkey + Self::decrease_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey.clone(), + &coldkey.clone(), + netuid, + alpha_amount, + ); + + // --- 6. Unstake the amount of alpha for the destination coldkey + Self::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey.clone(), + &destination_coldkey.clone(), + netuid, + alpha_amount, + ); + + // --- 7. Log the event. + log::info!( + "StakeTransferred( coldkey:{:?}, origin_hotkey:{:?}, origin_netuid:{:?}, destination_hotkey:{:?}, destination_netuid:{:?} )", + coldkey.clone(), + destination_coldkey.clone(), + hotkey, + netuid.clone(), + origin_tao + ); + Self::deposit_event(Event::StakeTransferred( + coldkey, + destination_coldkey, + hotkey, + netuid, + origin_tao, + )); + + // -- 8. Ok and return. + Ok(()) + } +} From 93d790c49817ea5c9dd6193bdb617a92a7294292 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sun, 19 Jan 2025 14:31:11 +0100 Subject: [PATCH 2/6] Update pallets/subtensor/src/staking/transfer_stake.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/src/staking/transfer_stake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs index 21710d14c..3bad491cc 100644 --- a/pallets/subtensor/src/staking/transfer_stake.rs +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -58,7 +58,7 @@ impl Pallet { alpha_amount, ); - // --- 6. Unstake the amount of alpha for the destination coldkey + // --- 6. Stake the amount of alpha for the destination coldkey Self::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey.clone(), &destination_coldkey.clone(), From 0bf13096d74e84a6a3dbf41996f18242877d6632 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sun, 19 Jan 2025 14:31:55 +0100 Subject: [PATCH 3/6] Update pallets/subtensor/src/staking/transfer_stake.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/src/staking/transfer_stake.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs index 3bad491cc..29bfde72a 100644 --- a/pallets/subtensor/src/staking/transfer_stake.rs +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -41,10 +41,8 @@ impl Pallet { ); // --- 4. Get the current alpha stake for the origin hotkey-coldkey pair in the origin subnet - let origin_alpha = - Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); ensure!( - alpha_amount <= origin_alpha, + Self::has_enough_stake_on_subnet(&hotkey, &coldkey, netuid, alpha_amount) Error::::NotEnoughStakeToWithdraw ); From cc8e30c2d075b2063a82fa23233221d8d34752c6 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sun, 19 Jan 2025 14:33:27 +0100 Subject: [PATCH 4/6] Update pallets/subtensor/src/staking/transfer_stake.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/src/staking/transfer_stake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs index 29bfde72a..8aed40f7f 100644 --- a/pallets/subtensor/src/staking/transfer_stake.rs +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -66,12 +66,12 @@ impl Pallet { // --- 7. Log the event. log::info!( - "StakeTransferred( coldkey:{:?}, origin_hotkey:{:?}, origin_netuid:{:?}, destination_hotkey:{:?}, destination_netuid:{:?} )", + "StakeTransferred( coldkey:{:?}, destination_coldkey:{:?}, hotkey:{:?}, netuid:{:?}, alpha:{:?} )", coldkey.clone(), destination_coldkey.clone(), hotkey, netuid.clone(), - origin_tao + alpha_amount ); Self::deposit_event(Event::StakeTransferred( coldkey, From 861433ab0bf581e378f39dc1834f4b8c77c5c713 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sun, 19 Jan 2025 14:34:20 +0100 Subject: [PATCH 5/6] Update pallets/subtensor/src/staking/transfer_stake.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/src/staking/transfer_stake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs index 8aed40f7f..a8b89a4ac 100644 --- a/pallets/subtensor/src/staking/transfer_stake.rs +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -78,7 +78,7 @@ impl Pallet { destination_coldkey, hotkey, netuid, - origin_tao, + alpha_amount, )); // -- 8. Ok and return. From 961d6acbb000354abb871f0ef1d3ea21af3bd408 Mon Sep 17 00:00:00 2001 From: Ben Mason Date: Sun, 19 Jan 2025 14:38:59 +0100 Subject: [PATCH 6/6] remove tao swap --- pallets/subtensor/src/staking/transfer_stake.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pallets/subtensor/src/staking/transfer_stake.rs b/pallets/subtensor/src/staking/transfer_stake.rs index a8b89a4ac..f383851bc 100644 --- a/pallets/subtensor/src/staking/transfer_stake.rs +++ b/pallets/subtensor/src/staking/transfer_stake.rs @@ -18,6 +18,7 @@ impl Pallet { /// * The origin is not signed by the `origin_coldkey`. /// * The subnet does not exist. /// * The `hotkey` does not exist. + /// * The coldkey doesn't have enough stake to transfer. /// /// # Events /// Emits a `StakeTransferred` event upon successful completion of the stake movement. @@ -42,12 +43,10 @@ impl Pallet { // --- 4. Get the current alpha stake for the origin hotkey-coldkey pair in the origin subnet ensure!( - Self::has_enough_stake_on_subnet(&hotkey, &coldkey, netuid, alpha_amount) + Self::has_enough_stake_on_subnet(&hotkey, &coldkey, netuid, alpha_amount), Error::::NotEnoughStakeToWithdraw ); - let origin_tao: u64 = Self::swap_alpha_for_tao(netuid, alpha_amount); - // --- 5. Unstake the amount of alpha from the origin coldkey Self::decrease_stake_for_hotkey_and_coldkey_on_subnet( &hotkey.clone(), @@ -66,7 +65,7 @@ impl Pallet { // --- 7. Log the event. log::info!( - "StakeTransferred( coldkey:{:?}, destination_coldkey:{:?}, hotkey:{:?}, netuid:{:?}, alpha:{:?} )", + "StakeTransferred( coldkey:{:?}, destination_coldkey:{:?}, hotkey:{:?}, netuid:{:?}, alpha_amount:{:?} )", coldkey.clone(), destination_coldkey.clone(), hotkey,