Skip to content

Adds new move_stake_limit extrinsic #1583

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

Open
wants to merge 4 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
36 changes: 36 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2258,6 +2258,42 @@ where
Self::get_priority_staking(who, origin_hotkey, *alpha_amount),
)
}
Some(Call::move_stake_limit {
origin_hotkey,
destination_hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
limit_price,
allow_partial,
}) => {
if ColdkeySwapScheduled::<T>::contains_key(who) {
return InvalidTransaction::Custom(
CustomTransactionError::ColdkeyInSwapSchedule.into(),
)
.into();
}

// Get the max amount possible to exchange
let max_amount = Pallet::<T>::get_max_amount_move(*origin_netuid, *destination_netuid, *limit_price);

// Fully validate the user input
Self::result_to_validity(
Pallet::<T>::validate_stake_transition(
who,
who,
origin_hotkey,
destination_hotkey,
*origin_netuid,
*destination_netuid,
*alpha_amount,
max_amount,
Some(*allow_partial),
false,
),
Self::get_priority_staking(who, origin_hotkey, *alpha_amount),
)
}
Some(Call::transfer_stake {
destination_coldkey,
hotkey,
Expand Down
47 changes: 47 additions & 0 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,53 @@ mod dispatches {
)
}

/// Moves specified amount of stake from a hotkey to another across subnets with a price limit.
///
/// # Arguments
/// * `origin` - (<T as frame_system::Config>::Origin): - The signature of the caller's coldkey.
/// * `origin_hotkey` (T::AccountId): - The hotkey account to move stake from.
/// * `destination_hotkey` (T::AccountId): - The hotkey account to move stake to.
/// * `origin_netuid` (T::AccountId): - The subnet ID to move stake from.
/// * `destination_netuid` (T::AccountId): - The subnet ID to move stake to.
/// * `alpha_amount` (T::AccountId): - The alpha stake amount to move.
/// * `limit_price` (u64): - The limit price expressed in units of RAO per one Alpha.
/// * `allow_partial` (bool): - Allows partial execution of the amount. If set to false, this becomes fill or kill type or order.
///
/// # Errors
/// Returns an error if:
/// * The origin is not signed by the correct coldkey.
/// * Either subnet does not exist.
/// * The hotkeys do not exist.
/// * There is insufficient stake on `(coldkey, origin_hotkey, origin_netuid)`.
/// * The price is worse than the limit_price.
/// * The transfer amount is below the minimum stake requirement and partial execution is not allowed.
///
/// # Events
/// Emits a `StakeMoved` event upon successful completion of the stake movement.
#[pallet::call_index(94)]
#[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))]
pub fn move_stake_limit(
origin: T::RuntimeOrigin,
origin_hotkey: T::AccountId,
destination_hotkey: T::AccountId,
origin_netuid: u16,
destination_netuid: u16,
alpha_amount: u64,
limit_price: u64,
allow_partial: bool,
) -> DispatchResult {
Self::do_move_stake_limit(
origin,
origin_hotkey,
destination_hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
limit_price,
allow_partial,
)
}

/// Swaps a specified amount of stake from one subnet to another, while keeping the same coldkey and hotkey.
///
/// # Arguments
Expand Down
75 changes: 75 additions & 0 deletions pallets/subtensor/src/staking/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,81 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Moves stake from one hotkey to another across subnets with a price limit.
///
/// # Arguments
/// * `origin` - The origin of the transaction, which must be signed by the `origin_hotkey`.
/// * `origin_hotkey` - The account ID of the hotkey from which the stake is being moved.
/// * `destination_hotkey` - The account ID of the hotkey to which the stake is being moved.
/// * `origin_netuid` - The network ID of the origin subnet.
/// * `destination_netuid` - The network ID of the destination subnet.
/// * `alpha_amount` - The amount of stake to move.
/// * `limit_price` - The limit price expressed in units of RAO per one Alpha.
/// * `allow_partial` - Allows partial execution of the amount. If set to false, this becomes fill or kill type or order.
///
/// # 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_hotkey`.
/// * Either the origin or destination subnet does not exist.
/// * The `origin_hotkey` or `destination_hotkey` does not exist.
/// * There are locked funds that cannot be moved across subnets.
/// * The price is worse than the limit_price.
/// * The transfer amount is below the minimum stake requirement and partial execution is not allowed.
///
/// # Events
/// Emits a `StakeMoved` event upon successful completion of the stake movement.
pub fn do_move_stake_limit(
origin: T::RuntimeOrigin,
origin_hotkey: T::AccountId,
destination_hotkey: T::AccountId,
origin_netuid: u16,
destination_netuid: u16,
alpha_amount: u64,
limit_price: u64,
allow_partial: bool,
) -> dispatch::DispatchResult {
// Check that the origin is signed by the origin_hotkey.
let coldkey = ensure_signed(origin)?;

// Validate input and move stake
let tao_moved = Self::transition_stake_internal(
&coldkey,
&coldkey,
&origin_hotkey,
&destination_hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
Some(limit_price),
Some(allow_partial),
false,
)?;

// Log the event.
log::debug!(
"StakeMovedLimit( coldkey:{:?}, origin_hotkey:{:?}, origin_netuid:{:?}, destination_hotkey:{:?}, destination_netuid:{:?} )",
coldkey.clone(),
origin_hotkey.clone(),
origin_netuid,
destination_hotkey.clone(),
destination_netuid
);
Self::deposit_event(Event::StakeMoved(
coldkey,
origin_hotkey,
origin_netuid,
destination_hotkey,
destination_netuid,
tao_moved,
));

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

/// Transfers stake from one coldkey to another, optionally moving from one subnet to another,
/// while keeping the same hotkey.
///
Expand Down
Loading