Skip to content

Commit a062fb9

Browse files
committed
Merge branch 'fix/staking-fees' of github.com:opentensor/subtensor into fix/staking-fees
2 parents 79ecb52 + c7162ea commit a062fb9

File tree

4 files changed

+150
-5
lines changed

4 files changed

+150
-5
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
@@ -509,6 +509,12 @@ pub mod pallet {
509509
T::InitialNetworkRateLimit::get()
510510
}
511511
#[pallet::type_value]
512+
/// Default value for weights version key rate limit.
513+
/// In units of tempos.
514+
pub fn DefaultWeightsVersionKeyRateLimit<T: Config>() -> u64 {
515+
5 // 5 tempos
516+
}
517+
#[pallet::type_value]
512518
/// Default value for pending emission.
513519
pub fn DefaultPendingEmission<T: Config>() -> u64 {
514520
0
@@ -1077,6 +1083,10 @@ pub mod pallet {
10771083
pub type NetworkRateLimit<T> = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit<T>>;
10781084
#[pallet::storage] // --- ITEM( nominator_min_required_stake )
10791085
pub type NominatorMinRequiredStake<T> = StorageValue<_, u64, ValueQuery, DefaultZeroU64<T>>;
1086+
#[pallet::storage]
1087+
/// ITEM( weights_version_key_rate_limit ) --- Rate limit in tempos.
1088+
pub type WeightsVersionKeyRateLimit<T> =
1089+
StorageValue<_, u64, ValueQuery, DefaultWeightsVersionKeyRateLimit<T>>;
10801090

10811091
/// ============================
10821092
/// ==== Subnet Locks =====

pallets/subtensor/src/utils/rate_limiting.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub enum TransactionType {
77
SetChildkeyTake,
88
Unknown,
99
RegisterNetwork,
10+
SetWeightsVersionKey,
1011
}
1112

1213
/// Implement conversion from TransactionType to u16
@@ -17,6 +18,7 @@ impl From<TransactionType> for u16 {
1718
TransactionType::SetChildkeyTake => 1,
1819
TransactionType::Unknown => 2,
1920
TransactionType::RegisterNetwork => 3,
21+
TransactionType::SetWeightsVersionKey => 4,
2022
}
2123
}
2224
}
@@ -28,6 +30,7 @@ impl From<u16> for TransactionType {
2830
0 => TransactionType::SetChildren,
2931
1 => TransactionType::SetChildkeyTake,
3032
3 => TransactionType::RegisterNetwork,
33+
4 => TransactionType::SetWeightsVersionKey,
3134
_ => TransactionType::Unknown,
3235
}
3336
}
@@ -41,14 +44,18 @@ impl<T: Config> Pallet<T> {
4144
match tx_type {
4245
TransactionType::SetChildren => 150, // 30 minutes
4346
TransactionType::SetChildkeyTake => TxChildkeyTakeRateLimit::<T>::get(),
44-
TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit)
4547
TransactionType::RegisterNetwork => NetworkRateLimit::<T>::get(),
48+
49+
TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit)
50+
_ => 0,
4651
}
4752
}
4853

49-
pub fn get_rate_limit_on_subnet(tx_type: &TransactionType, _netuid: u16) -> u64 {
54+
pub fn get_rate_limit_on_subnet(tx_type: &TransactionType, netuid: u16) -> u64 {
5055
#[allow(clippy::match_single_binding)]
5156
match tx_type {
57+
TransactionType::SetWeightsVersionKey => (Tempo::<T>::get(netuid) as u64)
58+
.saturating_mul(WeightsVersionKeyRateLimit::<T>::get()),
5259
_ => Self::get_rate_limit(tx_type),
5360
}
5461
}

0 commit comments

Comments
 (0)