Skip to content
13 changes: 8 additions & 5 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,10 @@ impl<T: Config> Pallet<T> {
NetworkLastLockCost::<T>::get()
}
pub fn get_network_last_lock_block() -> u64 {
NetworkLastRegistered::<T>::get()
Self::get_rate_limited_last_block(&RateLimitKey::NetworkLastRegistered)
}
pub fn set_network_last_lock_block(block: u64) {
NetworkLastRegistered::<T>::set(block);
Self::set_rate_limited_last_block(&RateLimitKey::NetworkLastRegistered, block);
}
pub fn set_lock_reduction_interval(interval: u64) {
NetworkLockReductionInterval::<T>::set(interval);
Expand All @@ -588,10 +588,13 @@ impl<T: Config> Pallet<T> {
let halved_interval: I64F64 = interval.saturating_mul(halving);
halved_interval.saturating_to_num::<u64>()
}
pub fn get_rate_limited_last_block(rate_limit_key: &RateLimitKey) -> u64 {
pub fn get_rate_limited_last_block(rate_limit_key: &RateLimitKey<T::AccountId>) -> u64 {
LastRateLimitedBlock::<T>::get(rate_limit_key)
}
pub fn set_rate_limited_last_block(rate_limit_key: &RateLimitKey, block: u64) {
LastRateLimitedBlock::<T>::set(rate_limit_key, block);
pub fn set_rate_limited_last_block(rate_limit_key: &RateLimitKey<T::AccountId>, block: u64) {
LastRateLimitedBlock::<T>::insert(rate_limit_key, block);
}
pub fn remove_rate_limited_last_block(rate_limit_key: &RateLimitKey<T::AccountId>) {
LastRateLimitedBlock::<T>::remove(rate_limit_key);
}
}
25 changes: 14 additions & 11 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extern crate alloc;

pub const MAX_CRV3_COMMIT_SIZE_BYTES: u32 = 5000;

#[allow(deprecated)]
#[deny(missing_docs)]
#[import_section(errors::errors)]
#[import_section(events::events)]
Expand Down Expand Up @@ -525,11 +526,6 @@ pub mod pallet {
T::InitialNetworkImmunityPeriod::get()
}
#[pallet::type_value]
/// Default value for network last registered.
pub fn DefaultNetworkLastRegistered<T: Config>() -> u64 {
0
}
#[pallet::type_value]
/// Default value for network min allowed UIDs.
pub fn DefaultNetworkMinAllowedUids<T: Config>() -> u16 {
T::InitialNetworkMinAllowedUids::get()
Expand Down Expand Up @@ -1164,10 +1160,6 @@ pub mod pallet {
pub type NetworkImmunityPeriod<T> =
StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod<T>>;
#[pallet::storage]
/// ITEM( network_last_registered_block )
pub type NetworkLastRegistered<T> =
StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered<T>>;
#[pallet::storage]
/// ITEM( min_network_lock_cost )
pub type NetworkMinLockCost<T> =
StorageValue<_, TaoCurrency, ValueQuery, DefaultNetworkMinLockCost<T>>;
Expand Down Expand Up @@ -1200,7 +1192,7 @@ pub mod pallet {
#[pallet::storage]
/// --- MAP ( RateLimitKey ) --> Block number in which the last rate limited operation occured
pub type LastRateLimitedBlock<T: Config> =
StorageMap<_, Identity, RateLimitKey, u64, ValueQuery, DefaultZeroU64<T>>;
StorageMap<_, Identity, RateLimitKey<T::AccountId>, u64, ValueQuery, DefaultZeroU64<T>>;

/// ============================
/// ==== Subnet Locks =====
Expand Down Expand Up @@ -1657,14 +1649,17 @@ pub mod pallet {
u64,
ValueQuery,
>;
#[deprecated]
#[pallet::storage]
/// --- MAP ( key ) --> last_block
pub type LastTxBlock<T: Config> =
StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock<T>>;
#[deprecated]
#[pallet::storage]
/// --- MAP ( key ) --> last_tx_block_childkey_take
pub type LastTxBlockChildKeyTake<T: Config> =
StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock<T>>;
#[deprecated]
#[pallet::storage]
/// --- MAP ( key ) --> last_tx_block_delegate_take
pub type LastTxBlockDelegateTake<T: Config> =
Expand Down Expand Up @@ -2135,9 +2130,17 @@ impl<T: Config + pallet_balances::Config<Balance = u64>>
/// Enum that defines types of rate limited operations for
/// storing last block when this operation occured
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug, TypeInfo)]
pub enum RateLimitKey {
pub enum RateLimitKey<AccountId> {
// The setting sn owner hotkey operation is rate limited per netuid
SetSNOwnerHotkey(NetUid),
// Subnet registration rate limit
NetworkLastRegistered,
// Last tx block limit per account ID
LastTxBlock(AccountId),
// Last tx block child key limit per account ID
LastTxBlockChildKeyTake(AccountId),
// Last tx block delegate key limit per account ID
LastTxBlockDelegateTake(AccountId),
}

pub trait ProxyInterface<AccountId> {
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2031,7 +2031,7 @@ mod dispatches {
/// * commit_reveal_version (`u16`):
/// - The client (bittensor-drand) version
#[pallet::call_index(113)]
#[pallet::weight((Weight::from_parts(64_530_000, 0)
#[pallet::weight((Weight::from_parts(80_690_000, 0)
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))]
pub fn commit_timelocked_weights(
Expand Down
4 changes: 3 additions & 1 deletion pallets/subtensor/src/macros/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ mod hooks {
//Migrate CRV3 to TimelockedCommits
.saturating_add(migrations::migrate_crv3_v2_to_timelocked::migrate_crv3_v2_to_timelocked::<T>())
// Migrate to fix root counters
.saturating_add(migrations::migrate_fix_root_tao_and_alpha_in::migrate_fix_root_tao_and_alpha_in::<T>());
.saturating_add(migrations::migrate_fix_root_tao_and_alpha_in::migrate_fix_root_tao_and_alpha_in::<T>())
// Migrate last block rate limiting storage items
.saturating_add(migrations::migrate_rate_limiting_last_blocks::migrate_obsolete_rate_limiting_last_blocks_storage::<T>());
weight
}

Expand Down
161 changes: 161 additions & 0 deletions pallets/subtensor/src/migrations/migrate_rate_limiting_last_blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
use crate::Vec;
use crate::{Config, HasMigrationRun, Pallet};
use alloc::string::String;
use codec::Decode;
use frame_support::traits::Get;
use frame_support::weights::Weight;
use sp_io::hashing::twox_128;
use sp_io::storage::{clear, get};

pub fn migrate_obsolete_rate_limiting_last_blocks_storage<T: Config>() -> Weight {
migrate_network_last_registered::<T>()
.saturating_add(migrate_last_tx_block::<T>())
.saturating_add(migrate_last_tx_block_childkey_take::<T>())
.saturating_add(migrate_last_tx_block_delegate_take::<T>())
}

pub fn migrate_network_last_registered<T: Config>() -> Weight {
let migration_name = b"migrate_network_last_registered".to_vec();
let pallet_name = "SubtensorModule";
let storage_name = "NetworkLastRegistered";

migrate_value::<T, _>(migration_name, pallet_name, storage_name, |limit| {
Pallet::<T>::set_network_last_lock_block(limit);
})
}

#[allow(deprecated)]
pub fn migrate_last_tx_block<T: Config>() -> Weight {
let migration_name = b"migrate_last_tx_block".to_vec();

migrate_last_block_map::<T, _, _>(
migration_name,
|| crate::LastTxBlock::<T>::drain().collect::<Vec<_>>(),
|account, block| {
Pallet::<T>::set_last_tx_block(&account, block);
},
)
}

#[allow(deprecated)]
pub fn migrate_last_tx_block_childkey_take<T: Config>() -> Weight {
let migration_name = b"migrate_last_tx_block_childkey_take".to_vec();

migrate_last_block_map::<T, _, _>(
migration_name,
|| crate::LastTxBlockChildKeyTake::<T>::drain().collect::<Vec<_>>(),
|account, block| {
Pallet::<T>::set_last_tx_block_childkey(&account, block);
},
)
}

#[allow(deprecated)]
pub fn migrate_last_tx_block_delegate_take<T: Config>() -> Weight {
let migration_name = b"migrate_last_tx_block_delegate_take".to_vec();

migrate_last_block_map::<T, _, _>(
migration_name,
|| crate::LastTxBlockDelegateTake::<T>::drain().collect::<Vec<_>>(),
|account, block| {
Pallet::<T>::set_last_tx_block_delegate_take(&account, block);
},
)
}

fn migrate_value<T, SetValueFunction>(
migration_name: Vec<u8>,
pallet_name: &str,
storage_name: &str,
set_value: SetValueFunction,
) -> Weight
where
T: Config,
SetValueFunction: Fn(u64 /*limit in blocks*/),
{
// Initialize the weight with one read operation.
let mut weight = T::DbWeight::get().reads(1);

// Check if the migration has already run
if HasMigrationRun::<T>::get(&migration_name) {
log::info!("Migration '{migration_name:?}' has already run. Skipping.",);
return weight;
}
log::info!(
"Running migration '{}'",
String::from_utf8_lossy(&migration_name)
);

let pallet_name_hash = twox_128(pallet_name.as_bytes());
let storage_name_hash = twox_128(storage_name.as_bytes());
let full_key = [pallet_name_hash, storage_name_hash].concat();

if let Some(value_bytes) = get(&full_key) {
if let Ok(rate_limit) = Decode::decode(&mut &value_bytes[..]) {
set_value(rate_limit);
}

clear(&full_key);
}

weight = weight.saturating_add(T::DbWeight::get().writes(2));
weight = weight.saturating_add(T::DbWeight::get().reads(1));

// Mark the migration as completed
HasMigrationRun::<T>::insert(&migration_name, true);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

log::info!(
"Migration '{:?}' completed.",
String::from_utf8_lossy(&migration_name)
);

// Return the migration weight.
weight
}

fn migrate_last_block_map<T, GetValuesFunction, SetValueFunction>(
migration_name: Vec<u8>,
get_values: GetValuesFunction,
set_value: SetValueFunction,
) -> Weight
where
T: Config,
GetValuesFunction: Fn() -> Vec<(T::AccountId, u64)>, // (account, limit in blocks)
SetValueFunction: Fn(T::AccountId, u64),
{
// Initialize the weight with one read operation.
let mut weight = T::DbWeight::get().reads(1);

// Check if the migration has already run
if HasMigrationRun::<T>::get(&migration_name) {
log::info!("Migration '{migration_name:?}' has already run. Skipping.",);
return weight;
}
log::info!(
"Running migration '{}'",
String::from_utf8_lossy(&migration_name)
);

let key_values = get_values();
weight = weight.saturating_add(T::DbWeight::get().reads(key_values.len() as u64));

for (account, block) in key_values.into_iter() {
set_value(account, block);

weight = weight.saturating_add(T::DbWeight::get().writes(2));
weight = weight.saturating_add(T::DbWeight::get().reads(1));
}

// Mark the migration as completed
HasMigrationRun::<T>::insert(&migration_name, true);
weight = weight.saturating_add(T::DbWeight::get().writes(1));

log::info!(
"Migration '{:?}' completed.",
String::from_utf8_lossy(&migration_name)
);

// Return the migration weight.
weight
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod migrate_init_total_issuance;
pub mod migrate_orphaned_storage_items;
pub mod migrate_populate_owned_hotkeys;
pub mod migrate_rao;
pub mod migrate_rate_limiting_last_blocks;
pub mod migrate_remove_commitments_rate_limit;
pub mod migrate_remove_stake_map;
pub mod migrate_remove_total_hotkey_coldkey_stakes_this_interval;
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/subnets/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl<T: Config> Pallet<T> {
log::debug!("SubnetMechanism for netuid {netuid_to_register:?} set to: {mechid:?}");

// --- 12. Set the creation terms.
NetworkLastRegistered::<T>::set(current_block);
Self::set_network_last_lock_block(current_block);
NetworkRegisteredAt::<T>::insert(netuid_to_register, current_block);

// --- 13. Set the symbol.
Expand Down
21 changes: 9 additions & 12 deletions pallets/subtensor/src/swap/swap_hotkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,18 @@ impl<T: Config> Pallet<T> {
);

// 8. Swap LastTxBlock
// LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey.
let last_tx_block: u64 = LastTxBlock::<T>::get(old_hotkey);
LastTxBlock::<T>::insert(new_hotkey, last_tx_block);
let last_tx_block: u64 = Self::get_last_tx_block(old_hotkey);
Self::set_last_tx_block(new_hotkey, last_tx_block);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));

// 9. Swap LastTxBlockDelegateTake
// LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take.
let last_tx_block_delegate_take: u64 = LastTxBlockDelegateTake::<T>::get(old_hotkey);
LastTxBlockDelegateTake::<T>::insert(new_hotkey, last_tx_block_delegate_take);
let last_tx_block_delegate_take: u64 = Self::get_last_tx_block_delegate_take(old_hotkey);
Self::set_last_tx_block_delegate_take(new_hotkey, last_tx_block_delegate_take);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));

// 10. Swap LastTxBlockChildKeyTake
// LastTxBlockChildKeyTake( hotkey ) --> u64 -- the last transaction block for the hotkey child key take.
let last_tx_block_child_key_take: u64 = LastTxBlockChildKeyTake::<T>::get(old_hotkey);
LastTxBlockChildKeyTake::<T>::insert(new_hotkey, last_tx_block_child_key_take);
let last_tx_block_child_key_take: u64 = Self::get_last_tx_block_childkey_take(old_hotkey);
Self::set_last_tx_block_childkey(new_hotkey, last_tx_block_child_key_take);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));

// 11. fork for swap hotkey on a specific subnet case after do the common check
Expand Down Expand Up @@ -197,17 +194,17 @@ impl<T: Config> Pallet<T> {

// 6. Swap LastTxBlock
// LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey.
LastTxBlock::<T>::remove(old_hotkey);
Self::remove_last_tx_block(old_hotkey);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2));

// 7. Swap LastTxBlockDelegateTake
// LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take.
LastTxBlockDelegateTake::<T>::remove(old_hotkey);
Self::remove_last_tx_block_delegate_take(old_hotkey);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2));

// 8. Swap LastTxBlockChildKeyTake
// LastTxBlockChildKeyTake( hotkey ) --> u64 -- the last transaction block for the hotkey child key take.
LastTxBlockChildKeyTake::<T>::remove(old_hotkey);
Self::remove_last_tx_block_childkey(old_hotkey);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2));

// 9. Swap Senate members.
Expand Down
Loading