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

Separate defaults for tx fee from min stake + tx validation #1183

Merged
merged 6 commits into from
Jan 24, 2025
Merged
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
195 changes: 158 additions & 37 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ use frame_support::{
dispatch::{self, DispatchInfo, DispatchResult, DispatchResultWithPostInfo, PostDispatchInfo},
ensure,
pallet_macros::import_section,
traits::{
tokens::{fungible, Fortitude, Preservation},
IsSubType,
},
traits::{tokens::fungible, IsSubType},
};

use codec::{Decode, Encode};
Expand Down Expand Up @@ -707,11 +704,17 @@ pub mod pallet {
#[pallet::type_value]
/// Default minimum stake.
/// 500k rao matches $0.25 at $500/TAO
/// Also used as staking fee
pub fn DefaultMinStake<T: Config>() -> u64 {
500_000
}

#[pallet::type_value]
/// Default staking fee.
/// 500k rao matches $0.25 at $500/TAO
pub fn DefaultStakingFee<T: Config>() -> u64 {
500_000
}

#[pallet::type_value]
/// Default unicode vector for tau symbol.
pub fn DefaultUnicodeVecU8<T: Config>() -> Vec<u8> {
Expand Down Expand Up @@ -1554,13 +1557,25 @@ pub enum CallType {
pub enum CustomTransactionError {
ColdkeyInSwapSchedule,
StakeAmountTooLow,
BalanceTooLow,
SubnetDoesntExist,
HotkeyAccountDoesntExist,
NotEnoughStakeToWithdraw,
RateLimitExceeded,
BadRequest,
}

impl From<CustomTransactionError> for u8 {
fn from(variant: CustomTransactionError) -> u8 {
match variant {
CustomTransactionError::ColdkeyInSwapSchedule => 0,
CustomTransactionError::StakeAmountTooLow => 1,
CustomTransactionError::BalanceTooLow => 2,
CustomTransactionError::SubnetDoesntExist => 3,
CustomTransactionError::HotkeyAccountDoesntExist => 4,
CustomTransactionError::NotEnoughStakeToWithdraw => 5,
CustomTransactionError::RateLimitExceeded => 6,
CustomTransactionError::BadRequest => 255,
}
}
}
Expand Down Expand Up @@ -1603,6 +1618,41 @@ where
pub fn check_weights_min_stake(who: &T::AccountId, netuid: u16) -> bool {
Pallet::<T>::check_weights_min_stake(who, netuid)
}

pub fn result_to_validity(result: Result<(), Error<T>>) -> TransactionValidity {
if let Err(err) = result {
match err {
Error::<T>::AmountTooLow => Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into()),
Error::<T>::SubnetNotExists => Err(InvalidTransaction::Custom(
CustomTransactionError::SubnetDoesntExist.into(),
)
.into()),
Error::<T>::NotEnoughBalanceToStake => Err(InvalidTransaction::Custom(
CustomTransactionError::BalanceTooLow.into(),
)
.into()),
Error::<T>::HotKeyAccountNotExists => Err(InvalidTransaction::Custom(
CustomTransactionError::HotkeyAccountDoesntExist.into(),
)
.into()),
Error::<T>::NotEnoughStakeToWithdraw => Err(InvalidTransaction::Custom(
CustomTransactionError::NotEnoughStakeToWithdraw.into(),
)
.into()),
_ => Err(
InvalidTransaction::Custom(CustomTransactionError::BadRequest.into()).into(),
),
}
} else {
Ok(ValidTransaction {
priority: Self::get_priority_vanilla(),
..Default::default()
})
}
}
}

impl<T: Config + Send + Sync + TypeInfo> sp_std::fmt::Debug for SubtensorSignedExtension<T> {
Expand Down Expand Up @@ -1647,7 +1697,10 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(1).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::reveal_weights { netuid, .. }) => {
Expand All @@ -1659,7 +1712,10 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(2).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::batch_reveal_weights { netuid, .. }) => {
Expand All @@ -1671,7 +1727,10 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(6).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::set_weights { netuid, .. }) => {
Expand All @@ -1683,7 +1742,10 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(3).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::set_tao_weights { netuid, hotkey, .. }) => {
Expand All @@ -1695,7 +1757,10 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(4).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::commit_crv3_weights { netuid, .. }) => {
Expand All @@ -1707,38 +1772,91 @@ where
..Default::default()
})
} else {
Err(InvalidTransaction::Custom(7).into())
Err(InvalidTransaction::Custom(
CustomTransactionError::StakeAmountTooLow.into(),
)
.into())
}
}
Some(Call::add_stake {
hotkey: _,
netuid: _,
hotkey,
netuid,
amount_staked,
}) => {
// Check that amount parameter is at least the min stake
// also check the coldkey balance
let coldkey_balance = <<T as Config>::Currency as fungible::Inspect<
<T as frame_system::Config>::AccountId,
>>::reducible_balance(
who, Preservation::Expendable, Fortitude::Polite
);

if (*amount_staked < DefaultMinStake::<T>::get())
|| (coldkey_balance < DefaultMinStake::<T>::get())
{
InvalidTransaction::Custom(CustomTransactionError::StakeAmountTooLow.into())
.into()
} else {
Ok(ValidTransaction {
priority: Self::get_priority_vanilla(),
..Default::default()
})
}
// Fully validate the user input
Self::result_to_validity(Pallet::<T>::validate_add_stake(
who,
hotkey,
*netuid,
*amount_staked,
))
}
Some(Call::remove_stake {
hotkey,
netuid,
amount_unstaked,
}) => {
// Fully validate the user input
Self::result_to_validity(Pallet::<T>::validate_remove_stake(
who,
hotkey,
*netuid,
*amount_unstaked,
))
}
Some(Call::move_stake {
origin_hotkey,
destination_hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
}) => {
// 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,
))
}
Some(Call::transfer_stake {
destination_coldkey,
hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
}) => {
// Fully validate the user input
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
who,
destination_coldkey,
hotkey,
hotkey,
*origin_netuid,
*destination_netuid,
*alpha_amount,
))
}
Some(Call::swap_stake {
hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
}) => {
// Fully validate the user input
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
who,
who,
hotkey,
hotkey,
*origin_netuid,
*destination_netuid,
*alpha_amount,
))
}
Some(Call::remove_stake { .. }) => Ok(ValidTransaction {
priority: Self::get_priority_vanilla(),
..Default::default()
}),
Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => {
let registrations_this_interval =
Pallet::<T>::get_registrations_this_interval(*netuid);
Expand All @@ -1747,7 +1865,10 @@ where
if registrations_this_interval >= (max_registrations_per_interval.saturating_mul(3))
{
// If the registration limit for the interval is exceeded, reject the transaction
return Err(InvalidTransaction::Custom(5).into());
return Err(InvalidTransaction::Custom(
CustomTransactionError::RateLimitExceeded.into(),
)
.into());
}
Ok(ValidTransaction {
priority: Self::get_priority_vanilla(),
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/macros/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ mod errors {
/// Request to stake, unstake or subscribe is made by a coldkey that is not associated with
/// the hotkey account.
NonAssociatedColdKey,
/// Stake amount to withdraw is zero.
StakeToWithdrawIsZero,
/// DEPRECATED: Stake amount to withdraw is zero.
// StakeToWithdrawIsZero,
/// The caller does not have enought stake to perform this action.
NotEnoughStake,
/// The caller is requesting removing more stake than there exists in the staking account.
Expand Down
28 changes: 5 additions & 23 deletions pallets/subtensor/src/staking/add_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,16 @@ impl<T: Config> Pallet<T> {
stake_to_be_added
);

// 2. Ensure that the subnet exists.
ensure!(Self::if_subnet_exist(netuid), Error::<T>::SubnetNotExists);
// 2. Validate user input
Self::validate_add_stake(&coldkey, &hotkey, netuid, stake_to_be_added)?;

// 3. Ensure the callers coldkey has enough stake to perform the transaction.
ensure!(
Self::can_remove_balance_from_coldkey_account(&coldkey, stake_to_be_added),
Error::<T>::NotEnoughBalanceToStake
);

// 4. Ensure that the hotkey account exists this is only possible through registration.
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

// Ensure stake_to_be_added is at least DefaultMinStake
ensure!(
stake_to_be_added >= DefaultMinStake::<T>::get(),
Error::<T>::AmountTooLow
);

// 5. Ensure the remove operation from the coldkey is a success.
// 3. Ensure the remove operation from the coldkey is a success.
let tao_staked: u64 =
Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?;

// 6. Swap the stake into alpha on the subnet and increase counters.
// 4. Swap the stake into alpha on the subnet and increase counters.
// Emit the staking event.
let fee = DefaultMinStake::<T>::get();
let fee = DefaultStakingFee::<T>::get();
Self::stake_into_subnet(&hotkey, &coldkey, netuid, tao_staked, fee);

// Ok and return.
Expand Down
Loading
Loading