Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transfer stake (untested) #1170

Open
wants to merge 6 commits into
base: devnet-ready
Choose a base branch
from
Open
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
29 changes: 29 additions & 0 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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` - (<T as frame_system::Config>::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)
}
}
}
2 changes: 2 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions pallets/subtensor/src/staking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod move_stake;
pub mod remove_stake;
pub mod set_children;
pub mod stake_utils;
pub mod transfer_stake;
86 changes: 86 additions & 0 deletions pallets/subtensor/src/staking/transfer_stake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use super::*;

impl<T: Config> Pallet<T> {
/// 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.
/// * The coldkey doesn't have enough stake to transfer.
///
/// # 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::<T>::SubnetNotExists);

// --- 3. Check that the hotkey exists.
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

// --- 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),
Error::<T>::NotEnoughStakeToWithdraw
);

// --- 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. Stake 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:{:?}, destination_coldkey:{:?}, hotkey:{:?}, netuid:{:?}, alpha_amount:{:?} )",
coldkey.clone(),
destination_coldkey.clone(),
hotkey,
netuid.clone(),
alpha_amount
);
Self::deposit_event(Event::StakeTransferred(
coldkey,
destination_coldkey,
hotkey,
netuid,
alpha_amount,
));

// -- 8. Ok and return.
Ok(())
}
}