Skip to content

Commit 2977bdf

Browse files
authored
Merge pull request #1183 from opentensor/feat/add-staking-tx-fees-to-subnet-tao
Separate defaults for tx fee from min stake + tx validation
2 parents d91dc3c + beb6f6b commit 2977bdf

File tree

14 files changed

+475
-323
lines changed

14 files changed

+475
-323
lines changed

pallets/subtensor/src/lib.rs

Lines changed: 158 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ use frame_support::{
1212
dispatch::{self, DispatchInfo, DispatchResult, DispatchResultWithPostInfo, PostDispatchInfo},
1313
ensure,
1414
pallet_macros::import_section,
15-
traits::{
16-
tokens::{fungible, Fortitude, Preservation},
17-
IsSubType,
18-
},
15+
traits::{tokens::fungible, IsSubType},
1916
};
2017

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

711+
#[pallet::type_value]
712+
/// Default staking fee.
713+
/// 500k rao matches $0.25 at $500/TAO
714+
pub fn DefaultStakingFee<T: Config>() -> u64 {
715+
500_000
716+
}
717+
715718
#[pallet::type_value]
716719
/// Default unicode vector for tau symbol.
717720
pub fn DefaultUnicodeVecU8<T: Config>() -> Vec<u8> {
@@ -1554,13 +1557,25 @@ pub enum CallType {
15541557
pub enum CustomTransactionError {
15551558
ColdkeyInSwapSchedule,
15561559
StakeAmountTooLow,
1560+
BalanceTooLow,
1561+
SubnetDoesntExist,
1562+
HotkeyAccountDoesntExist,
1563+
NotEnoughStakeToWithdraw,
1564+
RateLimitExceeded,
1565+
BadRequest,
15571566
}
15581567

15591568
impl From<CustomTransactionError> for u8 {
15601569
fn from(variant: CustomTransactionError) -> u8 {
15611570
match variant {
15621571
CustomTransactionError::ColdkeyInSwapSchedule => 0,
15631572
CustomTransactionError::StakeAmountTooLow => 1,
1573+
CustomTransactionError::BalanceTooLow => 2,
1574+
CustomTransactionError::SubnetDoesntExist => 3,
1575+
CustomTransactionError::HotkeyAccountDoesntExist => 4,
1576+
CustomTransactionError::NotEnoughStakeToWithdraw => 5,
1577+
CustomTransactionError::RateLimitExceeded => 6,
1578+
CustomTransactionError::BadRequest => 255,
15641579
}
15651580
}
15661581
}
@@ -1603,6 +1618,41 @@ where
16031618
pub fn check_weights_min_stake(who: &T::AccountId, netuid: u16) -> bool {
16041619
Pallet::<T>::check_weights_min_stake(who, netuid)
16051620
}
1621+
1622+
pub fn result_to_validity(result: Result<(), Error<T>>) -> TransactionValidity {
1623+
if let Err(err) = result {
1624+
match err {
1625+
Error::<T>::AmountTooLow => Err(InvalidTransaction::Custom(
1626+
CustomTransactionError::StakeAmountTooLow.into(),
1627+
)
1628+
.into()),
1629+
Error::<T>::SubnetNotExists => Err(InvalidTransaction::Custom(
1630+
CustomTransactionError::SubnetDoesntExist.into(),
1631+
)
1632+
.into()),
1633+
Error::<T>::NotEnoughBalanceToStake => Err(InvalidTransaction::Custom(
1634+
CustomTransactionError::BalanceTooLow.into(),
1635+
)
1636+
.into()),
1637+
Error::<T>::HotKeyAccountNotExists => Err(InvalidTransaction::Custom(
1638+
CustomTransactionError::HotkeyAccountDoesntExist.into(),
1639+
)
1640+
.into()),
1641+
Error::<T>::NotEnoughStakeToWithdraw => Err(InvalidTransaction::Custom(
1642+
CustomTransactionError::NotEnoughStakeToWithdraw.into(),
1643+
)
1644+
.into()),
1645+
_ => Err(
1646+
InvalidTransaction::Custom(CustomTransactionError::BadRequest.into()).into(),
1647+
),
1648+
}
1649+
} else {
1650+
Ok(ValidTransaction {
1651+
priority: Self::get_priority_vanilla(),
1652+
..Default::default()
1653+
})
1654+
}
1655+
}
16061656
}
16071657

16081658
impl<T: Config + Send + Sync + TypeInfo> sp_std::fmt::Debug for SubtensorSignedExtension<T> {
@@ -1647,7 +1697,10 @@ where
16471697
..Default::default()
16481698
})
16491699
} else {
1650-
Err(InvalidTransaction::Custom(1).into())
1700+
Err(InvalidTransaction::Custom(
1701+
CustomTransactionError::StakeAmountTooLow.into(),
1702+
)
1703+
.into())
16511704
}
16521705
}
16531706
Some(Call::reveal_weights { netuid, .. }) => {
@@ -1659,7 +1712,10 @@ where
16591712
..Default::default()
16601713
})
16611714
} else {
1662-
Err(InvalidTransaction::Custom(2).into())
1715+
Err(InvalidTransaction::Custom(
1716+
CustomTransactionError::StakeAmountTooLow.into(),
1717+
)
1718+
.into())
16631719
}
16641720
}
16651721
Some(Call::batch_reveal_weights { netuid, .. }) => {
@@ -1671,7 +1727,10 @@ where
16711727
..Default::default()
16721728
})
16731729
} else {
1674-
Err(InvalidTransaction::Custom(6).into())
1730+
Err(InvalidTransaction::Custom(
1731+
CustomTransactionError::StakeAmountTooLow.into(),
1732+
)
1733+
.into())
16751734
}
16761735
}
16771736
Some(Call::set_weights { netuid, .. }) => {
@@ -1683,7 +1742,10 @@ where
16831742
..Default::default()
16841743
})
16851744
} else {
1686-
Err(InvalidTransaction::Custom(3).into())
1745+
Err(InvalidTransaction::Custom(
1746+
CustomTransactionError::StakeAmountTooLow.into(),
1747+
)
1748+
.into())
16871749
}
16881750
}
16891751
Some(Call::set_tao_weights { netuid, hotkey, .. }) => {
@@ -1695,7 +1757,10 @@ where
16951757
..Default::default()
16961758
})
16971759
} else {
1698-
Err(InvalidTransaction::Custom(4).into())
1760+
Err(InvalidTransaction::Custom(
1761+
CustomTransactionError::StakeAmountTooLow.into(),
1762+
)
1763+
.into())
16991764
}
17001765
}
17011766
Some(Call::commit_crv3_weights { netuid, .. }) => {
@@ -1707,38 +1772,91 @@ where
17071772
..Default::default()
17081773
})
17091774
} else {
1710-
Err(InvalidTransaction::Custom(7).into())
1775+
Err(InvalidTransaction::Custom(
1776+
CustomTransactionError::StakeAmountTooLow.into(),
1777+
)
1778+
.into())
17111779
}
17121780
}
17131781
Some(Call::add_stake {
1714-
hotkey: _,
1715-
netuid: _,
1782+
hotkey,
1783+
netuid,
17161784
amount_staked,
17171785
}) => {
1718-
// Check that amount parameter is at least the min stake
1719-
// also check the coldkey balance
1720-
let coldkey_balance = <<T as Config>::Currency as fungible::Inspect<
1721-
<T as frame_system::Config>::AccountId,
1722-
>>::reducible_balance(
1723-
who, Preservation::Expendable, Fortitude::Polite
1724-
);
1725-
1726-
if (*amount_staked < DefaultMinStake::<T>::get())
1727-
|| (coldkey_balance < DefaultMinStake::<T>::get())
1728-
{
1729-
InvalidTransaction::Custom(CustomTransactionError::StakeAmountTooLow.into())
1730-
.into()
1731-
} else {
1732-
Ok(ValidTransaction {
1733-
priority: Self::get_priority_vanilla(),
1734-
..Default::default()
1735-
})
1736-
}
1786+
// Fully validate the user input
1787+
Self::result_to_validity(Pallet::<T>::validate_add_stake(
1788+
who,
1789+
hotkey,
1790+
*netuid,
1791+
*amount_staked,
1792+
))
1793+
}
1794+
Some(Call::remove_stake {
1795+
hotkey,
1796+
netuid,
1797+
amount_unstaked,
1798+
}) => {
1799+
// Fully validate the user input
1800+
Self::result_to_validity(Pallet::<T>::validate_remove_stake(
1801+
who,
1802+
hotkey,
1803+
*netuid,
1804+
*amount_unstaked,
1805+
))
1806+
}
1807+
Some(Call::move_stake {
1808+
origin_hotkey,
1809+
destination_hotkey,
1810+
origin_netuid,
1811+
destination_netuid,
1812+
alpha_amount,
1813+
}) => {
1814+
// Fully validate the user input
1815+
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
1816+
who,
1817+
who,
1818+
origin_hotkey,
1819+
destination_hotkey,
1820+
*origin_netuid,
1821+
*destination_netuid,
1822+
*alpha_amount,
1823+
))
1824+
}
1825+
Some(Call::transfer_stake {
1826+
destination_coldkey,
1827+
hotkey,
1828+
origin_netuid,
1829+
destination_netuid,
1830+
alpha_amount,
1831+
}) => {
1832+
// Fully validate the user input
1833+
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
1834+
who,
1835+
destination_coldkey,
1836+
hotkey,
1837+
hotkey,
1838+
*origin_netuid,
1839+
*destination_netuid,
1840+
*alpha_amount,
1841+
))
1842+
}
1843+
Some(Call::swap_stake {
1844+
hotkey,
1845+
origin_netuid,
1846+
destination_netuid,
1847+
alpha_amount,
1848+
}) => {
1849+
// Fully validate the user input
1850+
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
1851+
who,
1852+
who,
1853+
hotkey,
1854+
hotkey,
1855+
*origin_netuid,
1856+
*destination_netuid,
1857+
*alpha_amount,
1858+
))
17371859
}
1738-
Some(Call::remove_stake { .. }) => Ok(ValidTransaction {
1739-
priority: Self::get_priority_vanilla(),
1740-
..Default::default()
1741-
}),
17421860
Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => {
17431861
let registrations_this_interval =
17441862
Pallet::<T>::get_registrations_this_interval(*netuid);
@@ -1747,7 +1865,10 @@ where
17471865
if registrations_this_interval >= (max_registrations_per_interval.saturating_mul(3))
17481866
{
17491867
// If the registration limit for the interval is exceeded, reject the transaction
1750-
return Err(InvalidTransaction::Custom(5).into());
1868+
return Err(InvalidTransaction::Custom(
1869+
CustomTransactionError::RateLimitExceeded.into(),
1870+
)
1871+
.into());
17511872
}
17521873
Ok(ValidTransaction {
17531874
priority: Self::get_priority_vanilla(),

pallets/subtensor/src/macros/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ mod errors {
2525
/// Request to stake, unstake or subscribe is made by a coldkey that is not associated with
2626
/// the hotkey account.
2727
NonAssociatedColdKey,
28-
/// Stake amount to withdraw is zero.
29-
StakeToWithdrawIsZero,
28+
/// DEPRECATED: Stake amount to withdraw is zero.
29+
// StakeToWithdrawIsZero,
3030
/// The caller does not have enought stake to perform this action.
3131
NotEnoughStake,
3232
/// The caller is requesting removing more stake than there exists in the staking account.

pallets/subtensor/src/staking/add_stake.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,34 +47,16 @@ impl<T: Config> Pallet<T> {
4747
stake_to_be_added
4848
);
4949

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

53-
// 3. Ensure the callers coldkey has enough stake to perform the transaction.
54-
ensure!(
55-
Self::can_remove_balance_from_coldkey_account(&coldkey, stake_to_be_added),
56-
Error::<T>::NotEnoughBalanceToStake
57-
);
58-
59-
// 4. Ensure that the hotkey account exists this is only possible through registration.
60-
ensure!(
61-
Self::hotkey_account_exists(&hotkey),
62-
Error::<T>::HotKeyAccountNotExists
63-
);
64-
65-
// Ensure stake_to_be_added is at least DefaultMinStake
66-
ensure!(
67-
stake_to_be_added >= DefaultMinStake::<T>::get(),
68-
Error::<T>::AmountTooLow
69-
);
70-
71-
// 5. Ensure the remove operation from the coldkey is a success.
53+
// 3. Ensure the remove operation from the coldkey is a success.
7254
let tao_staked: u64 =
7355
Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?;
7456

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

8062
// Ok and return.

0 commit comments

Comments
 (0)