Skip to content

Commit 0479ad1

Browse files
committed
Merge branch 'devnet-ready' into feat/ema-slowdown-hyperparam
2 parents d31e278 + f293e46 commit 0479ad1

File tree

13 files changed

+399
-80
lines changed

13 files changed

+399
-80
lines changed

pallets/admin-utils/src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ pub mod pallet {
2525
use super::*;
2626
use frame_support::pallet_prelude::*;
2727
use frame_support::traits::tokens::Balance;
28-
use frame_support::{dispatch::DispatchResult, pallet_prelude::StorageMap};
28+
use frame_support::{
29+
dispatch::{DispatchResult, RawOrigin},
30+
pallet_prelude::StorageMap,
31+
};
2932
use frame_system::pallet_prelude::*;
3033
use pallet_evm_chain_id::{self, ChainId};
34+
use pallet_subtensor::utils::rate_limiting::TransactionType;
3135
use sp_runtime::BoundedVec;
3236
use substrate_fixed::types::I96F32;
3337

@@ -249,12 +253,35 @@ pub mod pallet {
249253
netuid: u16,
250254
weights_version_key: u64,
251255
) -> DispatchResult {
252-
pallet_subtensor::Pallet::<T>::ensure_subnet_owner_or_root(origin, netuid)?;
256+
pallet_subtensor::Pallet::<T>::ensure_subnet_owner_or_root(origin.clone(), netuid)?;
253257

254258
ensure!(
255259
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
256260
Error::<T>::SubnetDoesNotExist
257261
);
262+
263+
if let Ok(RawOrigin::Signed(who)) = origin.into() {
264+
// SN Owner
265+
// Ensure the origin passes the rate limit.
266+
ensure!(
267+
pallet_subtensor::Pallet::<T>::passes_rate_limit_on_subnet(
268+
&TransactionType::SetWeightsVersionKey,
269+
&who,
270+
netuid,
271+
),
272+
pallet_subtensor::Error::<T>::TxRateLimitExceeded
273+
);
274+
275+
// Set last transaction block
276+
let current_block = pallet_subtensor::Pallet::<T>::get_current_block_as_u64();
277+
pallet_subtensor::Pallet::<T>::set_last_transaction_block_on_subnet(
278+
&who,
279+
netuid,
280+
&TransactionType::SetWeightsVersionKey,
281+
current_block,
282+
);
283+
}
284+
258285
pallet_subtensor::Pallet::<T>::set_weights_version_key(netuid, weights_version_key);
259286
log::debug!(
260287
"WeightsVersionKeySet( netuid: {:?} weights_version_key: {:?} ) ",

pallets/admin-utils/src/tests/mod.rs

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use frame_support::{
55
traits::Hooks,
66
};
77
use frame_system::Config;
8-
use pallet_subtensor::Error as SubtensorError;
8+
use pallet_subtensor::{Error as SubtensorError, SubnetOwner, Tempo, WeightsVersionKeyRateLimit};
99
// use pallet_subtensor::{migrations, Event};
1010
use pallet_subtensor::Event;
1111
use sp_consensus_grandpa::AuthorityId as GrandpaId;
@@ -162,6 +162,107 @@ fn test_sudo_set_weights_version_key() {
162162
});
163163
}
164164

165+
#[test]
166+
fn test_sudo_set_weights_version_key_rate_limit() {
167+
new_test_ext().execute_with(|| {
168+
let netuid: u16 = 1;
169+
let to_be_set: u64 = 10;
170+
171+
let sn_owner = U256::from(1);
172+
add_network(netuid, 10);
173+
// Set the Subnet Owner
174+
SubnetOwner::<Test>::insert(netuid, sn_owner);
175+
176+
let rate_limit = WeightsVersionKeyRateLimit::<Test>::get();
177+
let tempo: u16 = Tempo::<Test>::get(netuid);
178+
179+
let rate_limit_period = rate_limit * (tempo as u64);
180+
181+
assert_ok!(AdminUtils::sudo_set_weights_version_key(
182+
<<Test as Config>::RuntimeOrigin>::signed(sn_owner),
183+
netuid,
184+
to_be_set
185+
));
186+
assert_eq!(SubtensorModule::get_weights_version_key(netuid), to_be_set);
187+
188+
// Try to set again with
189+
// Assert rate limit not passed
190+
assert!(!SubtensorModule::passes_rate_limit_on_subnet(
191+
&pallet_subtensor::utils::rate_limiting::TransactionType::SetWeightsVersionKey,
192+
&sn_owner,
193+
netuid
194+
));
195+
196+
// Try transaction
197+
assert_noop!(
198+
AdminUtils::sudo_set_weights_version_key(
199+
<<Test as Config>::RuntimeOrigin>::signed(sn_owner),
200+
netuid,
201+
to_be_set + 1
202+
),
203+
pallet_subtensor::Error::<Test>::TxRateLimitExceeded
204+
);
205+
206+
// Wait for rate limit to pass
207+
run_to_block(rate_limit_period + 2);
208+
assert!(SubtensorModule::passes_rate_limit_on_subnet(
209+
&pallet_subtensor::utils::rate_limiting::TransactionType::SetWeightsVersionKey,
210+
&sn_owner,
211+
netuid
212+
));
213+
214+
// Try transaction
215+
assert_ok!(AdminUtils::sudo_set_weights_version_key(
216+
<<Test as Config>::RuntimeOrigin>::signed(sn_owner),
217+
netuid,
218+
to_be_set + 1
219+
));
220+
assert_eq!(
221+
SubtensorModule::get_weights_version_key(netuid),
222+
to_be_set + 1
223+
);
224+
});
225+
}
226+
227+
#[test]
228+
fn test_sudo_set_weights_version_key_rate_limit_root() {
229+
// root should not be effected by rate limit
230+
new_test_ext().execute_with(|| {
231+
let netuid: u16 = 1;
232+
let to_be_set: u64 = 10;
233+
234+
let sn_owner = U256::from(1);
235+
add_network(netuid, 10);
236+
// Set the Subnet Owner
237+
SubnetOwner::<Test>::insert(netuid, sn_owner);
238+
239+
let rate_limit = WeightsVersionKeyRateLimit::<Test>::get();
240+
let tempo: u16 = Tempo::<Test>::get(netuid);
241+
242+
let rate_limit_period = rate_limit * (tempo as u64);
243+
// Verify the rate limit is more than 0 blocks
244+
assert!(rate_limit_period > 0);
245+
246+
assert_ok!(AdminUtils::sudo_set_weights_version_key(
247+
<<Test as Config>::RuntimeOrigin>::root(),
248+
netuid,
249+
to_be_set
250+
));
251+
assert_eq!(SubtensorModule::get_weights_version_key(netuid), to_be_set);
252+
253+
// Try transaction
254+
assert_ok!(AdminUtils::sudo_set_weights_version_key(
255+
<<Test as Config>::RuntimeOrigin>::signed(sn_owner),
256+
netuid,
257+
to_be_set + 1
258+
));
259+
assert_eq!(
260+
SubtensorModule::get_weights_version_key(netuid),
261+
to_be_set + 1
262+
);
263+
});
264+
}
265+
165266
#[test]
166267
fn test_sudo_set_weights_set_rate_limit() {
167268
new_test_ext().execute_with(|| {

pallets/subtensor/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,12 @@ pub mod pallet {
514514
T::InitialNetworkRateLimit::get()
515515
}
516516
#[pallet::type_value]
517+
/// Default value for weights version key rate limit.
518+
/// In units of tempos.
519+
pub fn DefaultWeightsVersionKeyRateLimit<T: Config>() -> u64 {
520+
5 // 5 tempos
521+
}
522+
#[pallet::type_value]
517523
/// Default value for pending emission.
518524
pub fn DefaultPendingEmission<T: Config>() -> u64 {
519525
0
@@ -1082,6 +1088,10 @@ pub mod pallet {
10821088
pub type NetworkRateLimit<T> = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit<T>>;
10831089
#[pallet::storage] // --- ITEM( nominator_min_required_stake )
10841090
pub type NominatorMinRequiredStake<T> = StorageValue<_, u64, ValueQuery, DefaultZeroU64<T>>;
1091+
#[pallet::storage]
1092+
/// ITEM( weights_version_key_rate_limit ) --- Rate limit in tempos.
1093+
pub type WeightsVersionKeyRateLimit<T> =
1094+
StorageValue<_, u64, ValueQuery, DefaultWeightsVersionKeyRateLimit<T>>;
10851095

10861096
/// ============================
10871097
/// ==== Subnet Locks =====

pallets/subtensor/src/staking/add_stake.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::*;
2-
use sp_core::Get;
2+
use substrate_fixed::types::I96F32;
33

44
impl<T: Config> Pallet<T> {
55
/// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account.
@@ -58,13 +58,19 @@ impl<T: Config> Pallet<T> {
5858
)?;
5959

6060
// 3. Ensure the remove operation from the coldkey is a success.
61-
let tao_staked: u64 =
62-
Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?;
61+
let tao_staked: I96F32 =
62+
Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?.into();
6363

6464
// 4. Swap the stake into alpha on the subnet and increase counters.
6565
// Emit the staking event.
6666
let fee = DefaultStakingFee::<T>::get();
67-
Self::stake_into_subnet(&hotkey, &coldkey, netuid, tao_staked, fee);
67+
Self::stake_into_subnet(
68+
&hotkey,
69+
&coldkey,
70+
netuid,
71+
tao_staked.saturating_to_num::<u64>(),
72+
fee,
73+
);
6874

6975
// Ok and return.
7076
Ok(())
@@ -148,12 +154,19 @@ impl<T: Config> Pallet<T> {
148154
}
149155

150156
// 5. Ensure the remove operation from the coldkey is a success.
151-
let tao_staked: u64 = Self::remove_balance_from_coldkey_account(&coldkey, possible_stake)?;
157+
let tao_staked: I96F32 =
158+
Self::remove_balance_from_coldkey_account(&coldkey, possible_stake)?.into();
152159

153160
// 6. Swap the stake into alpha on the subnet and increase counters.
154161
// Emit the staking event.
155162
let fee = DefaultStakingFee::<T>::get();
156-
Self::stake_into_subnet(&hotkey, &coldkey, netuid, tao_staked, fee);
163+
Self::stake_into_subnet(
164+
&hotkey,
165+
&coldkey,
166+
netuid,
167+
tao_staked.saturating_to_num::<u64>(),
168+
fee,
169+
);
157170

158171
// Ok and return.
159172
Ok(())

pallets/subtensor/src/staking/move_stake.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use safe_math::*;
33
use sp_core::Get;
4-
use substrate_fixed::types::U64F64;
4+
use substrate_fixed::types::{I96F32, U64F64};
55

66
impl<T: Config> Pallet<T> {
77
/// Moves stake from one hotkey to another across subnets.
@@ -338,7 +338,13 @@ impl<T: Config> Pallet<T> {
338338
};
339339

340340
// Unstake from the origin subnet, returning TAO (or a 1:1 equivalent).
341-
let fee = DefaultStakingFee::<T>::get().safe_div(2);
341+
let fee = Self::calculate_staking_fee(
342+
origin_netuid,
343+
origin_hotkey,
344+
I96F32::saturating_from_num(alpha_amount),
345+
)
346+
.safe_div(2);
347+
342348
let tao_unstaked = Self::unstake_from_subnet(
343349
origin_hotkey,
344350
origin_coldkey,

pallets/subtensor/src/staking/remove_stake.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::*;
2-
use sp_core::Get;
2+
use substrate_fixed::types::I96F32;
33

44
impl<T: Config> Pallet<T> {
55
/// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey.
@@ -58,7 +58,11 @@ impl<T: Config> Pallet<T> {
5858
)?;
5959

6060
// 3. Swap the alpba to tao and update counters for this subnet.
61-
let fee = DefaultStakingFee::<T>::get();
61+
let fee = Self::calculate_staking_fee(
62+
netuid,
63+
&hotkey,
64+
I96F32::saturating_from_num(alpha_unstaked),
65+
);
6266
let tao_unstaked: u64 =
6367
Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee);
6468

@@ -109,8 +113,6 @@ impl<T: Config> Pallet<T> {
109113
origin: T::RuntimeOrigin,
110114
hotkey: T::AccountId,
111115
) -> dispatch::DispatchResult {
112-
let fee = DefaultStakingFee::<T>::get();
113-
114116
// 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information.
115117
let coldkey = ensure_signed(origin)?;
116118
log::info!("do_unstake_all( origin:{:?} hotkey:{:?} )", coldkey, hotkey);
@@ -126,20 +128,26 @@ impl<T: Config> Pallet<T> {
126128
log::debug!("All subnet netuids: {:?}", netuids);
127129

128130
// 4. Iterate through all subnets and remove stake.
129-
for netuid in netuids.iter() {
131+
for netuid in netuids.into_iter() {
130132
// Ensure that the hotkey has enough stake to withdraw.
131133
let alpha_unstaked =
132-
Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid);
134+
Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid);
135+
let fee = Self::calculate_staking_fee(
136+
netuid,
137+
&hotkey,
138+
I96F32::saturating_from_num(alpha_unstaked),
139+
);
140+
133141
if alpha_unstaked > 0 {
134142
// Swap the alpha to tao and update counters for this subnet.
135143
let tao_unstaked: u64 =
136-
Self::unstake_from_subnet(&hotkey, &coldkey, *netuid, alpha_unstaked, fee);
144+
Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee);
137145

138146
// Add the balance to the coldkey. If the above fails we will not credit this coldkey.
139147
Self::add_balance_to_coldkey_account(&coldkey, tao_unstaked);
140148

141149
// If the stake is below the minimum, we clear the nomination from storage.
142-
Self::clear_small_nomination_if_required(&hotkey, &coldkey, *netuid);
150+
Self::clear_small_nomination_if_required(&hotkey, &coldkey, netuid);
143151
}
144152
}
145153

@@ -177,8 +185,6 @@ impl<T: Config> Pallet<T> {
177185
origin: T::RuntimeOrigin,
178186
hotkey: T::AccountId,
179187
) -> dispatch::DispatchResult {
180-
let fee = DefaultStakingFee::<T>::get();
181-
182188
// 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information.
183189
let coldkey = ensure_signed(origin)?;
184190
log::info!("do_unstake_all( origin:{:?} hotkey:{:?} )", coldkey, hotkey);
@@ -195,22 +201,28 @@ impl<T: Config> Pallet<T> {
195201

196202
// 4. Iterate through all subnets and remove stake.
197203
let mut total_tao_unstaked: u64 = 0;
198-
for netuid in netuids.iter() {
204+
for netuid in netuids.into_iter() {
199205
// If not Root network.
200-
if *netuid != Self::get_root_netuid() {
206+
if netuid != Self::get_root_netuid() {
201207
// Ensure that the hotkey has enough stake to withdraw.
202208
let alpha_unstaked =
203-
Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid);
209+
Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid);
210+
let fee = Self::calculate_staking_fee(
211+
netuid,
212+
&hotkey,
213+
I96F32::saturating_from_num(alpha_unstaked),
214+
);
215+
204216
if alpha_unstaked > 0 {
205217
// Swap the alpha to tao and update counters for this subnet.
206-
let tao_unstaked: u64 =
207-
Self::unstake_from_subnet(&hotkey, &coldkey, *netuid, alpha_unstaked, fee);
218+
let tao_unstaked =
219+
Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee);
208220

209221
// Increment total
210222
total_tao_unstaked = total_tao_unstaked.saturating_add(tao_unstaked);
211223

212224
// If the stake is below the minimum, we clear the nomination from storage.
213-
Self::clear_small_nomination_if_required(&hotkey, &coldkey, *netuid);
225+
Self::clear_small_nomination_if_required(&hotkey, &coldkey, netuid);
214226
}
215227
}
216228
}
@@ -302,8 +314,12 @@ impl<T: Config> Pallet<T> {
302314
)?;
303315

304316
// 4. Swap the alpha to tao and update counters for this subnet.
305-
let fee = DefaultStakingFee::<T>::get();
306-
let tao_unstaked: u64 =
317+
let fee = Self::calculate_staking_fee(
318+
netuid,
319+
&hotkey,
320+
I96F32::saturating_from_num(alpha_unstaked),
321+
);
322+
let tao_unstaked =
307323
Self::unstake_from_subnet(&hotkey, &coldkey, netuid, possible_alpha, fee);
308324

309325
// 5. We add the balance to the coldkey. If the above fails we will not credit this coldkey.

0 commit comments

Comments
 (0)